Interactions & overrides

This is where modules interconnect and override each other — always dynamically, never by direct import.

Cross-module services #

import { ModuleServiceRegistry } from '@kubuno/sdk'

// Memo PUBLIE un contrat que d'autres modules pourront appeler (s'ils existent)
ModuleServiceRegistry.publish('memo', {
  openNote: (id: string) => {
    useMemoStore.getState().select(id)
    if (!location.pathname.startsWith('/memo')) {
      history.pushState({}, '', `/memo/${id}`)
      dispatchEvent(new PopStateEvent('popstate'))
    }
  },
})
// …et CONSOMME un service d'un autre module, de façon optionnelle
const createMeeting = ModuleServiceRegistry.get<MeetingFn>('chat', 'createMeeting')
const meeting = await createMeeting?.('Réunion sur la note', attendeeIds)
// `?.` : si le module `chat` n'est pas installé, l'appel n'a simplement pas lieu
Note

Dynamic discovery + optional calls (?.): a module never assumes another one is present.

Slots, overrides, extensions & widgets #

// Surcharger / étendre des emplacements du shell
SlotRegistry.register('app-dialogs', 'memo', MemoBackgroundWorker)   // monté partout
SlotRegistry.register('dashboard-stats-cards', 'memo', MemoStatsCard)
// Remplacer une surface du host par la sienne quand le module est actif
SlotRegistry.registerOverride('empty-state', 'memo', MemoEmptyState)

// Points d'extension ouverts (un module expose, d'autres garnissent)
ExtensionRegistry.register('note-actions', 'memo', { id: 'export-pdf', Component: ExportPdfButton })
const actions = ExtensionRegistry.getAll('note-actions')

// Vignette de tableau de bord
WidgetRegistry.register({ id: 'memo-recent', moduleId: 'memo', Component: RecentNotesWidget, size: 'medium', order: 30 })

SlotRegistry.register injects a component into a named slot; registerOverride replaces a host surface while your module is active; ExtensionRegistry opens points that others fill; WidgetRegistry adds a dashboard widget.

Remember

Shared singletons (React, stores, Radix…): they stay external, never re-bundled — otherwise you get duplicates and a broken UI.