{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n  hasInjectionContext,\n  inject,\n  provide,\n  withContext,\n} from '@andrew_l/context';\nimport {\n  type AnyFunction,\n  type OverwriteWith,\n  isFunction,\n} from '@andrew_l/toolkit';\n\ntype ServiceActorInternal = {\n  traceId: unknown;\n  actorId: unknown;\n  actorType: unknown;\n  [SYM_API]: Record<PropertyKey, Function>;\n  [SYM_MARKER]: boolean;\n  [SYM_RAW]: any;\n  [SYM_DATA]: Record<PropertyKey, unknown>;\n};\n\nexport type AnyServiceActor = {\n  traceId: any;\n  actorId: any;\n  actorType: any;\n  [x: PropertyKey]: any;\n};\n\nexport type ServiceActorData<T extends Record<PropertyKey, any> = {}> =\n  OverwriteWith<\n    {\n      traceId: string;\n      actorId: string | null;\n      actorType: 'unknown' | string;\n    },\n    T\n  >;\n\nexport type ServiceActor<T extends Record<PropertyKey, any> = {}> =\n  ServiceActorData<T> & {\n    assign(params: Partial<ServiceActorData<T>>): ServiceActor<T>;\n  };\n\nconst SYM_MARKER = Symbol();\nconst SYM_RAW = Symbol();\nconst SYM_DATA = Symbol();\nconst SYM_API = Symbol();\n\n/**\n * Create service actor hooks\n *\n * @example\n * const { use: useServiceActor, with: withServiceActor } = serviceActor(() => ({\n *   actorType: 'http-request',\n *   ipAddress: '',\n *  }));\n *\n * app.use((ctx, next) => {\n *   return withServiceActor(\n *     {\n *       traceId: ctx.headers['x-request-id'],\n *       ipAddress: ctx.headers['x-forwarded-for'],\n *     },\n *     next,\n *   );\n * });\n *\n * app.get('/', () => {\n *   const actor = useServiceActor();\n *\n *   // { traceId: 'req_35123', actorId: null, actorType: 'http-request', ipAddress: '::' }\n *   console.log(actor);\n * });\n *\n * @group Main\n */\nexport function serviceActor<T extends Record<PropertyKey, any> = {}>(\n  factory?: () => T,\n): {\n  /**\n   * Wrap a function to execute it with service actor providers\n   */\n  with: <Fn extends AnyFunction>(\n    fn: Fn,\n    params?: Partial<ServiceActor<T>>,\n  ) => Fn;\n\n  /**\n   * Returns the service actor instance from the current context.\n   */\n  inject: () => ServiceActor<T> | undefined;\n\n  /**\n   * Returns the service actor instance from the context, or creates and binds a new instance if none exists.\n   */\n  use: () => ServiceActor<T>;\n} {\n  const injectKey = Symbol();\n\n  let idSeq = 0;\n\n  const createActor = (): AnyServiceActor => {\n    const actor = createServiceActor();\n\n    actor.traceId = `trace-${++idSeq}`;\n\n    if (factory) {\n      actor.assign(factory());\n    }\n\n    return actor;\n  };\n\n  const withHook = <Fn extends AnyFunction>(\n    fn: Fn,\n    params?: Partial<ServiceActor<T>>,\n  ): Fn => {\n    return withContext(function (this: any, ...args: any[]) {\n      const parentActor = inject<ServiceActor>(injectKey);\n      const actor = createActor();\n\n      if (parentActor) {\n        actor.assign(parentActor);\n      }\n\n      if (params) {\n        actor.assign(params);\n      }\n\n      provide(injectKey, actor);\n\n      return fn.apply(this, args);\n    }) as Fn;\n  };\n\n  const injectHook = (): AnyServiceActor | undefined => {\n    return hasInjectionContext() ? inject<ServiceActor>(injectKey) : undefined;\n  };\n\n  const useHok = (): AnyServiceActor => {\n    if (!hasInjectionContext()) {\n      const actor = createActor();\n      provide(injectKey, actor, true);\n\n      return actor;\n    }\n\n    const existed = inject<AnyServiceActor>(injectKey);\n\n    if (existed) return existed;\n\n    const actor = createActor();\n    provide(injectKey, actor);\n\n    return actor;\n  };\n\n  return { with: withHook, use: useHok as any, inject: injectHook as any };\n}\n\nfunction createServiceActor(): ServiceActor {\n  const actor: ServiceActorInternal = {\n    traceId: '',\n    actorId: null,\n    actorType: 'unknown',\n    [SYM_API]: {\n      assign,\n    },\n    [SYM_DATA]: {},\n    [SYM_RAW]: null,\n    [SYM_MARKER]: true,\n  };\n\n  const reservedKeys = new Set(Object.keys(actor));\n\n  actor[SYM_RAW] = actor;\n\n  const newProxy = new Proxy(actor[SYM_DATA], {\n    defineProperty(target, key, value) {\n      if (key in actor) {\n        (actor as any)[key] = value;\n      } else {\n        target[key] = value;\n      }\n\n      return true;\n    },\n    deleteProperty(target, key) {\n      if (key in actor) {\n        delete (actor as any)[key];\n      } else {\n        delete target[key];\n      }\n\n      return true;\n    },\n    has(target, key) {\n      return key in actor || key in target;\n    },\n    ownKeys(target) {\n      return [...reservedKeys, ...Object.keys(target)];\n    },\n    set: function (target, key, value) {\n      if (key in actor[SYM_API]) return false;\n\n      if (key in actor) {\n        Reflect.set(actor, key, value);\n      } else if (isFunction(value)) {\n        Reflect.set(actor[SYM_API], key, value);\n      } else {\n        Reflect.set(target, key, value);\n      }\n\n      return true;\n    },\n    get: (target, key) => {\n      let value: any;\n\n      if (key in actor) {\n        value = Reflect.get(actor, key, value);\n      } else if (key in actor[SYM_API]) {\n        value = Reflect.get(actor[SYM_API], key, value).bind(newProxy);\n      } else {\n        value = Reflect.get(target, key);\n      }\n\n      return value;\n    },\n    getOwnPropertyDescriptor(k) {\n      return {\n        enumerable: true,\n        configurable: true,\n      };\n    },\n  });\n\n  return newProxy as ServiceActor;\n}\n\nfunction assign(this: ServiceActor, params: Record<any, any>) {\n  Object.assign(this, params);\n  return this;\n}\n"],"names":["actor"],"mappings":"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"}