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.