@lorion-org/registry-hub
v1.0.0-beta.2
Published
Framework-free typed registry and registry-hub primitives.
Readme
@lorion-org/registry-hub
Framework-free typed registry and registry-hub primitives.
This package provides small registry primitives for systems that need typed named entries without coupling the registry to a framework runtime. It stays intentionally small and does not know anything about Nuxt, Nitro, H3, or app-specific lifecycle hooks.
Design goals
- generic names for reusable runtime terms
- deterministic overwrite behavior for duplicate item ids
- lazy registry creation via the hub
- no framework globals, events, priorities, or persistence
entries()covers explicit inspect/debug and enumeration use cases in v1
Installation
pnpm add @lorion-org/registry-hubWhen not to use this package
This package is intentionally small. It is not a fit if you need:
- ordered or priority-based plugin execution
- unregister or disposal semantics
- async lifecycle orchestration
- persistence or distributed registry state
API
import { createRegistry, createRegistryHub } from '@lorion-org/registry-hub';Create a single registry
import { createRegistry, type RegistryItem } from '@lorion-org/registry-hub';
type PaymentProvider = RegistryItem & {
createCheckoutPath: (input: { shopId: string }) => string;
};
const paymentProviders = createRegistry<PaymentProvider>('payment-checkout-providers');
paymentProviders.register({
id: 'payment-provider-stripe',
createCheckoutPath: (input) =>
`/providers/payment-provider-stripe/checkout?shop=${encodeURIComponent(input.shopId)}`,
});
paymentProviders.get('payment-provider-stripe');
paymentProviders.list();
paymentProviders.entries();Use a registry hub
import { createRegistryHub, type RegistryItem } from '@lorion-org/registry-hub';
type Shop = RegistryItem & {
path: string;
};
const hub = createRegistryHub();
hub.createRegistry<Shop>('shops');
hub.register<Shop>('shops', { id: 'shop-coffee', path: '/shops/coffee' });
const shop = hub.get<Shop>('shops', 'shop-coffee');
const shops = hub.list<Shop>('shops');
const registries = hub.entries();Shop registry example
import { createRegistry, type RegistryItem } from '@lorion-org/registry-hub';
type Shop = RegistryItem & {
name: string;
path: string;
};
const shops = createRegistry<Shop>('shops');
shops.register([
{ id: 'shop-coffee', name: 'Bean Supply', path: '/shops/coffee' },
{ id: 'shop-stationery', name: 'Paper Desk', path: '/shops/stationery' },
]);
const knownShops = shops.entries();Framework recipe
The package does not ship framework bindings, but it is designed to be easy to inject into one.
import { createRegistryHub } from '@lorion-org/registry-hub';
export default defineNuxtPlugin(() => {
const registryHub = createRegistryHub();
return {
provide: {
registryHub,
},
};
});Another plugin can then consume that injected hub and register its own entries.
import type { RegistryItem } from '@lorion-org/registry-hub';
type Shop = RegistryItem & {
name: string;
path: string;
};
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.$registryHub.register<Shop>('shops', {
id: 'shop-coffee',
name: 'Bean Supply',
path: '/shops/coffee',
});
});A composable can later load all entries of one typed registry from that same hub.
import type { RegistryItem } from '@lorion-org/registry-hub';
type Shop = RegistryItem & {
name: string;
path: string;
};
export function useShops(): Shop[] {
return useNuxtApp().$registryHub.list<Shop>('shops');
}Runnable example files live in examples/.
The Node example imports the published package name instead of local source files so it mirrors real consumer usage.
The examples use the same shop and checkout-provider domain as the LORION playgrounds.
Local commands
cd packages/registry-hub
pnpm build
pnpm test
pnpm coverage
pnpm typecheck
pnpm package:checkpnpm package:check builds the package, runs pnpm pack --dry-run, and
validates the published package shape with publint.
