@arsedizioni/ars-utils

中文文档
22.7.8发布于 2026/10/23MITTypeScriptES Module近 30 天下载 3613

Common tools and standalone components shared among ARS Edizioni Angular based web applications.

原始使用文档
文档目录9 节
  1. Platform
  2. Entry points
  3. Nucleo condiviso
  4. Specifici ARS
  5. Grafo delle dipendenze statiche
  6. Regole da rispettare
  7. Da dove parte un'applicazione
  8. Differenze rispetto alla versione precedente (22.1.x monoli…
  9. Authors

ARS Utils

Common tools and standalone components shared among ARS Edizioni Angular based web applications.

Rispetto alla versione monolitica precedente adotta la struttura a entry point introdotta con @fabio.buscaroli/scm-utils: code splitting e tree shaking sono il criterio di ripartizione dei simboli, non un effetto collaterale.

Platform

Angular 22 + Material

Entry points

La libreria non espone un barrel unico: l'entry point secondario e' l'unica unita' di code splitting riconosciuta da ng-packagr, quindi ogni gruppo di simboli che ha un ciclo di vita proprio vive nel suo entry point. Importare sempre dal path specifico.

Nucleo condiviso

LivelloEntry pointContenutoNote
L0coreSystemUtils, models, definitions, pipe, direttive validator, servizi (broadcast, screen, theme, splash, environment), LoginOAuthTypenessuna dipendenza da Angular Material
L0core.dateprovideArsDateFns, provideArsLocalDates, MAT_DATE_FNS_FORMATS, arsLocalDateInterceptor, ARS_TIME_ZONEisola @angular/material/core + datepicker
L0core.markdownMarkdownUtils, FormatMarkdownPipeparser markdown, fuori dal percorso comune
L0core.validatorsdirettive validator per i form template-driven (ValidatorDirective, ValidIfDirective, EqualsValidatorDirective, PasswordValidatorDirective, EmailsValidatorDirective, ...)isola @angular/forms (53 KB): core sta sul percorso di boot e non deve trascinarselo
L0.5ui.shellShellService (info, error, busy*, wait, BusyTimer), ShellMessageComponent, ShellBusyComponentzero Material e zero CDK: e' quello che shell, interceptor, guard e app initializer possono permettersi sul percorso di boot
L1uiFlexLayoutModule, MediaObserver, UIService, tipi dei dialogkernel: deve restare magro, e non importa nulla da Material
L1ui.paginatorPaginatorIntlisola @angular/material/paginator, che si porta dietro mat-select e mat-option
L1.5ui.dialogsDialogService (estende ShellService) + confirm, delete, toast, open, e le aperture pigre dei dialog pesantitutto cio' che chiede qualcosa all'utente, piu' il toast
L2ui.dialogs.authcredentials, reset-password, recover-password, prompt-otp, OtpInputComponent, PasswordStrengthComponentsolo route di login/account
L2ui.dialogs.promptprompt, prompt-date, prompt-timeporta @angular/material/datepicker
L2ui.dialogs.selectselect, select-tree, send-toporta mat-tree, mat-list, mat-chips
L2ui.filesfile-input, file-preview, select-file, select-picture
L2ui.controlsbutton-selector, button-toggle, chips-selectorbase Material comune: button, icon, form-field
L2ui.controls.dateMatDatepickerParseErrorFixDirective, CalendarEmptyHeaderisola @angular/material/datepicker: ui.dialogs.prompt aggancia solo questo
L2ui.controls.treeTreePickerComponentisola mat-tree, mat-tabs, mat-input, mat-checkbox, che nessun altro controllo usa
L2ui.filtersFilterBarComponent + modello Filters
L2ui.navigationNavigationBarComponent + definizionishell applicativa

Specifici ARS

LivelloEntry pointContenutoDipendenze pesanti
L0.5support.commonSupportService, notifiche, definitions, messages-
L0.5evolution.commonEvolutionService, account, compliance, login, interceptor auth-
L2ui.oauthLoginOAuthComponent, LoginOAuthOkMSComponent@azure/msal-angular, @azure/msal-browser
L2ui.helpHelpService, HelpViewerComponent, modello dei capitoli-
L2ui.tinymceTinymceEditorDirective, TinymceLoaderService, TinymceUtils, TinyMceEditorComponent, langs/it.jstinymce (caricato a runtime)
L2ui.notificationsNotificationsBrowserComponent (ex support.ui)-
L2clipper.commonClipperService, documents, login, canali e contatori non letti, interceptor authsolo il necessario a consultare i documenti
L4clipper.uibrowser, document, references, search-* e ClipperDocumentUtilsServiceclipper.scss

I peer dependency opzionali (@azure/msal-*, tinymce) servono solo a chi importa rispettivamente ui.oauth e ui.tinymce: sono dichiarati in peerDependenciesMeta.optional proprio perche' nessun altro entry point li aggancia.

Grafo delle dipendenze statiche

core        core.date        core.markdown        core.validators        ui.paginator        ui.controls.date
 |    \
 |     ui.shell
 |        |
 ui ------|-----------------------------------------------------------
 |        |      |               |             |             |                 |               |
 |        | ui.controls  ui.controls.tree  ui.filters  ui.navigation  ui.dialogs.select  clipper.common
 |        |
ui.dialogs      <-- DialogService extends ShellService: dipende da `ui` E da `ui.shell`
 |         |                  |              |          |            |
 |   ui.dialogs.auth   ui.dialogs.prompt  ui.files   ui.help    ui.oauth
 |                                                   ui.notifications (+ support.common)
clipper.ui  (+ clipper.common, ui.controls, ui.controls.date, ui.files, ui.dialogs.select)

`ui.dialogs` --- import() --->  ui.dialogs.{auth,prompt,select}, ui.files
Gli archi dinamici puntano all'insu' e sono l'unica ragione per cui quei quattro entry point
restano fuori dal bundle iniziale. Regge finche' NESSUNO di loro importa `DialogService`: per
`error()` e `busy()` iniettano `ShellService`.

`ui.controls.date` non dipende da nulla della libreria (solo `@angular/core` e
`@angular/material/datepicker`): e' cio' che permette al chunk di `ui.dialogs.prompt` di
agganciare la direttiva senza linkare il file di `ui.controls`.

evolution.common e support.common dipendono solo da core.

Regole da rispettare

  1. Il grafo statico tra entry point deve restare un DAG: ui.dialogs raggiunge i dialog pesanti solo con import(), e quei quattro entry point non devono importare DialogService in nessun modo — ng-packagr rifiuta la build con circular dependency al primo che lo fa. Per messaggi e attesa iniettano ShellService, che sta sotto di loro nel grafo.
  2. I tipi condivisi fra il facade e i dialog pesanti stanno in ui (dialog.definitions.ts). Se un tipo servisse a entrambi e vivesse nel dialog, l'import() del facade tornerebbe statico.
  3. Il facade usa import type per i tipi dei componenti e import() per i valori: e' quello che tiene i dialog fuori dal bundle iniziale.
  4. Dopo una modifica, verificare che gli import() sopravvivano alla build: grep -o "import('@arsedizioni[^']*')" dist/ars-utils/fesm2022/*ui.dialogs.mjs deve stampare i nove.
  5. ui.shell non importa nulla da @angular/material ne' da @angular/cdk, e nemmeno da ui. E' l'unica ragione per cui esiste: se ci finisce dentro un solo simbolo di Material, la shell torna a pagare l'intero stack sul percorso di boot. Da verificare dopo ogni build: grep -oE "@angular/(material|cdk)[^'\"]*" dist/ars-utils/fesm2022/*ui.shell.mjs non deve stampare nulla.
  6. Le sovrapposizioni di ui.shell stanno nel top layer del browser, non nello stack del CDK. Da Angular CDK 22 ogni overlay viene aperto come popover="manual", quindi un dialog Material non sta piu' a z-index 1000: sta nel top layer, che viene disegnato sopra tutta la pagina qualunque cosa dica lo z-index della pagina. Un numero, per quanto alto, non ci arriva sopra: per questo ShellService promuove anche i suoi due overlay con showPopover(). Nel top layer l'ordine e' quello di promozione, l'ultimo promosso sta sopra. Da qui le tre regole esplicite: setBusy() ripromuove il messaggio dopo aver alzato il busy, DialogService.open() chiama raiseMessage() dopo aver aperto un dialog, e chiama clearBusy(true) senza periodo di grazia. La coppia --ars-shell-dialog-z-index/--ars-shell-busy-z-index (1100/1090) resta valida e serve ancora: e' quello che ordina gli overlay sui browser senza Popover API, dove nemmeno il CDK la usa. Se un'applicazione avesse bisogno del vecchio comportamento puo' spegnere la Popover API del CDK con { provide: OVERLAY_DEFAULT_CONFIG, useValue: { usePopover: false } }.
  7. ui non importa valori da Material. PaginatorIntl e' uscito da li' proprio per questo: era l'unico simbolo che ne dipendeva, e faceva pagare mat-paginator + mat-select + mat-option a chiunque toccasse ui.dialogs. Restano due eccezioni, entrambe volute: MatFormFieldAppearance in dialog.definitions.ts, che e' un import type e quindi sparisce in compilazione, e @angular/cdk/layout (1 KB) di cui MediaObserver ha bisogno.

Da dove parte un'applicazione

core + ui.shell. Sono i due entry point che una applicazione ARS carica comunque prima di avere una rotta, e gli unici due che non costano Material. core porta SystemUtils, i modelli, BroadcastService, SplashService, EnvironmentService, ThemeService; ui.shell porta il modo di dire all'utente che la sessione e' scaduta o che l'API non risponde.

Non sono un entry point solo, e non devono diventarlo: core e' L0 e ci dipendono anche clipper.common, evolution.common e support.common, che di interfaccia non ne hanno. Fonderli significherebbe far dipendere tre entry point headless da uno di UI, cioe' rompere la regola 1.

La conseguenza pratica per chi scrive l'applicazione:

  • shell, interceptor, guard, provideAppInitializer -> ShellService di ui.shell
  • componenti di rotta -> DialogService di ui.dialogs, che apre anche i dialog pesanti

I tre servizi sono una catena, non tre servizi diversi:

ShellService                info, error, busy*, wait, busyTimer     ui.shell
  └ DialogService           + open, confirm, delete, toast,         ui.dialogs
                              select, prompt, sendTo, ... (pigri)

Quindi chi inietta DialogService ha tutto quello che aveva prima: info, error e busy non sono spariti, sono ereditati. E non esistono in due copie — c'e' una implementazione sola, quella senza Material.

ShellService.info() e ShellService.error() hanno gli stessi parametri, nello stesso ordine, delle omonime di DialogService: spostare una chiamata dall'una all'altra e' un cambio di servizio iniettato e nient'altro.

Differenze rispetto alla versione precedente (22.1.x monolitica)

  • Nessun barrel radice: @arsedizioni/ars-utils esporta solo ARS_UTILS_VERSION.
  • ui non contiene piu' i dialog: DialogService sta in ui.dialogs.
  • ui.application non esiste piu': i nove metodi che apriva stanno in DialogService. I controlli sono in ui.controls, i file in ui.files, i filtri in ui.filters, la navigazione in ui.navigation.
  • SystemUtils.markdownToHtml non esiste piu': usare MarkdownUtils.toHtml da core.markdown.
  • SelectableModel espone first e selectedAny al posto di selectedFirst e selectedAll.
  • support.ui si chiama ui.notifications, help si chiama ui.help, tinymce si chiama ui.tinymce.
  • PaginatorIntl non sta piu' in ui: sta in ui.paginator.
  • ui.tinymce non dipende piu' da @tinymce/tinymce-angular: l'editor e' la direttiva [tinymceEditor] su una <textarea>, e TinyMCE viene caricato a runtime da TinymceLoaderService. Il componente <editor> non esiste piu'.
  • Le direttive validator non stanno piu' in core: stanno in core.validators, che e' l'unico entry point del nucleo a dipendere da @angular/forms.
  • I token CSS della shell stanno tutti sotto --ars-shell-dialog-* e --ars-shell-busy-*: prima erano --ars-dialog-*, --ars-scrim-color, --ars-busy-* e --ars-progress-track-color, che si confondevano con --ars-dialog-item-*, cioe' i dialog Material veri. Un'applicazione che ne sovrascriveva qualcuno deve rinominarlo.
  • La shell non deve piu' iniettare DialogService per mostrare un errore: c'e' ShellService in ui.shell.
  • info, error, busy, busySpinner, busyHourglass, wait, busyTimer e clearBusy sono passati a ShellService. DialogService li eredita, quindi nessuna chiamata cambia.
  • info() e error() restituiscono ShellMessageRef invece di MatDialogRef<InfoDialogComponent>. In myARS nessun chiamante usava quel valore; controllare nelle altre applicazioni.
  • clearBusy() accetta immediate: clearBusy(true) non aspetta i 500 ms di grazia.
  • BusyTimer si importa da ui.shell, non piu' da ui.dialogs.
  • InfoDialogComponent e BusyDialogComponent non esistono piu': li sostituiscono ShellMessageComponent e ShellBusyComponent, senza Material.

Authors

Fabio Buscaroli, Alberto Doria

版本与发布记录

@arsedizioni/ars-utils 共发布 2,845 个版本,首次发布于 2020/03/11;过去 12 个月发布了 578 个版本。

版本发布日期距今
22.7.8latest2026/10/2315 天前
22.7.72026/10/1721 天前
22.7.62026/10/1424 天前
22.7.52026/10/1424 天前
22.7.42026/10/1424 天前
22.7.32026/10/1028 天前

关于 @arsedizioni/ars-utils 的常见问题

@arsedizioni/ars-utils 是什么?

Common tools and standalone components shared among ARS Edizioni Angular based web applications.

如何安装 @arsedizioni/ars-utils?

在项目目录运行 npm install @arsedizioni/ars-utils,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:date-fns(^4)、file-saver(^2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@arsedizioni/ars-utils 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@arsedizioni/ars-utils 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@arsedizioni/ars-utils 可以商用吗?

@arsedizioni/ars-utils 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@arsedizioni/ars-utils 的下载量有多少?

根据 npm 官方下载统计,@arsedizioni/ars-utils 在 2026/10/07 – 2026/11/05 这 30 天内被下载 3,613 次,日均约 120 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arsedizioni/ars-utils 还在维护吗?

最新版本 22.7.8 发布于 2026/10/23(15 天前);至今共发布 2845 个版本,其中过去 12 个月发布了 578 个;首次发布于 2020/03/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。