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

@intra-mart/juggling-core

v0.1.2

Published

Domain-logic TypeScript library for IM-Juggling: intra-mart module catalog retrieval, repository access, project/module-structure operations, and WAR/static build output. ESM-only, Node >= 22.19.0.

Readme

@intra-mart/juggling-core

TypeScript library implementing the IM-Juggling domain logic — intra-mart module catalog retrieval, repository access, project/module-structure operations, and WAR/static build output — as a set of composable, strongly-typed APIs for Node.

Full usage manual (Japanese): README.ja.md walks through every use case end to end — catalog retrieval, project creation, module selection, user modules, configuration deployment, WAR / static output, patches, and version upgrades — with runnable, type-checked examples.

Overview

@intra-mart/juggling-core ports the module/repository/build logic of IM-Juggling into a pure TypeScript library. It covers the full flow from fetching module catalogs to producing deployable WAR and static outputs, and mirrors the observable behavior of the current IM-Juggling tooling. Known compatibility quirks are documented and exposed programmatically through the compat subpath.

  • ESM-only, targeting Node.js >= 22.19 (also runs on Bun).
  • Layered, side-effect-free core: the model / i18n / expr / rules layers are pure, synchronous, and deterministic; all I/O lives behind injectable runtime ports.
  • Distributed as compiled .js + .d.ts with one entry per public subpath.

Requirements

  • Node.js >= 22.19 (or Bun)
  • ESM ("type": "module", or import() from CommonJS)

Installation

bun add @intra-mart/juggling-core
# or: npm install @intra-mart/juggling-core

Runtime dependencies (sax, undici, yauzl, yazl) are installed automatically.

Public subpaths

The package exposes one entry point per area. Import only what you need.

| Subpath | Contents | Layer | |---|---|---| | @intra-mart/juggling-core (root) | Aggregate facade: createJuggling() wires the repository service together with projects.* (create / createFromRecommended / open) and build.* (exportWar / exportStatic / templates). | facade | | @intra-mart/juggling-core/model | Domain model (ModuleKey / Version / metadata / catalog types / dependencies / hashes / enums) — pure and synchronous. | L0 | | @intra-mart/juggling-core/i18n | Locale-candidate resolution, .properties handling, message resolution, LocalizedText. | L0 | | @intra-mart/juggling-core/expr | OGNL-subset evaluator (parser + evaluator + host bindings). | L0 | | @intra-mart/juggling-core/rules | Declarative rule catalog (validation, filtering, selection propagation, edition detection) plus an extension registry. | L1 | | @intra-mart/juggling-core/repository | Repository reads (FILESET / HTTP), cross-cutting retrieval, catalog, merge, and createJuggling. | L2 | | @intra-mart/juggling-core/project | ModuleStructure, selection operations, the project-layer model, and conf/schema deployment. | L2 | | @intra-mart/juggling-core/lifecycle | Use-case procedures: create / open / save, patch, upgrade (plan → apply), additional resources. | L2 | | @intra-mart/juggling-core/build | imm expansion engine, web.xml synthesis, WAR / static output, template definitions. | L2 | | @intra-mart/juggling-core/compat | Machine-readable compatibility ledger and format-compatibility conversion helpers. | L2 | | @intra-mart/juggling-core/runtime, .../runtime/node | Runtime port types and the Node implementation. | L3 | | @intra-mart/juggling-core/testing | In-memory / fixture ports and comparison helpers for use in your own tests. | L3 |

Quick start

// Start with all defaults: management repository = ~/.juggling/repository,
// module repositories = product defaults, locale = host environment. The root import is
// the aggregate facade (repository service + projects.* + build.*).
import { createJuggling } from "@intra-mart/juggling-core";

const juggling = await createJuggling();

// --- Catalog (categories, recommended configuration) ---
const base = await juggling.catalog.getBaseCategories();        // base modules
const apps = await juggling.catalog.getApplicationCategories(); // applications
const recommended = await juggling.catalog.getRecommendedData();
for (const category of base) {
  console.log(category.id, category.name?.get());               // name is a LocalizedText
  for (const m of category.availableModules()) {
    console.log(" ", m.id, m.version.toString());
  }
}

