Skip to content

Latest commit

 

History

History
132 lines (75 loc) · 26.4 KB

GLOSSARY.md

File metadata and controls

132 lines (75 loc) · 26.4 KB

Graph Explorer

A React-based web application that lets users visually explore graph databases without writing queries. Connects to property graph and RDF databases over HTTP.

Language

Vertex: A node in the graph — an entity with an ID, one or more types, and attributes. Called "node" in the UI to match user expectations; called "vertex" in code to avoid collision with Node.js global types. Avoid: Node (in code)

Edge: A directed relationship between two vertices (source → target), with a type and optional attributes. Always directed in the data model regardless of graph type. Avoid: Relationship, link

Graph Database: The external graph database a user connects to and explores — the source of all vertices and edges, reached over HTTP via a Connection. It is the user's own data, brought along and queried live; distinct from the local app state (connections, schema cache, styles, sessions) that Graph Explorer keeps in the browser's IndexedDB, plus the per-tab View Layout in sessionStorage. Avoid: Database (ambiguous — clarify remote graph database vs. local persisted state)

Connection: A saved database profile — the Database URL, query language, and optional IAM authentication settings. Each Connection is either a Proxy Connection (the default) or a Direct Connection, and IAM authentication is only available on a Proxy Connection. The Proxy Server is same-origin, so no proxy endpoint is configured. Users create and manage these in the UI. Avoid: Configuration (legacy term being phased out — previously bundled connection + schema + Styles into one object; Configuration-prefixed code names like RawConfiguration or ConfigurationId were renamed to their Connection/SavedConnection forms, see epic #2296. MergedConfiguration, ConfigurationContextProps, useConfiguration, mergeConfiguration, and mergedConfigurationSelector keep the name on purpose, because they describe the merged view of a Connection with its Schema and Styles); proxy endpoint (removed — see ADR unify-docker-image-remove-sagemaker-variant)

Proxy Connection: A Connection whose requests go through the same-origin Proxy Server, which reaches the Database URL on the browser's behalf. The default, and the only kind that can use IAM authentication, because only the Proxy Server can sign a request. The connection form labels it Through the Graph Explorer server. Avoid: server connection

Direct Connection: A Connection whose requests the browser sends to the Database URL itself instead of through the Proxy Server, so the database must allow cross-origin requests from the Graph Explorer page. A supported option for databases that already allow CORS. The connection form labels it Directly from your browser. Avoid: public endpoint, non-proxy connection, browser connection

Database URL: The endpoint of a Connection's Graph Database, stored as graphDbUrl. The Proxy Server sends database requests here, so it must be reachable from the host running Graph Explorer, not from the browser, except for a Direct Connection. Avoid: Graph Connection URL, graph DB URL

Fetch Timeout: A limit the user sets on a Connection for how long Graph Explorer waits for one request. Enforced in the browser; the Graph Database never sees it. Exceeding it has nothing to do with database configuration. Avoid: Timeout (unqualified), client timeout, request timeout

Database Query Timeout: The Graph Database's own limit on how long a query may run, set in its configuration or in the query itself. The database stops the query and reports it in its error response. A memory limit or throttled request is not one even with the same HTTP status. Avoid: Timeout (unqualified), server timeout, deadline exceeded

Active Connection: The one Connection a single browser tab is currently exploring — what the entire app reads to decide which Schema, Session, and queries are in play. Held per-tab (sessionStorage): it survives that tab's reload but dies with the tab, and one tab activating a Connection never changes another tab's Active Connection. Avoid: Active configuration (formerly the code atom activeConfigurationAtom, now activeConnectionIdAtom)

Last Active Connection: A persisted, shared breadcrumb recording the most recently activated Connection across all tabs. Last-writer-wins; used only as the cold-start seed for a fresh tab's Active Connection, never read live by the app.

Default Connection: A Connection injected automatically into an empty store from a defaultConnection.json file the Proxy Server serves, fetched over the same relative path in every deployment mode. Seeded only when no Connections exist, and re-seeded if the last Connection is deleted. When the config names no Query Language, one Default Connection is produced per Query Language. Distinct from the Last Active Connection, which is a persisted breadcrumb rather than a connection. Avoid: Seed connection

Query Language: The graph query protocol a Connection uses — one of Gremlin, openCypher, or SPARQL. Determines which Explorer is instantiated and implies the graph type (Gremlin/openCypher → property graph, SPARQL → RDF). Avoid: Query engine (internal code name queryEngine, but UI says "Query Language")

Query Fragment: A piece of query text that carries its own delimiters, so a template interpolating it never writes quotes around it. Every value reaching a query — a string literal, an identifier such as a Property key or type label, or an IRI — becomes a Query Fragment first. Each Query Language has its own fragments; one language's fragment is not valid in another. Avoid: Query Parameter Value (implies parameterization, which no supported backend offers for identifiers), Query Literal (an identifier is not a literal), Fragment (unqualified — the connector code already calls a Vertex or Edge returned without its attributes a "fragment", which is a result rather than query text)

Vertex Type: A classification of vertices. The schema, styling, filtering, and exploration all operate at the type level. UI label varies by query language: "Node Label" (Gremlin/openCypher), "Class" (SPARQL).

Edge Type: A classification of edges. UI label varies by query language: "Edge Label" (Gremlin), "Relationship Type" (openCypher), "Predicate" (SPARQL).

Composite Label: A single string in which Amazon Neptune joins the multiple labels of one vertex with the reserved :: delimiter (g.addV("A::B")). It appears only on the Gremlin wire (element label, by(label) keys, label() output); openCypher returns labels as an array and never uses ::. Graph Explorer splits a composite label into its constituent Vertex Types once, at the Gremlin ingestion boundary — a Vertex Type is always a single label thereafter. Avoid: Multi-label (describes the vertex, not the joined string), Label list (it is a delimited string, not a list until split)

Icon Source: The classification of a Vertex Type's configured icon into what it takes to render it: lucide (a lucide:<name> reference to bundled, trusted geometry), svg (user-supplied SVG markup, untrusted), raster (an uploaded image's data: url), or none. Derived from iconUrl + iconImageType; the lucide: prefix is authoritative and wins over the image type. Its Icon Source Id is the identity key — namespaced by kind so a url and a lucide name cannot collide — and deliberately carries no color, because one icon is drawn in as many colors as there are Vertex Types using it. Avoid: Icon type (ambiguous with iconImageType, the stored MIME string)

