Foundation / @fjell/core

The operation runtime beneath every Item.

Types describe an Item. Validation checks its shape. Core gives the model executable machinery: coordinates, key factories, operation contracts, dictionaries, errors, and events that let User, Company, Address, Team, and Membership objects move through the framework consistently.

What does Core add?

Core is not your business layer and it is not a database adapter. It is the framework runtime that makes the Item model usable by higher layers.

Coordinates

Describe a hierarchy

A coordinate records the key-type array and scopes. For Alex's contained Address, the hierarchy can be ["address","user"].

Factories

Build and recognize Items

IFactory and IQFactory construct keys, Items, and queries without every package inventing its own representation.

Operations

Define the contract

Core operations provide the common vocabulary for create, get, update, remove, find, and query work.

Events + errors

Make changes observable

Standard events and framework errors let libraries, adapters, logs, and callers respond predictably.

Same graph, different coordinates.

User
[user]
PItem · u-42
Company
[company]
PItem · acme-7
Address
[address,user]
CItem · home of u-42
The coordinate tells higher layers how an Item is keyed, located, and routed. A PItem has no parent location; a CItem carries its parent location.

Core also exports key predicates and conversions: primary keys, composite keys, location-key arrays, equality helpers, and query utilities. That shared vocabulary is what allows validation, registry, and lib to agree about the same graph.

Core defines the operation boundary.

import { createCoordinate, IFactory } from "@fjell/core";

const addressCoordinate = createCoordinate(
  ["address", "user"],
  []
);

const factory = new IFactory();
const homeKey = factory.key(
  { pk: "home", loc: [{ kt: "user", lk: "u-42" }] },
  addressCoordinate
);

// Higher layers implement the work behind this contract.
const home = await addressOperations.get(homeKey);

The point is separation: Core knows what a valid operation looks like and how Items are identified. It does not know whether Address data lives in Firestore, PostgreSQL, a filesystem, or somewhere else.

Events connect changes to the rest of the system.

When Alex's User or Address changes, framework events give downstream code a consistent signal. Logging can observe it, caches can invalidate it, providers can refresh it, and application code can react without coupling every package directly to storage.

Create / update / remove

Standard lifecycle vocabulary

Consumers can subscribe to the same event concepts regardless of which Item or adapter produced them.

Errors

Predictable failure boundaries

Core error types distinguish duplicate, missing, invalid, and action failures so the layers above can map them cleanly.

Where Core goes next.

Registry composes and finds instances. Lib wraps Core operations with domain behavior. Storage adapters provide persistence, and routers expose the resulting graph.

Previous: validation →Next: registry →Jump to lib →