{"version":3,"file":"complex.cjs","names":[],"sources":["../src/complex/counter.ts","../src/complex/global-point.ts","../src/complex/global-config.ts","../src/complex/modules-factory.ts","../src/complex/pub-sub.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/complex\n *\n * ## Description\n *\n * Callable **counter** objects with increment, decrement, and reset for UI steppers, pagination,\n * and id generators. Values can be mapped on read so the public API stays typed while the internal\n * tick stays numeric. This file is the `counter` slice of the broader `yummies/complex` entry point.\n *\n * ## Usage\n *\n * ```ts\n * import { createCounter } from \"yummies/complex\";\n * ```\n */\n\nexport interface Counter<TValue = number> {\n  (): TValue;\n  counter: number;\n  value: TValue;\n  increment(): TValue;\n  decrement(): TValue;\n  reset(): void;\n}\n\n/**\n * @deprecated use {`Counter`}. Will be removed in next major release\n */\nexport interface CounterFn<TValue = number> extends Counter<TValue> {}\n\n/**\n * Creates a callable counter object with increment, decrement and reset helpers.\n *\n * The returned function increments the internal numeric counter when called and\n * exposes both the raw counter value and an optionally transformed `value`.\n *\n * @template TValue Public value type returned by the counter.\n * @param processValue Optional mapper that transforms the numeric counter value.\n * @param initial Initial numeric counter value.\n * @returns Callable counter with state and control methods.\n *\n * @example\n * ```ts\n * const counter = createCounter();\n * counter.increment(); // 1\n * ```\n *\n * @example\n * ```ts\n * const idCounter = createCounter((value) => `id-${value}`, 10);\n * idCounter(); // 'id-11'\n * ```\n */\nexport const createCounter = <TValue = number>(\n  processValue?: (value: number) => TValue,\n  initial: number = 0,\n): Counter<TValue> => {\n  const update = (counter: number) => {\n    fn.value = processValue?.(counter) ?? (counter as TValue);\n    return fn.value;\n  };\n\n  const increment = () => update(++fn.counter);\n  const decrement = () => update(--fn.counter);\n\n  const fn: Counter<TValue> = increment as any;\n\n  fn.increment = increment;\n  fn.decrement = decrement;\n\n  fn.reset = () => {\n    fn.counter = initial;\n    fn.value = processValue?.(initial) ?? (initial as TValue);\n  };\n\n  fn.reset();\n\n  return fn as Counter<TValue>;\n};\n","/**\n * ---header-docs-section---\n * # yummies/complex\n *\n * ## Description\n *\n * Minimal **global or scoped storage** with `get` / `set` / `unset` semantics. When an access symbol\n * is provided the value lives on `globalThis`; otherwise it is isolated in a closure. Handy for\n * bridging non-React singletons, test doubles, or legacy globals without `window.foo =` sprawl.\n *\n * ## Usage\n *\n * ```ts\n * import { createGlobalPoint } from \"yummies/complex\";\n * ```\n */\n\nimport type { AnyObject } from 'yummies/types';\n\nexport interface GlobalPoint<TValue> {\n  get(): TValue;\n  set(value: TValue): TValue;\n  unset(): void;\n}\n\n/**\n * Creates a simple storage point that can live either in `globalThis` under a\n * provided key or in a local closure when no key is given.\n *\n * @template TValue Stored value type.\n * @param accessSymbol Optional global property name used for storage.\n * @returns Getter/setter API for the stored value.\n *\n * @example\n * ```ts\n * const point = createGlobalPoint<number>();\n * point.set(10);\n * ```\n *\n * @example\n * ```ts\n * const point = createGlobalPoint<string>('__token__');\n * point.get();\n * ```\n */\nexport const createGlobalPoint = <TValue>(\n  accessSymbol?: keyof any,\n): GlobalPoint<TValue> => {\n  if (accessSymbol == null) {\n    let storedValue: TValue | undefined;\n\n    return {\n      get: (): TValue => storedValue!,\n      unset: () => {\n        storedValue = undefined;\n      },\n      set: (value: TValue): TValue => {\n        storedValue = value;\n        return value;\n      },\n    };\n  }\n\n  const _globalThis = globalThis as AnyObject;\n\n  return {\n    get: (): TValue => _globalThis[accessSymbol],\n    unset: () => {\n      delete _globalThis[accessSymbol];\n    },\n    set: (value: TValue): TValue => {\n      _globalThis[accessSymbol] = value;\n      return value;\n    },\n  };\n};\n","/**\n * ---header-docs-section---\n * # yummies/complex\n *\n * ## Description\n *\n * **Singleton-style config** backed by either `globalThis` (keyed by symbol) or a module closure.\n * Use for app-wide feature flags, bootstrapped locale, or SSR-safe defaults without prop-drilling.\n * Pairs with `createGlobalPoint` for other global handles in the same `yummies/complex` package.\n *\n * ## Usage\n *\n * ```ts\n * import { createGlobalConfig } from \"yummies/complex\";\n * ```\n */\n\nimport type { AnyObject, Maybe } from 'yummies/types';\nimport { createGlobalPoint } from './global-point.js';\n\n/**\n * Creates or reuses a globally accessible config object.\n *\n * The config is stored in a global point identified by `accessSymbol`, or in a\n * local closure when no symbol is provided.\n *\n * @template T Config object type.\n * @param defaultValue Default value used when no config has been created yet.\n * @param accessSymbol Optional global key used to store the config.\n * @returns Existing or newly initialized global config object.\n *\n * @example\n * ```ts\n * const config = createGlobalConfig({ locale: 'en' }, '__app_config__');\n * ```\n *\n * @example\n * ```ts\n * const config = createGlobalConfig({ debug: false });\n * config.debug;\n * ```\n */\nexport const createGlobalConfig = <T extends AnyObject>(\n  defaultValue: T,\n  accessSymbol?: keyof any,\n): T => {\n  const globalPoint = createGlobalPoint<T>(accessSymbol);\n  return globalPoint.get() || globalPoint.set(defaultValue);\n};\n\nexport interface GlobalDynamicConfig<TValue extends AnyObject> {\n  get(): TValue;\n  set(value: TValue): TValue;\n  unset(): void;\n  update(value: Partial<TValue>): void;\n}\n\n/**\n * Creates a mutable global config manager whose value is produced and updated\n * through a custom processor function.\n *\n * @template T Config object type.\n * @param processFn Function that builds the next config state from a partial change and current value.\n * @param accessSymbol Optional global key used to store the config.\n * @returns API for reading, replacing, resetting and partially updating the config.\n *\n * @example\n * ```ts\n * const config = createGlobalDynamicConfig(\n *   (change, current) => ({ theme: 'light', ...current, ...change }),\n *   '__theme__',\n * );\n * ```\n *\n * @example\n * ```ts\n * const config = createGlobalDynamicConfig((change, current) => ({ ...current, ...change }));\n * config.update({ locale: 'ru' });\n * ```\n */\nexport const createGlobalDynamicConfig = <T extends AnyObject>(\n  processFn: (change: Maybe<Partial<T>>, current: Maybe<T>) => T,\n  accessSymbol?: keyof any,\n): GlobalDynamicConfig<T> => {\n  const globalPoint = createGlobalPoint<T>(accessSymbol);\n\n  const getValue = () => {\n    return globalPoint.get() ?? globalPoint.set(processFn(null, null))!;\n  };\n\n  return {\n    get: getValue,\n    set: globalPoint.set,\n    unset: globalPoint.unset,\n    update: (value: Partial<T>) => {\n      const currentValue = getValue();\n      Object.assign(currentValue, processFn(value, currentValue));\n    },\n  };\n};\n","/**\n * ---header-docs-section---\n * # yummies/complex\n *\n * ## Description\n *\n * **Dependency-injection style factory** for classes that take a single deps object in their\n * constructor. Merges predefined singletons with per-call overrides so feature modules can be\n * constructed consistently in apps that avoid heavyweight DI containers.\n *\n * ## Usage\n *\n * ```ts\n * import { ModulesFactory } from \"yummies/complex\";\n * ```\n */\n\nimport type { AnyObject, Class, EmptyObject, IsPartial } from 'yummies/types';\n\ntype ModuleLoaderConfig<TPredefinedDeps extends AnyObject = EmptyObject> = {\n  factory<TInstance, TDeps extends TPredefinedDeps>(\n    moduleClass: Class<TInstance, [TDeps]>,\n    deps: TDeps,\n  ): TInstance;\n} & (TPredefinedDeps extends EmptyObject\n  ? { deps?: TPredefinedDeps }\n  : { deps: TPredefinedDeps });\n\n/**\n * Universal factory for creating class instances with predefined and per-call\n * dependencies.\n *\n * Works with classes whose constructor accepts a single dependency object.\n *\n * @template TPredefinedDeps Dependency shape that is always injected by the factory.\n *\n * @example\n * ```\n * const factory = new ModulesFactory({\n *   factory: (MyClass, deps) => new MyClass(deps),\n *   deps: { someDependency: new Dependency() }\n * });\n *\n * const instance = factory.create(MyClass, { extraDependency: new ExtraDependency() });\n * ```\n *\n * @example\n * ```ts\n * const factory = new ModulesFactory({\n *   factory: (Module, deps) => new Module(deps),\n * });\n * ```\n *\n * @example\n * ```ts\n * const service = factory.create(UserService, { api });\n * ```\n */\nexport class ModulesFactory<TPredefinedDeps extends AnyObject = EmptyObject> {\n  /**\n   * Creates a new module factory.\n   *\n   * @param config Factory strategy and predefined dependencies.\n   *\n   * @example\n   * ```ts\n   * const factory = new ModulesFactory({\n   *   factory: (Module, deps) => new Module(deps),\n   * });\n   * ```\n   *\n   * @example\n   * ```ts\n   * const factory = new ModulesFactory({\n   *   factory: (Module, deps) => new Module(deps),\n   *   deps: { api },\n   * });\n   * ```\n   */\n  constructor(private config: ModuleLoaderConfig<TPredefinedDeps>) {}\n\n  /**\n   * Creates an instance of the provided class by merging predefined and\n   * per-call dependencies.\n   *\n   * @template TInstance Instance type produced by the constructor.\n   * @template TDeps Full dependency object expected by the constructor.\n   * @param Constructor Class constructor receiving a single dependency object.\n   * @param args Additional dependencies merged over predefined ones.\n   * @returns Created class instance.\n   *\n   * @example\n   * ```ts\n   * const service = factory.create(UserService, { logger });\n   * ```\n   *\n   * @example\n   * ```ts\n   * const store = factory.create(UserStore);\n   * ```\n   */\n  create<TInstance, TDeps extends TPredefinedDeps = TPredefinedDeps>(\n    Constructor: Class<TInstance, [TDeps]>,\n    ...args: IsPartial<Omit<TDeps, keyof TPredefinedDeps>> extends true\n      ? [extraDeps?: Omit<TDeps, keyof TPredefinedDeps>]\n      : [extraDeps: Omit<TDeps, keyof TPredefinedDeps>]\n  ) {\n    return this.config.factory(Constructor, {\n      ...this.config.deps!,\n      ...args[0],\n    } as any);\n  }\n}\n","/**\n * ---header-docs-section---\n * # yummies/complex\n *\n * ## Description\n *\n * Tiny **publish–subscribe** bus: subscribers register callbacks, publishers broadcast arguments, and\n * the last payload remains readable for late subscribers. Simpler than full event emitters when you\n * only need in-memory fan-out inside a feature or view-model layer.\n *\n * ## Usage\n *\n * ```ts\n * import { createPubSub } from \"yummies/complex\";\n * ```\n */\n\nexport type SubFn<PubArgs extends any[] = any[]> = (...args: PubArgs) => void;\n\n/**\n * The Publish-Subscribe pattern, which allows objects to interact with each other\n * through an event system. Subscribers can subscribe to events and receive notifications\n * when these events occur. The last published data can be accessed through the `data` property.\n */\nexport interface PubSub<PubArgs extends any[] = any[]> {\n  (...args: PubArgs): void;\n\n  /**\n   * Last published arguments\n   */\n  lastPub: PubArgs | undefined;\n\n  /**\n   * An array of subscriber functions (sub) that will be called\n   * when an event is published. Each subscriber must match the type SubFn,\n   * taking the arguments that will be passed to it when the publisher calls pub.\n   */\n  subs: SubFn<PubArgs>[];\n\n  /**\n   * A function to unsubscribe from events. When a subscriber function (sub) is passed,\n   * it will be removed from the `subs` array, and will no longer receive notifications.\n   */\n  unsub(sub: SubFn<PubArgs>): void;\n  /**\n   * A function to subscribe to events. When a subscriber function (sub) is passed,\n   * it will be added to the `subs` array, and will receive notifications when the publisher calls pub.\n   * Returns a function that can be used to unsubscribe from events.\n   */\n  sub(sub: SubFn<PubArgs>): VoidFunction;\n}\n\n/**\n * Creates a simple publish-subscribe dispatcher that stores the last published\n * arguments and allows subscription management.\n *\n * @template PubArgs Argument tuple delivered to subscribers.\n * @returns Callable publisher with subscribe and unsubscribe helpers.\n *\n * @example\n * ```ts\n * const pub = createPubSub<[string]>();\n * pub('ready');\n * ```\n *\n * @example\n * ```ts\n * const pub = createPubSub<[number]>();\n * const unsub = pub.sub((value) => console.log(value));\n * ```\n */\nexport const createPubSub = <PubArgs extends any[] = any[]>() => {\n  const pubSub = ((...args: PubArgs) => {\n    pubSub.lastPub = args;\n    pubSub.subs.forEach((sub) => {\n      sub(...args);\n    });\n  }) as PubSub<PubArgs>;\n  pubSub.lastPub = undefined;\n\n  pubSub.subs = [];\n\n  pubSub.unsub = (sub: SubFn<PubArgs>) => {\n    pubSub.subs = pubSub.subs.filter((it) => it !== sub);\n  };\n  pubSub.sub = (sub: SubFn<PubArgs>) => {\n    pubSub.subs.push(sub);\n    return () => pubSub.unsub(sub);\n  };\n\n  return pubSub;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,IAAa,iBACX,cACA,UAAkB,MACE;CACpB,MAAM,UAAU,YAAoB;EAClC,GAAG,QAAQ,eAAe,OAAO,KAAM;EACvC,OAAO,GAAG;CACZ;CAEA,MAAM,kBAAkB,OAAO,EAAE,GAAG,OAAO;CAC3C,MAAM,kBAAkB,OAAO,EAAE,GAAG,OAAO;CAE3C,MAAM,KAAsB;CAE5B,GAAG,YAAY;CACf,GAAG,YAAY;CAEf,GAAG,cAAc;EACf,GAAG,UAAU;EACb,GAAG,QAAQ,eAAe,OAAO,KAAM;CACzC;CAEA,GAAG,MAAM;CAET,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;AClCA,IAAa,qBACX,iBACwB;CACxB,IAAI,gBAAgB,MAAM;EACxB,IAAI;EAEJ,OAAO;GACL,WAAmB;GACnB,aAAa;IACX,cAAc,KAAA;GAChB;GACA,MAAM,UAA0B;IAC9B,cAAc;IACd,OAAO;GACT;EACF;CACF;CAEA,MAAM,cAAc;CAEpB,OAAO;EACL,WAAmB,YAAY;EAC/B,aAAa;GACX,OAAO,YAAY;EACrB;EACA,MAAM,UAA0B;GAC9B,YAAY,gBAAgB;GAC5B,OAAO;EACT;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;ACjCA,IAAa,sBACX,cACA,iBACM;CACN,MAAM,cAAc,kBAAqB,YAAY;CACrD,OAAO,YAAY,IAAI,KAAK,YAAY,IAAI,YAAY;AAC1D;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAa,6BACX,WACA,iBAC2B;CAC3B,MAAM,cAAc,kBAAqB,YAAY;CAErD,MAAM,iBAAiB;EACrB,OAAO,YAAY,IAAI,KAAK,YAAY,IAAI,UAAU,MAAM,IAAI,CAAC;CACnE;CAEA,OAAO;EACL,KAAK;EACL,KAAK,YAAY;EACjB,OAAO,YAAY;EACnB,SAAS,UAAsB;GAC7B,MAAM,eAAe,SAAS;GAC9B,OAAO,OAAO,cAAc,UAAU,OAAO,YAAY,CAAC;EAC5D;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzCA,IAAa,iBAAb,MAA6E;CAqBvD;;;;;;;;;;;;;;;;;;;;;CAApB,YAAY,QAAqD;EAA7C,KAAA,SAAA;CAA8C;;;;;;;;;;;;;;;;;;;;;CAsBlE,OACE,aACA,GAAG,MAGH;EACA,OAAO,KAAK,OAAO,QAAQ,aAAa;GACtC,GAAG,KAAK,OAAO;GACf,GAAG,KAAK;EACV,CAAQ;CACV;AACF;;;;;;;;;;;;;;;;;;;;;;ACzCA,IAAa,qBAAoD;CAC/D,MAAM,WAAW,GAAG,SAAkB;EACpC,OAAO,UAAU;EACjB,OAAO,KAAK,SAAS,QAAQ;GAC3B,IAAI,GAAG,IAAI;EACb,CAAC;CACH;CACA,OAAO,UAAU,KAAA;CAEjB,OAAO,OAAO,CAAC;CAEf,OAAO,SAAS,QAAwB;EACtC,OAAO,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,GAAG;CACrD;CACA,OAAO,OAAO,QAAwB;EACpC,OAAO,KAAK,KAAK,GAAG;EACpB,aAAa,OAAO,MAAM,GAAG;CAC/B;CAEA,OAAO;AACT"}