index.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /** Read-only projection of the current Cordis Loader plugin entries. */
  2. import type { Context, FiberState } from '@deepseek-ai/cordis'
  3. import type {} from '@deepseek-ai/cordis-plugin-loader'
  4. import { TypertRemoteService, Remote } from '@deepseek-ai/dsh-typert-protocol'
  5. // Typert-generated ./typert and ./remote artifacts import Zod at runtime.
  6. import type {} from 'zod'
  7. import type {
  8. PluginEntryId,
  9. PluginFiberPhase,
  10. PluginInventoryEntry,
  11. PluginInventorySnapshot,
  12. } from './types.ts'
  13. export type * from './types.ts'
  14. /** Brand an existing Loader-tree entry id at the owning boundary. */
  15. function pluginEntryId(value: string): PluginEntryId {
  16. return value as PluginEntryId
  17. }
  18. /** Runtime mirror: FiberState is a cross-package const enum. */
  19. const FIBER_STATE = {
  20. PENDING: 0 as FiberState.PENDING,
  21. LOADING: 1 as FiberState.LOADING,
  22. ACTIVE: 2 as FiberState.ACTIVE,
  23. FAILED: 3 as FiberState.FAILED,
  24. DISPOSED: 4 as FiberState.DISPOSED,
  25. UNLOADING: 5 as FiberState.UNLOADING,
  26. } as const
  27. /** Complete public projection of Cordis Fiber states. */
  28. const FIBER_PHASE = {
  29. [FIBER_STATE.PENDING]: 'pending',
  30. [FIBER_STATE.LOADING]: 'loading',
  31. [FIBER_STATE.ACTIVE]: 'active',
  32. [FIBER_STATE.FAILED]: 'failed',
  33. [FIBER_STATE.DISPOSED]: null,
  34. [FIBER_STATE.UNLOADING]: 'unloading',
  35. } as const satisfies Record<FiberState, PluginFiberPhase>
  36. /** Remote-only service exposing the Loader's current non-group entry state. */
  37. export class PluginInventoryGateway extends TypertRemoteService {
  38. static inject = ['loader']
  39. constructor(ctx: Context) {
  40. super(ctx, 'pluginInventory')
  41. }
  42. /**
  43. * Read the Loader directly on every call. Cordis's internal plugin/status
  44. * events already maintain Entry.fiber and Fiber.state, so a second cache
  45. * would only add another lifecycle truth to keep synchronized.
  46. * @returns Current non-group Loader entries in Loader order.
  47. */
  48. @Remote('list')
  49. list(): PluginInventorySnapshot {
  50. const entries: PluginInventoryEntry[] = []
  51. for (const entry of this.ctx.loader.entries()) {
  52. if (entry.options.group) continue
  53. entries.push({
  54. entryId: pluginEntryId(entry.id),
  55. moduleName: entry.options.name,
  56. enabled: !entry.disabled,
  57. fiberPhase: entry.fiber === undefined ? null : FIBER_PHASE[entry.fiber.state],
  58. })
  59. }
  60. return { entries }
  61. }
  62. }
  63. export default PluginInventoryGateway