Skip to content

IoC Container

@nhtio/lucid-resourceful-vue-components/ioc

The IoC (Inversion of Control) container centralizes framework‑level services (i18n, validation, HTTP, cache, scheduling, timezones, browser utilities) and exposes them through strongly‑typed resolvers & composables. It enables safe runtime replacement, mutation, and observation of these services without tightly coupling components to concrete implementations.

Tip

Installation / initial setup is shown in the Quickstart. After calling app.use(IoC) (or IoC.install(app, options)), the container instance becomes available for injection.

Note

While the IoC primarily powers the internals of @nhtio/lucid-resourceful-vue-components by supplying shared services to the library itself, it’s intentionally exposed so you can reuse it from your own components and application code when helpful.

Required foundation (and optional extras)

You must install the IoC plugin for any component or composable from this library to function – it wires up translations, validation, HTTP, caching and more behind the scenes.

Once installed, you can also tap into those same services directly in your own app code:

  • Translations & validation (shared locale + rules)
  • HTTP requests with consistent request/response handling
  • Caching for ephemeral data
  • Lightweight scheduling via MilliCron
  • Timezone helpers (zones, current selection, options)
  • Browser utilities (platform/user‑agent convenience)

Customization is optional: if the defaults suit you, just install and forget. If not, replace or wrap a service (examples below).

Imports you’ll use

From @nhtio/lucid-resourceful-vue-components/ioc:

  • IoC – the Vue plugin.
  • setIocService(key, resolver) – replace a service at runtime.

From @nhtio/lucid-resourceful-vue-components/composables:

  • All use* composables (documented below).

Provided Services (default resolvers)

KeyDescription
i18nTranslator service (I18nTranslator). Drives locale & messages.
validationValidation root (ValidationRoot). Automatically re-linked to i18n when either changes.
httpNormalized HTTP service (ResourcefulHttpService).
cacheIn‑memory cache (ResourcefulMemoryCache).

Additional utility accessors exposed on the IoC instance (not part of IoCServices keys):

  • cronMilliCron scheduler.
  • timezonesResourcefulTimezoneInformation (zones, current, options helpers).
  • browserBrowserService abstraction.

Composables (import from @nhtio/lucid-resourceful-vue-components/composables)

All use* helpers are exported via the composables module (not the ioc barrel). Import them like:

ts
import { useIoC, useI18n, useValidation, useHttp, useCache, useCron, useCronTab, useTimezones, useTimezoneZones, useCurrentTimezone, useTimezoneOptions, useBrowser } from '@nhtio/lucid-resourceful-vue-components/composables'

Composable Summary

ComposableReturns
useIoC()The container instance (throws if not installed).
useI18n()Current translator service.
useValidation()Validation root bound to translator.
useHttp()HTTP service.
useCache()Memory cache.
useCron()MilliCron scheduler daemon.
useCronTab(crontab, callback)Registers a scheduled callback; returns cancel() to abort. Automatically unregistered on component unmount.
useTimezones()Full timezone information object.
useTimezoneZones()Array of raw zone objects.
useCurrentTimezone()Active timezone (or undefined).
useTimezoneOptions()Array of select options for UI pickers.
useBrowser()Browser utility service.

Typical usage

ts
import { useI18n, useHttp, useCache, useCronTab, useTimezoneOptions, useBrowser } from '@nhtio/lucid-resourceful-vue-components/composables'

const i18n = useI18n()
const http = useHttp()
const cache = useCache()
const options = useTimezoneOptions()
const browser = useBrowser()

// Translate
const title = i18n.t('users.title')

// HTTP request (typed by your app’s usage)
const users = await http.request({ url: '/api/users', method: 'GET' })

// Cache something
cache.set('users:list', users)

// Schedule a task every minute
const cancel = useCronTab('* * * * *', () => {
  // e.g., refresh a token or poll
})

// Detect user agent
const isMobile = browser.isMobile

Customizing services

Replace a Service

Use setIocService when you have a new resolver (factory) for a service:

ts
import { setIocService } from '@nhtio/lucid-resourceful-vue-components/ioc'
import { MyTranslator } from './my-translator'

setIocService('i18n', () => new MyTranslator(/* ... */))
// `validation` automatically re-binds to new i18n.

Mutate a service in place

Access the container directly with useIoC() for advanced mutations:

ts
import { useIoC } from '@nhtio/lucid-resourceful-vue-components/composables'

const ioc = useIoC()

ioc.mutate('http', (current) => () => ({
  // Wrap existing service to add logging
  ...current,
  request: async (opts) => {
    console.debug('[http]', opts)
    return current.request(opts)
  }
}))

mutate(key, mutator, bubble = true) receives the current concrete instance and must return a new resolver. When bubble is true (default) an update event is emitted.

Errors you might see

  • Setting an unknown key throws Invalid IoC Service: <key>.
  • Getting a missing service throws IoC Service not found: <key> (should only occur if manually deleted).
  • Using any composable before installation throws a descriptive error guiding you to install the plugin.

Listening for changes (optional)

The container emits events (via a typed event emitter) whenever a service changes:

EventTrigger
i18n:updatedi18n resolver replaced or mutated.
i18n:locale:updated(Emitted internally by translator when locale changes.)
validation:updatedValidation service replaced/mutated (also on i18n change due to rebinding).
http:updatedHTTP service replaced/mutated.
cache:updatedCache service replaced/mutated.

Usage (with the container instance):

ts
const ioc = useIoC()

function handleI18nChanged() {
  // re-fetch localized data, update UI, etc.
}

ioc.on('i18n:updated', handleI18nChanged)

// One-time listener
ioc.once('http:updated', () => console.info('HTTP layer swapped'))

// Later: remove
ioc.off('i18n:updated', handleI18nChanged)

Scheduling with cron

useCron() exposes the underlying MilliCron daemon; useCronTab() is a convenience for lifecycle-managed scheduling.

ts
import { useCronTab } from '@nhtio/lucid-resourceful-vue-components/composables'

// Every minute
const cancel = useCronTab('* * * * *', () => {
  // perform polling or cleanup
})

// Optional manual cancellation before unmount
cancel()

Timezone utilities

ts
import { useTimezoneOptions, useCurrentTimezone } from '@nhtio/lucid-resourceful-vue-components/composables'

const options = useTimezoneOptions()
const current = useCurrentTimezone()

Use options to build select menus and current for formatting decisions.

Common customizations

  • Point HTTP to your API base URL or add logging/metrics.
  • Swap the translator to your app’s i18n backend.
  • Provide a custom cache strategy.

Import the plugin & setIocService from ioc, and all runtime composables from composables.