// --- Metadata and module retrieval ---
import { ModuleKey, parseVersion } from "@intra-mart/juggling-core/model";

const key = ModuleKey.of("jp.co.intra_mart.vendor.velocity", parseVersion("1.7.0"));
const meta = await juggling.repositoryService.getMetadata(key);
const mod = await juggling.repositoryService.getModule(key);    // SHA-1 verified
const patch = await juggling.catalog.findPatch(key);            // latest patch, or null
  • Override the locale or repositories with createJuggling({ locale: "en", repositories: [...] }).
  • Retrieved name / description values are LocalizedText: use .get() for the resolved value and .raw for the original.

Projects and builds

const project = await juggling.projects.create({       // → JugglingProject
  dir: "/ws/myapp", name: "myapp", base, applications,
});
// Open an existing project instead: const project = await juggling.projects.open("/ws/myapp");

project.applyCheckState(module, true);                  // selection (synchronous)
const status = await project.validate();                // AggregateStatus (a value, not a throw)
await project.save({ description: "Initial configuration" });

await juggling.build.exportWar(project, {               // WAR output
  template: "resin40", destDir: "/out", fileName: "imart",
  inputs: { licenseType: "product", environment: "product", includeSamples: false },
});
await project.compact();                                // drop history, keep latest only

Lower-level standalone functions are also available for progressive disclosure: createProject(req, ctx) / openProject(dir, ctx) (lifecycle), buildWarFromProject(args) / exportWar(opts, deps) (build), applyCheckState(structure, m, checked) (project).

Usage guide

The Japanese manual documents the complete workflow, one section per use case. Every code sample there is executed against a live repository and type-checked:

  1. Create a project — retrieve catalogs, narrow applications to a base (filterApplicationCandidates), validate the selection, and projects.create(...).
  2. Open a project — restore a JugglingProject from a saved juggling.im.
  3. Select modules — edit the module structure with check-state propagation and resolve missing modules.
  4. Add user modules — register your own .imm files (addUserModules) and handle the AddUserModulesResult outcomes.
  5. Deploy configurations — expand conf/*.xml and schema/*.xsd into the project.
  6. Build a WARbuild.plan(...) then build.exportWar(...).
  7. Build static outputbuild.exportStatic(...) for a PUBLIC-resource zip.
  8. Find and apply patchesfindPatches() / applyPatches().
  9. UpgradeplanUpgrade(...) then applyUpgrade(...).
  10. Configure repositories — inspect and change module repositories.

Errors follow a deliberate split: I/O and integrity failures throw typed exceptions (BuildError / JugglingError / ArgumentError), while business-rule outcomes are returned as values (AggregateStatus, AddUserModulesResult, DeployBatchResult, and so on).

Development

This project uses Bun for dependency management and scripts.

bun install          # install dependencies
bun run typecheck    # tsc --noEmit (strict + exactOptionalPropertyTypes)
bun run lint         # eslint + dependency-cruiser (layer boundaries)
bun run build        # Vite library build → dist/ (ESM + .d.ts)
bun run check        # typecheck + lint + build

Layer rules are enforced in CI: the L0 (model / i18n / expr) and L1 (rules) layers must stay pure, synchronous, and deterministic; cross-layer imports are checked by dependency-cruiser.

Distribution

  • The build is ESM-only and produced by Vite. exports maps each public subpath to its compiled dist/<subpath>/index.js plus a .d.ts type declaration.
  • Node.js >= 22.19 fully supports ESM, so a CommonJS dual build is intentionally not provided.
  • Bundled assets (message catalogs, build templates, juggling.xsd, and related resources) are included in dist/.

License

Distributed under the GNU Lesser General Public License v3.0 (LGPL-3.0-only). The LGPL-3.0 incorporates the terms of the GPL-3.0; both texts are included as LICENSE (LGPL-3.0) and LICENSE.GPL-3.0 (GPL-3.0). See also NOTICE.

Copyright (C) 2026 INTRAMART CORPORATION.