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

@atmoner/logistic-unit

v0.0.2

Published

Packaging hierarchies, quantity conversions and physical logistics units

Readme

@atmoner/logistic-unit

Package npm

Bibliothèque npm sans dépendance pour modéliser les conditionnements d'un article et le contenu d'une unité physique d'expédition. JavaScript CommonJS et ESM, déclarations TypeScript incluses. Node.js ≥ 18.

Le modèle métier s'appuie sur l'article Blogistics : UVC (vente/consommation), SPCB (sous-colis), PCB (colis), couche et palette ; facteurs de conversion, dimensions, poids et identifiants par niveau. Les calculs et l'API sont une implémentation propre à ce package.

Installation

Installer le package depuis npm :

npm install @atmoner/logistic-unit

Pour une installation depuis le dépôt local, exécuter npm pack, puis installer l'archive .tgz générée avec npm install /chemin/vers/archive.tgz.

Exemple

const { PackagingHierarchy } = require('@atmoner/logistic-unit');
// ESM : import { PackagingHierarchy } from '@atmoner/logistic-unit';

const article = new PackagingHierarchy({
  articleId: 'PATES-500G',
  levels: [
    { id: 'UVC', pickable: true },
    { id: 'SPCB', quantity: 6, pickable: true },
    { id: 'PCB', quantity: 8, grossWeightKg: 25,
      dimensions: { length: 40, width: 30, height: 25, unit: 'cm' } },
    { id: 'LAYER', quantity: 10 },
    { id: 'PALLET', quantity: 5 },
  ],
});

article.convert(1, 'PALLET', 'UVC'); // 2400
article.convert(3, 'UVC', 'SPCB'); // 0.5
article.convert(48, 'UVC', 'PCB', { whole: true }); // 1
article.breakdown(101); // { PCB: 2, UVC: 5 }
article.breakdown(101, 'UVC', { pickableOnly: true }); // { SPCB: 16, UVC: 5 }
article.volumeM3('PCB', 2); // ≈ 0.06 m³
article.weightKg('PCB', 2); // 50 kg

Modèle et API

PackagingHierarchy reçoit des niveaux ordonnés du plus petit au plus grand. quantity décrit le nombre d'unités du niveau immédiatement précédent ; le premier vaut 1. Les identifiants sont libres : les niveaux intermédiaires peuvent être omis et des conditionnements spécifiques ajoutés. LEVELS expose les noms usuels UVC, SPCB, PCB, LAYER, PALLET.

| Méthode | Résultat | | --- | --- | | level(id) | Définition immuable, avec baseQuantity | | convert(q, from, to, { whole? }) | Quantité cible ; whole: true refuse une unité partielle | | breakdown(q, from?, { pickableOnly? }) | Décomposition gloutonne, du plus grand niveau au plus petit | | volumeM3(id, q = 1) | Volume mesuré, dimensions en mm, cm ou m | | weightKg(id, q = 1, kind = 'gross') | Poids brut ou net, en kg | | toJSON() | Définition sérialisable, réutilisable dans le constructeur |

Les quantités d'entrée et les facteurs sont des entiers positifs sûrs (zéro accepté pour les calculs). Les résultats de conversion peuvent être fractionnaires. Le package refuse les dépassements de précision entière, les niveaux inconnus et les incohérences de définition. Les calculs de volume et de poids utilisent la précision décimale native de JavaScript.

La décomposition sert une règle « plus grand conditionnement d'abord », sans optimiser le nombre de colis pour des facteurs arbitraires. Avec pickableOnly, seuls les niveaux explicitement marqués true sont utilisés ; un reliquat impossible à préparer déclenche une erreur.

Les gabarits et poids sont facultatifs, mais nécessaires pour les calculs correspondants. Ils sont mesurés par niveau, sans extrapolation depuis les niveaux inférieurs.

Unité physique et palettes panachées

const { LogisticUnit } = require('@atmoner/logistic-unit');

const palette = new LogisticUnit({
  sscc: '000000000000000017', // Exemple de format, pas un SSCC attribué.
  tareWeightKg: 20,
  dimensions: { length: 120, width: 80, height: 150, unit: 'cm' },
  contents: [{ hierarchy: article, level: 'PCB', quantity: 50, lot: 'LOT-001' }],
});

palette.totals(); // { 'PATES-500G': 2400 }
palette.grossWeightKg(); // 1270
palette.volumeM3(); // ≈ 1.44

Ajouter des lignes avec d'autres articles permet de représenter une palette panachée. Réutiliser la même instance de hiérarchie pour les lignes d'un même article. totals() agrège par article dans son unité de base ; lot conserve la référence du lot dans chaque ligne.

Le poids brut additionne les poids des conditionnements contenus et la tare de l'unité. Ne compter chaque emballage qu'une fois. Le volume utilise les dimensions extérieures de l'unité physique.

isValidGTIN(string) vérifie les longueurs 8/12/13/14 et la clé ; isValidSSCC(string) vérifie 18 chiffres et la clé. checkDigit(body) retourne la clé modulo 10. Ces fonctions suivent les règles de contrôle GS1. Les codes sont des chaînes pour préserver les zéros initiaux. Deux GTIN équivalents après normalisation à 14 chiffres sont refusés dans une hiérarchie.

Le contrôle de format ne vérifie ni l'attribution GS1 ni l'unicité mondiale. L'application appelante assure l'attribution et l'unicité des SSCC. Ce package ne génère pas d'images de codes-barres et n'implémente pas de WMS, de stockage persistant ou de règles réglementaires.

Développement

npm test
npm run example
npm pack

Les tests s'exécutent également avant la création d'une archive. Licence ISC.