Skip to content

How the packages fit together ​

packages/ holds ten libraries, published internally under the @morph-mapper/* scope. Together they power the template editor: a tool for taking a source file (PDF, table, XML, text, email, or JSON) and visually building a mapping into structured output data. This page is a map of how those ten libraries depend on one another, based on their actual imports, so you know which package to open for a given change.

At a glance

  • types is the shared data model almost everything else imports.
  • context, utils, shared-i18n are small, standalone foundations.
  • ui, schema-serialization, plugins build on the foundations only.
  • file-viewer renders the source file; node-inputs and node-logic build the node editor on top of it.
  • Jump straight to Where do I look for X? if you already know what you're trying to change.

The dependency graph ​

Grouping the packages by who they import from @morph-mapper/* gives four layers. This diagram (and the breakdown below it) reflects the imports found in source today — not a design document nobody's kept in sync with the code.

shared-i18n has no arrows because nothing in packages/ imports it — it's consumed directly by the apps. Click any box to jump to that package's reference. Full detail on each edge:

Foundations — no dependencies on sibling packages ​

  • types — the shared data model: tree nodes, entry types, schema variants, graph/port shapes, and the Zod DTOs for operators/templates/users. Nearly every other package imports from here.
  • utils — generic helpers (getKeys, getEntries, parseOutput, replaceEscapedCharacter, ...) used across the codebase.
  • context — one factory, createContext, for pairing a Zustand store with a React Provider scoped to a subtree.
  • shared-i18n — i18next bootstrap and translation strings. Not imported by any other package here; it's consumed directly by apps.

Built on the foundations only ​

  • ui — shared presentational components. Imports types (e.g. isZodEnum) and utils (e.g. parseOutput).
  • schema-serialization — converts the types tree model to and from a JSON-safe form. Imports types and utils.
  • plugins — the plugin framework and the built-in plugins. Imports types (TreeNode, EntryType, SchemaVariant) and utils, but not context — plugin state is a single global Zustand store (useGlobalPluginStore) rather than a per-subtree one. See Plugin framework for why.

The file being mapped ​

  • file-viewer — renders the source file and lets the user select parts of it. Imports types (to pick a viewer by SchemaVariant) and context (its store is created with @morph-mapper/context's createContext).

The node editor's input layer ​

  • node-inputs — maps the Input enum (from types) to form components. Imports ui for icon actions and, notably, file-viewer's useFileInteraction hook — some inputs (text selector, cell selector) let the user click directly into the file view to fill a field.
  • node-logic — per-filetype rule sets that decide what a node can do. Imports types, utils, and node-inputs (it references Input values when describing which widget a rule's option should render with).

Where do I look for X? ​

I want to...Start in
Change what a node in the graph is allowed to do for a given file typenode-logic
Add a new kind of form input for a node's configurationnode-inputs
Change how a source file is displayed or selectedfile-viewer, file-viewer selection
Write or modify a pluginplugins framework, built-in plugins
Change the shape of a tree node, entry, or schema varianttypes data model
Change how a template is saved to or loaded from the databaseschema-serialization
Add or change a shared UI component (button, badge, cell)ui
Add a new scoped store for a packagecontext
Look up a term you don't recognize (TreeNode, SchemaVariant, PathMode, ...)Glossary

Exact signatures ​

This guide describes relationships, not APIs. For function signatures, types, and props, see the Reference section, generated from source via TypeDoc.