Icon Registry: The single store of resolved icons, keyed by Icon Source Id and shared by every Icon Surface. Holds a color-free artifact — a sanitized SVG string or a raster data: url — so applying a Vertex Type's color stays a pure transform at the point of use. A stored SVG carries a viewBox whenever one can be derived (synthesized from px or unitless width/height when the source omits it), because the surfaces fit icons by preserveAspectRatio (issue #2108). An SVG with neither a viewBox nor such dimensions has no ratio to recover and still fills its box. A plain external store outside React/Jotai, bridged by useSyncExternalStore; explicitly not TanStack Query, because a per-hook subscription scaled with Vertex Type count and locked up the Schema View at 10k. Resolves a raster or SVG data: url synchronously and a Lucide reference asynchronously, and never retries a failure. See docs/adr/20260813-icon-registry-not-react-query.md. Avoid: Icon cache (it is the source of truth for resolution, not a layer in front of one)

Icon Surface: One of the three places an icon is drawn, which differ in how color is applied and how much they trust the markup. The canvas (useBackgroundImageMap → cytoscape background-image) and the sandboxed DOM (VertexSymbolIcon → <image href>) both render the icon as a separate image document, so CSS cannot reach it: an SVG is passed as a data: uri with the color baked into the markup, a raster as its own data: uri. Every icon reaching a surface is a lucide: reference or a data: uri (isAllowedIconValue; see ADR styling-file-format), so no surface references an external url. VertexSymbolIcon places either directly. Both surfaces inset the icon to 60% of the node and fit it with preserveAspectRatio, each in its own way (issue #2108; see ADR icon-registry-not-react-query). Inline DOM (VertexIcon, and the lucide branch of VertexSymbolIcon) renders live elements that inherit color through currentColor, making recolor free. Only trusted lucide geometry is inlined by VertexSymbolIcon; VertexIcon also inlines sanitized user SVG, which predates that rule and is the known outlier. Avoid: Icon renderer (three similarly-named components — VertexIcon, VertexSymbol, VertexSymbolIcon — differ by surface, so name the surface)

Neighbors: Vertices directly connected to a given vertex (one hop away). Users "expand neighbors" to progressively discover the graph. Neighbor counts track total vs. unfetched to indicate how much remains unexplored. Avoid: Connections (ambiguous with Connection)

Attribute Filter: A named property paired with a value that a neighbor's property must contain for that neighbor to be expanded. Only string properties are filterable, and every filter must match. Users add these when expanding neighbors to narrow the results. Avoid: Criterion (implies a configurable operator, which the product does not offer), filter criteria

Session: The set of vertices and edges a user has loaded through exploration for a given Connection. Persisted to IndexedDB so users can close the browser and restore where they left off. Avoid: State, workspace

Graph View: The interactive canvas where vertices and edges are visualized using Cytoscape.js. Users explore the graph here by expanding neighbors and applying a Layout. Nav label: "Graph". Avoid: Graph Explorer (ambiguous with the product name)

Data Table View: Tabular view of all vertices and edges currently in the Session, filterable by type. Complements the Graph View for structured browsing. Avoid: Data Explorer (legacy route name)

Schema View: Visual representation of the Schema — shows vertex types and their edge connections as a graph. Avoid: Schema Explorer (legacy route name)

Layout: The algorithm that positions vertices on a graph canvas, chosen from the layout picker and run by Cytoscape (LayoutName). The unqualified word always means the algorithm; which Layout the user picked is saved in the view's View Layout. Avoid: View Layout (the saved view state, below), graph arrangement

View Layout: The per-tab state of a view that saves and restores the user's selections for convenience, such as which sidebar panel is active, how wide the sidebar is, which content is toggled on, and which Layout is chosen. A per-tab Storage Scope concept, so it survives a tab's reload but not its close, and a fresh tab starts from the View Layout most recently used. The two are Graph View Layout and Schema View Layout. Never shortened to Layout, which is the positioning algorithm. Avoid: Layout (means the algorithm), preferences, settings

Graph View Layout: The View Layout for the Graph View, such as the active sidebar panel, sidebar width, active content toggles, table-view height, and the details-auto-open preference. Avoid: Graph preferences, graph settings

Schema View Layout: The View Layout for the Schema View, such as the active sidebar panel, sidebar width, the details-auto-open preference, and the chosen Layout. Avoid: Schema preferences, schema settings

Storage Scope: The cross-tab behavior a persisted atom picks at creation: per-tab (tabs diverge), shared-reconciled (merged per key), or shared-blind-write. See the per-tab-session-scoped-storage-primitive ADR for which atoms use which. Avoid: Persistence mode, storage strategy

Edge Connection: A schema-level pattern describing how two vertex types can be related via an edge type: sourceVertexType --[edgeType]--> targetVertexType. What the Schema View visualizes. Not an actual edge instance. Avoid: Relationship (Gremlin UI term), Object Property (SPARQL UI term)

Property: A key-value pair on a Vertex or Edge. UI label varies by query language: "Property" (Gremlin/openCypher), "Datatype Property" (SPARQL). Avoid: Attribute (legacy code term being phased out)

Styles: Display customizations per Vertex Type and Edge Type — shape, color, icon, line style, and display labels. A type's style resolves as the User Style if the user has set one, otherwise the App Default Style. Persisted and merged with Schema-discovered metadata to produce the final rendering. The two specific instances are Vertex Styles and Edge Styles, each stored in IndexedDB as its own type-keyed Map. Storage keys follow a user-<entity>-styles convention. The verb is customize; the UI shorthand is your styles. Avoid: User Preferences, preferences, user styling, user settings; "customization" as a standalone noun; Effective styles (no separate atom), style overrides

User Styles: The user's own styles, taking precedence over the app defaults. Per-type edits a user makes in the vertex/edge style dialogs, plus styles loaded from a file. Stored in userVertexStylesAtom (Map<VertexType, VertexStyleStorage>, key "user-vertex-styles") and userEdgeStylesAtom (Map<EdgeType, EdgeStyleStorage>, key "user-edge-styles"). Clearing these ("Reset to Defaults" in Settings) falls back to App Default Styles. A user saves their styles to a file and others load it to get the same look.

App Default Styles: The built-in fallback style, used for any type the user hasn't styled. Hardcoded in the codebase as appDefaultVertexStyle and appDefaultEdgeStyle. Not persisted — always available as the final fallback. In UI copy this is just the default style (the "app" qualifier is internal only).

Schema Sync: The process that queries the database to discover vertex types, edge types, and their attributes. Required before a user can explore a new Connection. Avoid: Fetch, load

Schema: The discovered structure of a connected graph database — vertex types, edge types, their attributes, and how they connect. Populated by Schema Sync when a Connection is first used; not user-defined. Avoid: Model, structure

Exported Connection File: The on-disk JSON format a user gets when they export a Connection (saveConnectionToFile), and which import consumes. It bundles the connection config with a snapshot of the Schema (lastUpdate is an ISO string on disk). A single Zod schema in parseConnectionFile.ts is the source of truth: both the writer and the importer target the same inferred type (ExportedConnectionFile). The writer assigns a Date for lastUpdate and JSON.stringify serializes it to the ISO string; the parser coerces it back via z.coerce.date(). The schema is lenient (every level is a looseObject), so unknown and legacy fields — styling, __inferred/__matches on prefixes, attribute dataType — pass through untouched. It is intentionally decoupled from the in-memory configuration and from the IndexedDB storage shape, so the wire format can evolve independently. So older builds can import it, the writer emits an explicit proxyConnection on every connection, plus the legacy url whenever graphDbUrl is set. In memory, url no longer exists, and proxyConnection is set only as false, to mark a Direct Connection (see ADR unify-docker-image-remove-sagemaker-variant). On import it is split — the connection lands in savedConnectionsAtom, the schema in schemaAtom. Avoid: Configuration file (the wire format is not the in-memory or persisted shape)

File Envelope: The shared { meta, data } wrapper for typed JSON export files (core/fileEnvelope/). meta.kind discriminates the file type and meta.version carries the Format Generation as a Wire Version (see both terms); parseFileEnvelope guards both — rejecting a wrong-kind file and one whose version is newer than the build supports — before the caller validates data per kind. The write contract (createFileEnvelope) also stamps diagnostic timestamp/source/sourceVersion; the read schema keeps only kind/version and strips the rest (along with any unknown field). Consumers today: styling-export and graph-export. The Exported Connection File is the outlier — it predates the envelope and is a flat shape, not wrapped in one. Avoid: Header, wrapper, metadata block

Format Generation: The integer identifying a File Envelope payload's schema version, bumped only on a breaking change (a renamed or removed field); additive changes ship as new optional fields and do not bump it. It is the value parseFileEnvelope guards (reject if newer than the build supports) and the consumer's …ForVersion switch dispatches on. Distinct from the app version (sourceVersion, diagnostic only). Each format owns one named constant for it (GRAPH_EXPORT_VERSION, STYLING_EXPORT_VERSION). Avoid: Version (unqualified — ambiguous with the app version and the Wire Version)

Wire Version: The version value as literally written in a file's meta.version, which normalizes to the Format Generation on read (EnvelopeVersion = number | "1.0"). Usually equals the generation integer, but graph-export writes generation 1 as the decimal string "1.0" (GRAPH_EXPORT_WIRE_VERSION) so builds predating the envelope — which validate version as the literal "1.0" — can still import files this build writes. styling-export has no such installed base and writes the integer 1. So a reader must not assume meta.version is an integer on disk (it always is after normalization). Avoid: Storage version, on-disk version ("storage" means the IndexedDB/persisted shape; "on-disk" already names the whole wire format)

Persistence Status: The single, global state of whether the app's client-side data is safely written to IndexedDB — idle | saving | failed. One source of truth that the Persistence Status Indicator subscribes to. idle = nothing queued and everything durable (no separate "saved" state — visually identical to a fresh session). saving = at least one write queued or in flight, including retryable retries. failed = at least one terminal failure outstanding, carrying failure records for a drill-in detail view. Aggregated across all per-key write queues by precedence: any terminal → failed; else any in-flight → saving; else idle. A failed key clears on its next successful write; status returns to idle when no failure records remain. Deliberately not per-key: a failed write flips the whole status rather than naming which collection failed, because the user cannot act on an individual key (the storage layer retries on their behalf). Lives in a plain external store outside React/Jotai; the React edge bridges it via useSyncExternalStore. Avoid: Save state (ambiguous with Session)

Persistence Status Indicator: The UI element in the nav bar (after the page title) that renders Persistence Status. It surfaces only on failed — a standing danger "Changes not saved" button — and stays absent at idle and saving. Clicking it opens a dialog showing the raw failure records (key, reason, attempt count, last attempt, and the underlying error's name/message/cause) in a read-only JSON editor. The dialog offers to save the configuration to a file via saveLocalForageToFile (core/StateProvider/localDb.ts) when storage is full (quota) — IndexedDB is still readable then — but not when storage is inaccessible (private mode, blocked), since the database never opened and there is nothing to read. Recovery scope is retry (transient failures) plus that backup (terminal-quota failures) — it does not guarantee the write eventually lands. Avoid: Save-status indicator

Proxy Server: The Node.js server that serves the frontend under the Static Mount Path and proxies database requests from the root. The client finds the API root from its own path, so the frontend and proxy are same-origin behind any external prefix, as long as a reverse proxy in front of them forwards the Static Mount Path segment unchanged. A proxy that renames that segment away is a misconfiguration, and Graph Explorer reports it as one. Every database request except a Direct Connection's routes through the Proxy Server, which has network access to the database and handles SigV4 signing. See ADR unify-docker-image-remove-sagemaker-variant. Avoid: proxy endpoint URL (no longer user-configured)

Database Origin Allowlist: The set of database origins the Proxy Server will contact on behalf of any Connection, set by whoever runs the deployment. Unset by default, which means any origin except a link-local IP address, which the Proxy Server always refuses and no allowlist entry can permit. It bounds signed and unsigned requests alike, and never a Direct Connection, whose requests skip the Proxy Server. Together with the database policy on the Proxy Server's AWS identity, it is what limits which databases the users of a deployment can reach. Avoid: allowed origins (the CORS setting), IAM allowlist, database allowlist

Static Mount Path: The path segment, currently /explorer, under which the Proxy Server serves the client's static files. A reverse proxy may put any prefix in front of it but must forward the segment itself intact. The API root is always the path with this segment removed. Avoid: /explorer as a bare literal (the constant is the source of truth); base path (ambiguous with Vite's base and the HTML <base href>)

Connection Link: A #/connect route on the Graph Explorer page, under the Static Mount Path, that an external application builds to hand Graph Explorer a Connection, carrying the params graphDbUrl, queryEngine, awsRegion, serviceType, name. See ADR connection-links for how it is resolved and validated. Avoid: deep link, auto-connect, URL connection params

Connection Link Intent: The action a Connection Link resolves to against the current Connections: activate (it matches an existing Connection; a no-op for the Active Connection), create (no match, so open a pre-filled create form), or invalid (a param fails validation). A Connection matches on Database URL, Query Language, and auth posture (whether IAM is on and, when on, its region and service type). A Direct Connection never has IAM on, so only a link without IAM can match one. Avoid: connection action, deep-link mode

Relationships

  • Each browser tab has at most one Active Connection; different tabs may have different ones
  • The Last Active Connection seeds a fresh tab's Active Connection on cold start only
  • A Connection has exactly one Query Language
  • A Connection has one Schema, populated by Schema Sync
  • A Schema contains Vertex Types, Edge Types, and Edge Connections
  • A Vertex has one or more Vertex Types and zero or more Properties
  • An Edge connects exactly two Vertices (source → target), has one Edge Type, and zero or more Properties
  • An Edge Connection links a source Vertex Type to a target Vertex Type via an Edge Type
  • A Session belongs to a Connection and contains Vertices and Edges
  • Neighbors are Vertices one hop away from a given Vertex
  • Styles are scoped per Vertex Type (Vertex Styles) and Edge Type (Edge Styles)
  • The Graph View, Data Table View, and Schema View all render from the same Session and Schema
  • Each browser tab has its own View Layout per view, the same divergence as Active Connection
  • A Layout positions Vertices on a canvas, and the Layout a user picks for a view is saved in that view's View Layout
  • Every persisted atom picks one of the three Storage Scopes at creation
  • A cancelled request is neither a Fetch Timeout nor a Database Query Timeout
  • A Connection Link resolves to a Connection Link Intent against the current Connections and the Active Connection
  • Activating a different Connection swaps which Session is displayed and keeps the previous one for when that Connection is reactivated. So an activate intent for another Connection, or a create intent whose form is saved, switches the displayed Session, while an activate intent for the Active Connection, an invalid intent, and a cancelled create leave it untouched

Example dialogue

Dev: "When a user creates a new Connection and opens the Graph View, can they start exploring immediately?" Domain expert: "No — a Schema Sync has to complete first. Until the Schema is populated, we don't know what Vertex Types or Edge Types exist, so there's nothing to search or filter by."

Dev: "If a user expands Neighbors on a vertex, do we fetch all connected vertices at once?" Domain expert: "No, it's progressive. We fetch one page at a time and track unfetched Neighbor counts so the user knows how much is left to explore."

Dev: "Are Styles shared across Connections?" Domain expert: "No — well, actually right now they're per Vertex Type and Edge Type globally, not scoped to a specific Connection. So if two databases happen to have the same type name, they'd share styling."