{"version":3,"sources":["../src/dynamic-table-state-helper.ts","../src/http-context-tokens.ts","../src/types.ts","../src/utils.ts","../src/paged-table-state-helper.ts","../src/table-utils.ts","../src/memoized-data-storage.ts","../src/component-state.ts","../src/component-data-storage.ts","../src/ng-select-helper.ts","../src/offset-paginated-ng-select-state.ts","../src/ng-select-utils.ts","../src/offset-paginated-prime-ng-table-state.ts"],"sourcesContent":["import { HttpClient, HttpContext } from \"@angular/common/http\";\nimport { signal, Signal } from \"@angular/core\";\nimport { signalState, patchState } from \"@ngrx/signals\";\nimport { FilterMetadata } from \"primeng/api\";\nimport { Table, TableLazyLoadEvent } from \"primeng/table\";\nimport { firstValueFrom } from \"rxjs\";\n\nimport { SkipLoadingSpinner } from \"./http-context-tokens\";\nimport {\n  DynamicQueryDto,\n  DynamicQueryFilterDto,\n  DynamicQuerySortDto,\n  PagedDataResponse,\n  PrimeNgTableState,\n  PrimeNgTableStateHelperQueryParam,\n  FilterTypeMapped,\n  dynamicQueryResponseZodSchema,\n} from \"./types\";\nimport { routeParamConcat } from \"./utils\";\n\n/**\n * Initial state factory function for dynamic table\n */\nfunction initialDynamicState<T>(): PrimeNgTableState<T> {\n  return {\n    data: [],\n    isLoading: false,\n    totalRecords: 0,\n    size: 15,\n    page: 1,\n    filter: [],\n    sort: [],\n  };\n}\n\n/**\n * Calculates pagination parameters from PrimeNG table lazy load event\n * @param event - The PrimeNG table lazy load event\n * @param defaultValue - Default pagination values if event is null\n * @returns Object containing page and limit for pagination\n */\nexport function calculatePrimengTablePagination(\n  event: TableLazyLoadEvent | null,\n  defaultValue: { page: number; limit: number } = { page: 1, limit: 15 }\n) {\n  if (!event) {\n    return defaultValue;\n  }\n  const page =\n    event.first && event.rows ? Math.floor(event.first / event.rows) : 0;\n\n  const limit = event.rows ?? 15;\n\n  return { page: page + 1, limit };\n}\n\n/**\n * Options for creating PrimeNgDynamicTableStateHelper\n */\ntype PrimeNgDynamicTableStateOpts = {\n  url: string;\n  httpClient: HttpClient;\n  skipLoadingSpinner?: boolean;\n};\n\n/**\n * PrimeNG Dynamic Table State Helper class for managing table state with lazy loading, filtering, and sorting\n *\n * This helper provides advanced table functionality including:\n * - Lazy loading with pagination\n * - Column filtering with multiple filter types\n * - Multi-column sorting\n * - State management with NgRx Signals\n * - Automatic API integration\n * - Route parameter support\n * - Query parameter management\n *\n * @example\n * ```typescript\n * const tableState = PrimeNgDynamicTableStateHelper.create<User>({\n *   url: '/api/users',\n *   httpClient: this.httpClient\n * });\n *\n * // In template\n * <p-table [value]=\"tableState.data()\"\n *          [lazy]=\"true\"\n *          [loading]=\"tableState.isLoading()\"\n *          [totalRecords]=\"tableState.totalRecords()\"\n *          (onLazyLoad)=\"tableState.onLazyLoad($event)\">\n * </p-table>\n * ```\n */\nexport class PrimeNgDynamicTableStateHelper<T> {\n  private readonly state = signalState<PrimeNgTableState<T>>(\n    initialDynamicState<T>()\n  );\n  private urlWithOutRouteParam: string;\n  private skipLoadingSpinner: boolean;\n  readonly #uniqueKey = signal(\"id\");\n  readonly uniqueKey = this.#uniqueKey.asReadonly();\n  #queryParams: PrimeNgTableStateHelperQueryParam = {};\n\n  // Public readonly signals\n  readonly totalRecords: Signal<number> = this.state.totalRecords;\n  readonly isLoading: Signal<boolean> = this.state.isLoading;\n  readonly data: Signal<Array<T>> = this.state.data;\n\n  private constructor(\n    private url: string,\n    private readonly httpClient: HttpClient,\n    skipLoadingSpinner: boolean = true\n  ) {\n    this.urlWithOutRouteParam = url;\n    this.skipLoadingSpinner = skipLoadingSpinner;\n  }\n\n  /**\n   * Creates a new instance of PrimeNgDynamicTableStateHelper\n   * @param options - Configuration options\n   * @returns New instance of PrimeNgDynamicTableStateHelper\n   */\n  public static create<T>(\n    options: PrimeNgDynamicTableStateOpts\n  ): PrimeNgDynamicTableStateHelper<T> {\n    return new PrimeNgDynamicTableStateHelper<T>(\n      options.url,\n      options.httpClient,\n      options.skipLoadingSpinner ?? true\n    );\n  }\n\n  /**\n   * Sets whether to skip the loading spinner\n   * @param skip - Whether to skip the loading spinner\n   * @returns This instance for method chaining\n   */\n  public setSkipLoadingSpinner(skip: boolean): this {\n    this.skipLoadingSpinner = skip;\n    return this;\n  }\n\n  /**\n   * Sets the unique key field for table rows\n   * @param newUniqueKey - The field name to use as unique identifier\n   * @returns This instance for method chaining\n   */\n  public setUniqueKey(newUniqueKey: string): this {\n    this.#uniqueKey.set(newUniqueKey);\n    return this;\n  }\n\n  /**\n   * Updates the API URL\n   * @param newUrl - The new API URL\n   * @returns This instance for method chaining\n   */\n  public setUrl(newUrl: string): this {\n    this.url = newUrl;\n    this.urlWithOutRouteParam = newUrl;\n    return this;\n  }\n\n  /**\n   * Appends a route parameter to the URL\n   * @param newRouteParam - The route parameter to append\n   * @returns This instance for method chaining\n   */\n  public setRouteParam(newRouteParam: string): this {\n    this.url = routeParamConcat(this.urlWithOutRouteParam, newRouteParam);\n    return this;\n  }\n\n  /**\n   * Patches existing query parameters\n   * @param value - Query parameters to merge\n   * @returns This instance for method chaining\n   */\n  public patchQueryParams(value: PrimeNgTableStateHelperQueryParam): this {\n    this.#queryParams = { ...this.#queryParams, ...value };\n    return this;\n  }\n\n  /**\n   * Removes a specific query parameter\n   * @param key - The key to remove\n   * @returns This instance for method chaining\n   */\n  public removeQueryParam(key: string): this {\n    delete this.#queryParams[key];\n    return this;\n  }\n\n  /**\n   * Sets all query parameters (replaces existing)\n   * @param newQueryParams - New query parameters\n   * @returns This instance for method chaining\n   */\n  public setQueryParams(\n    newQueryParams: PrimeNgTableStateHelperQueryParam\n  ): this {\n    this.#queryParams = newQueryParams;\n    return this;\n  }\n\n  /**\n   * Handles PrimeNG table lazy load events\n   * @param event - The lazy load event from PrimeNG table\n   */\n  public async onLazyLoad(event: TableLazyLoadEvent): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    patchState(this.state, {\n      size: event.rows || 15,\n      page: Math.floor((event.first || 0) / (event.rows || 15)) + 1,\n      filter: this.filterMapper(event.filters || {}),\n      sort:\n        Object.keys(event.multiSortMeta || {}).length > 0\n          ? (event.multiSortMeta || []).map((sort: any) => ({\n              field: sort.field,\n              dir: (sort.order === 1 ? \"asc\" : \"desc\") as \"asc\" | \"desc\",\n            }))\n          : event.sortField\n          ? [\n              {\n                field: event.sortField,\n                dir: ((event.sortOrder || 1) === 1 ? \"asc\" : \"desc\") as\n                  | \"asc\"\n                  | \"desc\",\n              },\n            ]\n          : [],\n    });\n\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Clears table data and resets to first page\n   * @param table - Optional PrimeNG Table reference to reset\n   */\n  public async clearTableData(table?: Table): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    patchState(this.state, {\n      data: [],\n      totalRecords: 0,\n      page: 1,\n      filter: [],\n      sort: [],\n    });\n\n    if (table) {\n      table.reset();\n    }\n\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Manually triggers data refresh with current state\n   */\n  public async refresh(): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Fetches data from the API\n   */\n  private async fetchData(dto: DynamicQueryDto): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    try {\n      patchState(this.state, { isLoading: true });\n\n      const params = new URLSearchParams();\n      Object.entries(this.#queryParams).forEach(([key, value]) => {\n        params.append(key, String(value));\n      });\n\n      const urlWithParams = params.toString()\n        ? `${this.url}?${params.toString()}`\n        : this.url;\n\n      const response = await firstValueFrom(\n        this.httpClient.post(urlWithParams, dto, {\n          context: new HttpContext().set(\n            SkipLoadingSpinner,\n            this.skipLoadingSpinner\n          ),\n        })\n      );\n\n      const validatedResponse = dynamicQueryResponseZodSchema.parse(response);\n\n      patchState(this.state, {\n        data: validatedResponse.data,\n        totalRecords: validatedResponse.last_row,\n        isLoading: false,\n      });\n    } catch (error) {\n      patchState(this.state, {\n        data: [],\n        totalRecords: 0,\n        isLoading: false,\n      });\n      throw error;\n    }\n  }\n\n  /**\n   * Builds the DTO for API requests\n   */\n  private dtoBuilder(): DynamicQueryDto {\n    return {\n      size: this.state.size(),\n      page: this.state.page(),\n      filter: this.state.filter(),\n      sort: this.state.sort(),\n    };\n  }\n\n  /**\n   * Maps PrimeNG filters to API filter format\n   */\n  private filterMapper(\n    dto: Record<string, FilterMetadata | FilterMetadata[] | undefined>\n  ): DynamicQueryFilterDto[] {\n    const filters: DynamicQueryFilterDto[] = [];\n\n    Object.entries(dto).forEach(([field, filterData]) => {\n      if (!filterData) return;\n\n      const processFilter = (filter: FilterMetadata) => {\n        if (\n          filter.value === null ||\n          filter.value === undefined ||\n          filter.value === \"\"\n        )\n          return;\n\n        const mappedType = this.evaluateInput(filter.matchMode || \"contains\");\n        if (mappedType) {\n          filters.push({\n            field,\n            value: String(filter.value),\n            type: mappedType,\n          });\n        }\n      };\n\n      if (Array.isArray(filterData)) {\n        filterData.forEach(processFilter);\n      } else {\n        processFilter(filterData);\n      }\n    });\n\n    return filters;\n  }\n\n  /**\n   * Maps PrimeNG filter match modes to API filter types\n   */\n  private evaluateInput(input: string): FilterTypeMapped | null {\n    const filterMap: Record<string, FilterTypeMapped> = {\n      startsWith: \"starts\",\n      notStartsWith: \"!starts\",\n      endsWith: \"ends\",\n      notEndsWith: \"!ends\",\n      contains: \"like\",\n      notContains: \"!like\",\n      equals: \"=\",\n      notEquals: \"!=\",\n      greaterThan: \">\",\n      lessThan: \"<\",\n      greaterThanOrEqual: \">=\",\n      lessThanOrEqual: \"<=\",\n    };\n\n    return filterMap[input] || null;\n  }\n}","import { HttpContextToken } from \"@angular/common/http\";\n\n/**\n * HTTP Context Token to skip loading spinner on HTTP requests\n * Usage: Set this token to true in HttpContext to skip showing loading spinner\n *\n * @example\n * ```typescript\n * const context = new HttpContext().set(SkipLoadingSpinner, true);\n * this.httpClient.get('/api/data', { context });\n * ```\n */\nexport const SkipLoadingSpinner = new HttpContextToken(() => false);\n","import { z } from \"zod\";\n\n// ===============================================================================\n// TypeScript Utility Types\n// ===============================================================================\n\n/**\n * Makes all properties of T nullable (T | null) recursively, handling functions, arrays, and objects\n * @template Thing - The type to make nullable\n * @example\n * ```typescript\n * type User = { id: number; name: string; email: string; tags: string[] };\n * type NullableUser = RecursiveNullable<User>;\n * // Result: {\n * //   id: number | null;\n * //   name: string | null;\n * //   email: string | null;\n * //   tags: (string | null)[] | null;\n * // }\n * ```\n */\nexport type RecursiveNullable<Thing> = Thing extends Function\n  ? Thing\n  : Thing extends Array<infer InferredArrayMember>\n  ? RecursiveNullableArray<InferredArrayMember>\n  : Thing extends Record<string, any>\n  ? RecursiveNullableObject<Thing>\n  : Exclude<Thing, undefined> | null;\n\ntype RecursiveNullableObject<Thing extends object> = {\n  [Key in keyof Thing]: RecursiveNullable<Thing[Key]>;\n};\n\ninterface RecursiveNullableArray<Thing> extends Array<RecursiveNullable<Thing>> {}\n\n/**\n * Makes all properties of T nullish (T | null | undefined)\n * @template T - The base type\n * @example\n * ```typescript\n * type User = { id: number; name: string };\n * type NullishUser = Nullish<User>;\n * // Result: { id: number | null | undefined; name: string | null | undefined }\n * ```\n */\nexport type Nullish<T> = {\n  [P in keyof T]: Exclude<T[P], null | undefined> | null | undefined;\n};\n\n/**\n * Makes all properties of T nullish (T | null | undefined) recursively, handling functions, arrays, and objects\n * @template Thing - The type to make nullish\n * @example\n * ```typescript\n * type User = { id: number; profile: { name: string; age: number }; tags: string[] };\n * type NullishUser = RecursiveNullish<User>;\n * // Result: {\n * //   id: number | null | undefined;\n * //   profile: {\n * //     name: string | null | undefined;\n * //     age: number | null | undefined\n * //   } | null | undefined;\n * //   tags: (string | null | undefined)[] | null | undefined;\n * // }\n * ```\n */\nexport type RecursiveNullish<Thing> = Thing extends Function\n  ? Thing\n  : Thing extends Array<infer InferredArrayMember>\n  ? RecursiveNullishArray<InferredArrayMember>\n  : Thing extends Record<string, any>\n  ? RecursiveNullishObject<Thing>\n  : Exclude<Thing, null | undefined> | null | undefined;\n\ntype RecursiveNullishObject<Thing extends object> = {\n  [Key in keyof Thing]: RecursiveNullish<Thing[Key]>;\n};\n\ninterface RecursiveNullishArray<Thing> extends Array<RecursiveNullish<Thing>> {}\n\n/**\n * Makes all properties optional recursively, useful for partial updates, handling functions, arrays, and objects\n * @template Thing - The type to make recursively partial\n * @example\n * ```typescript\n * type User = {\n *   id: number;\n *   profile: { name: string; age: number };\n *   settings: { theme: string; notifications: boolean };\n *   tags: string[];\n * };\n * type PartialUser = RecursivePartial<User>;\n * // Result: {\n * //   id?: number | undefined;\n * //   profile?: { name?: string | undefined; age?: number | undefined } | undefined;\n * //   settings?: { theme?: string | undefined; notifications?: boolean | undefined } | undefined;\n * //   tags?: (string | undefined)[] | undefined;\n * // }\n * ```\n */\nexport type RecursivePartial<Thing> = Thing extends Function\n  ? Thing\n  : Thing extends Array<infer InferredArrayMember>\n  ? RecursivePartialArray<InferredArrayMember>\n  : Thing extends object\n  ? RecursivePartialObject<Thing>\n  : Thing | undefined;\n\ntype RecursivePartialObject<Thing> = {\n  [Key in keyof Thing]?: RecursivePartial<Thing[Key]>;\n};\n\ninterface RecursivePartialArray<Thing> extends Array<RecursivePartial<Thing>> {}\n\n// ===============================================================================\n// Core Data Types\n// ===============================================================================\n\n/**\n * Enumeration for manipulation types in component operations\n * Used for tracking the current operation state in component management\n *\n * @example\n * ```typescript\n * // In a component\n * currentOperation: ManipulationType = ManipulationType.Create;\n *\n * // Check operation type\n * if (this.currentOperation === ManipulationType.Update) {\n *   // Handle update logic\n * }\n * ```\n */\nexport enum ManipulationType {\n  /** Creating a new item */\n  Create = \"create\",\n  /** Updating an existing item */\n  Update = \"update\",\n  /** Creating a child item */\n  CreateChild = \"create-child\",\n  /** Deleting an item */\n  Delete = \"delete\",\n  /** Viewing item details */\n  View = \"view\",\n  /** Saving an item */\n  Save = \"save\"\n}\n\n/**\n * Key-value pair type for common data structures\n * @template K The type of the key\n * @template D The type of the data\n */\nexport interface KeyData<K, D> {\n  key: K;\n  data: D;\n}\n\n/**\n * Common API response wrapper type\n * @template T The type of the data payload\n */\nexport interface ApiResponse<T> {\n  data: T;\n  message?: string;\n  status: number;\n  success: boolean;\n}\n\n/**\n * Pagination metadata interface\n */\nexport interface PaginationMeta {\n  currentPage: number;\n  totalPages: number;\n  totalItems: number;\n  itemsPerPage: number;\n  hasNextPage: boolean;\n  hasPreviousPage: boolean;\n}\n\n/**\n * Paginated response type\n * @template T The type of the data items\n */\nexport interface PaginatedResponse<T> {\n  data: T[];\n  meta: PaginationMeta;\n}\n\n/**\n * Query parameters for pagination\n */\nexport interface PaginationParams {\n  page?: number;\n  limit?: number;\n  offset?: number;\n}\n\n/**\n * Common sort parameters\n */\nexport interface SortParams {\n  sortBy?: string;\n  sortOrder?: \"asc\" | \"desc\";\n}\n\n/**\n * Combined query parameters for API requests\n */\nexport type QueryParams = Record<string, string | number | boolean> &\n  Partial<PaginationParams> &\n  Partial<SortParams>;\n\n// ===============================================================================\n// Table State Types\n// ===============================================================================\n\n/**\n * String filter types for PrimeNG table filtering\n */\nexport type StringFilterType =\n  | \"startsWith\"\n  | \"notStartsWith\"\n  | \"endsWith\"\n  | \"notEndsWith\"\n  | \"contains\"\n  | \"notContains\";\n\n/**\n * Numeric filter types for PrimeNG table filtering\n */\nexport type NumericFilterType =\n  | \"equals\"\n  | \"notEquals\"\n  | \"greaterThan\"\n  | \"lessThan\"\n  | \"greaterThanOrEqual\"\n  | \"lessThanOrEqual\";\n\n/**\n * Boolean filter types for PrimeNG table filtering\n */\nexport type BooleanFilterType = Extract<NumericFilterType, \"equals\" | \"notEquals\">;\n\n/**\n * Combined filter types\n */\nexport type FilterType = StringFilterType | NumericFilterType;\n\n/**\n * Filter type mappings for backend API\n */\nexport type FilterTypeMapped =\n  | \"starts\"\n  | \"!starts\"\n  | \"ends\"\n  | \"!ends\"\n  | \"like\"\n  | \"!like\"\n  | \"=\"\n  | \"!=\"\n  | \">\"\n  | \"<\"\n  | \">=\"\n  | \"<=\";\n\n/**\n * PrimeNG table header configuration interface\n */\nexport interface PrimeNgTableHeader {\n  identifier: {\n    label?: string;\n    field: string;\n    hasSort?: boolean;\n    isBoolean?: boolean;\n    isNested?: boolean;\n    isDate?: boolean;\n    isDateTime?: boolean;\n    isTimeOnly?: boolean;\n    styleClass?: string;\n  };\n  filter?: {\n    type: \"text\" | \"numeric\" | \"boolean\" | \"date\" | \"dropdown\" | \"multiselect\";\n    placeholder?: string;\n    matchModeOptions?: any[];\n    defaultMatchMode: FilterType;\n    ariaLabel?: string;\n    colspan?: number;\n    styleClass?: Record<string, string>;\n  };\n}\n\n/**\n * Dynamic query DTO interface\n */\nexport interface DynamicQueryDto {\n  size: number;\n  page: number;\n  filter: DynamicQueryFilterDto[];\n  sort: DynamicQuerySortDto[];\n}\n\n/**\n * Filter DTO for dynamic queries\n */\nexport interface DynamicQueryFilterDto {\n  field: string;\n  value: string;\n  type: FilterTypeMapped;\n}\n\n/**\n * Sort DTO for dynamic queries\n */\nexport interface DynamicQuerySortDto {\n  field: string;\n  dir: \"asc\" | \"desc\";\n}\n\n/**\n * Paged data response interface\n */\nexport interface DynamicQueryPagedDataResponse<T> {\n  data: T[];\n  last_page: number;\n  last_row: number;\n}\n\n/**\n * Paged data response interface for simple pagination\n */\nexport interface PagedDataResponse<T> {\n  payload: T[];\n  totalCount: number;\n}\n\n/**\n * Internal table state interface for dynamic table\n */\nexport interface PrimeNgTableState<T> {\n  data: Array<T>;\n  isLoading: boolean;\n  size: number;\n  page: number;\n  totalRecords: number;\n  filter: DynamicQueryFilterDto[];\n  sort: DynamicQuerySortDto[];\n}\n\n/**\n * Internal state interface for paged table\n */\nexport interface PrimeNgPagedTableState<T> {\n  data: Array<T>;\n  isLoading: boolean;\n  totalRecords: number;\n  limit: number;\n  page: number;\n}\n\n/**\n * Query DTO interface for paged data requests\n */\nexport interface PagedDataQueryDto {\n  limit: number;\n  page: number;\n}\n\n/**\n * Query parameters type for additional HTTP request parameters\n */\nexport type PrimeNgTableStateHelperQueryParam = Record<string, string | number | boolean>;\n\n// ===============================================================================\n// Zod Schemas\n// ===============================================================================\n\n/**\n * Zod schema for dynamic query response validation\n */\nexport const dynamicQueryResponseZodSchema = z.object({\n  data: z.any().array(),\n  last_page: z.number(),\n  last_row: z.number()\n});\n\n/**\n * Zod schema for paged data response validation\n */\nexport const PagedDataResponseZodSchema = z.object({\n  payload: z.any().array(),\n  totalCount: z.number()\n});\n\n/**\n * Zod schema for number/string key with string data validation\n */\nexport const NumberStringKeyDataSchema = z.object({\n  key: z.union([z.number(), z.string()]),\n  data: z.string()\n});\n\nexport type NumberStringKeyData = z.infer<typeof NumberStringKeyDataSchema>;\n\n/**\n * Zod schema for nullable API response validation\n * @template T The Zod schema type for the payload\n * @param payloadSchema The Zod schema for the payload data\n * @returns Zod schema for nullable API response\n */\nexport const NullableApiResponseSchema = <T extends z.ZodTypeAny>(payloadSchema: T) =>\n  z.object({\n    payload: payloadSchema.nullable()\n  });\n\n/**\n * Type for nullable API response\n * @template T The type of the payload data\n */\nexport type NullableApiResponse<T> = {\n  payload: T | null;\n};\n\n// ===============================================================================\n// Utility Functions and Type Guards\n// ===============================================================================\n\n/**\n * Error response interface\n */\nexport interface ErrorResponse {\n  error: string;\n  message: string;\n  statusCode: number;\n  timestamp: string;\n}\n\n/**\n * Creates a key-value pair object\n * @param key The key value\n * @param data The data value\n * @returns KeyData object\n */\nexport function createKeyData<K, D>(key: K, data: D): KeyData<K, D> {\n  return { key, data };\n}\n\n/**\n * Type guard to check if a response is an API response\n * @param response The response to check\n * @returns true if response is ApiResponse, false otherwise\n */\nexport function isApiResponse<T>(response: any): response is ApiResponse<T> {\n  return (\n    typeof response === \"object\" &&\n    response !== null &&\n    \"data\" in response &&\n    \"status\" in response &&\n    \"success\" in response\n  );\n}\n\n/**\n * Type guard to check if a response is paginated\n * @param response The response to check\n * @returns true if response is PaginatedResponse, false otherwise\n */\nexport function isPaginatedResponse<T>(response: any): response is PaginatedResponse<T> {\n  return (\n    typeof response === \"object\" &&\n    response !== null &&\n    \"data\" in response &&\n    Array.isArray(response.data) &&\n    \"meta\" in response &&\n    typeof response.meta === \"object\"\n  );\n}\n\n/**\n * Type guard to check if a response is a simple paged response\n * @param response The response to check\n * @returns true if response is PagedDataResponse, false otherwise\n */\nexport function isSimplePagedResponse<T>(response: any): response is PagedDataResponse<T> {\n  return (\n    typeof response === \"object\" &&\n    response !== null &&\n    \"payload\" in response &&\n    Array.isArray(response.payload) &&\n    \"totalCount\" in response &&\n    typeof response.totalCount === \"number\"\n  );\n}\n\n/**\n * Type guard to check if a response is a dynamic query response\n * @param response The response to check\n * @returns true if response is PagedDataResponse, false otherwise\n */\nexport function isDynamicQueryResponse<T>(\n  response: any\n): response is DynamicQueryPagedDataResponse<T> {\n  return (\n    typeof response === \"object\" &&\n    response !== null &&\n    \"data\" in response &&\n    Array.isArray(response.data) &&\n    \"last_page\" in response &&\n    \"last_row\" in response\n  );\n}\n\nexport type NestableColumn = {\n  isNested?: boolean;\n};\n","import { KeyData } from \"./types\";\n/**\n * Utility function to remove null and undefined values from an object\n *\n * This is particularly useful when setting query parameters, as null/undefined\n * values should typically be filtered out before sending to APIs.\n *\n * @param o The object to clean\n * @returns A new object with null and undefined values removed\n *\n * @example\n * ```typescript\n * const queryParams = {\n *   name: 'John',\n *   age: null,\n *   email: 'john@example.com',\n *   phone: undefined\n * };\n *\n * const cleaned = cleanNullishFromObject(queryParams);\n * // Result: { name: 'John', email: 'john@example.com' }\n *\n * // Use case with table state\n * this.tableState.setQueryParams(cleanNullishFromObject(queryParams));\n * ```\n */\nexport function cleanNullishFromObject(obj?: object): Record<string, any> {\n  if (obj === undefined) {\n    return {};\n  }\n\n  return Object.fromEntries(Object.entries(obj).filter(([, v]) => v != null));\n}\n\nexport function hasNullishInObject(obj: object): boolean {\n  return Object.values(obj).some((val) => val === null || val === undefined);\n}\n\nexport function routeParamConcat(baseUrl: string, routeParam: number | string) {\n  if (routeParam === undefined || routeParam === null) {\n    throw new Error(\"routeParam cannot be null or undefined\");\n  }\n\n  if (baseUrl.endsWith(\"/\")) {\n    return baseUrl.concat(routeParam.toString());\n  }\n  return baseUrl.concat(`/${routeParam.toString()}`);\n}\n\nexport function binarySearch<TItem>(arr: TItem[], val: TItem): number {\n  if (arr.length === 0) {\n    return -1;\n  }\n  let left = 0;\n  let right = arr.length - 1;\n  while (left <= right) {\n    const mid = Math.floor((left + right) / 2);\n    if (arr[mid] === val) {\n      return mid;\n    } else if (arr[mid] < val) {\n      left = mid + 1;\n    } else {\n      right = mid - 1;\n    }\n  }\n  return -1;\n}\n\nexport function emptyCallback() {}\n\nexport function nullableKeyData<TKey, TData>(\n  key: TKey | null,\n  data: TData | null\n): KeyData<TKey, TData> | null {\n  if (key && data) {\n    return { key, data };\n  }\n  return null;\n}\n\nexport class ReloadNotification {\n  static create() {\n    return new ReloadNotification();\n  }\n}\n\n/**\n * Represents a tree node structure compatible with PrimeNG TreeNode\n * @template T The type of data stored in the node\n */\nexport type TreeItem<T> = {\n  data: T;\n  children?: TreeItem<T>[];\n};\n\n/**\n * Creates a hierarchical tree structure from flat array data\n *\n * Converts a flat array of items with parent-child relationships into a tree structure\n * compatible with PrimeNG Tree component.\n *\n * @template T The type of items in the array\n * @param data Array of flat data items\n * @param idKey The property name that contains the unique identifier\n * @param parentIdKey The property name that contains the parent identifier\n * @returns Array of root tree nodes with nested children\n *\n * @example\n * ```typescript\n * interface Category {\n *   id: number;\n *   name: string;\n *   parentCategoryId: number | null;\n * }\n *\n * const categories: Category[] = [\n *   { id: 1, name: 'Electronics', parentCategoryId: null },\n *   { id: 2, name: 'Computers', parentCategoryId: 1 },\n *   { id: 3, name: 'Laptops', parentCategoryId: 2 }\n * ];\n *\n * const tree = createHierarchicalTree(categories, 'id', 'parentCategoryId');\n * // Result: Tree structure with Electronics -> Computers -> Laptops\n * ```\n */\nexport function createHierarchicalTree<T extends Record<string, any>>(\n  data: Array<T>,\n  idKey: string,\n  parentIdKey: string,\n  expanded: boolean = false\n): TreeItem<T>[] {\n  if (!Array.isArray(data)) {\n    throw new Error(\"data must be an array\");\n  }\n\n  // Create a map for quick lookup and convert to TreeNode format\n  const categoryMap = new Map<string | number, TreeItem<T>>(\n    data.map((item) => {\n      if (!Object.hasOwn(item, idKey) || !Object.hasOwn(item, parentIdKey)) {\n        throw new Error(\"idKey or parentIdKey is missing\", { cause: item });\n      }\n      return [\n        item[idKey],\n        {\n          data: item,\n          children: [],\n          expanded\n        }\n      ];\n    })\n  );\n\n  const rootNodes: TreeItem<T>[] = [];\n\n  // Build the tree by linking children to their parents\n  data.forEach((item) => {\n    const parentId = item[parentIdKey];\n\n    if (parentId != null && categoryMap.has(parentId)) {\n      // Add to parent's children list\n      const parent = categoryMap.get(parentId)!;\n      parent.children!.push(categoryMap.get(item[idKey])!);\n    } else {\n      // No parent means this is a root node\n      rootNodes.push(categoryMap.get(item[idKey])!);\n    }\n  });\n\n  return rootNodes;\n}\n","import { HttpClient, HttpContext } from \"@angular/common/http\";\nimport { signal, Signal } from \"@angular/core\";\nimport { patchState, signalState } from \"@ngrx/signals\";\nimport { Table, TableLazyLoadEvent } from \"primeng/table\";\nimport { firstValueFrom } from \"rxjs\";\nimport { SkipLoadingSpinner } from \"./http-context-tokens\";\nimport {\n  PagedDataQueryDto,\n  PagedDataResponseZodSchema,\n  PrimeNgPagedTableState,\n  PrimeNgTableStateHelperQueryParam\n} from \"./types\";\nimport { routeParamConcat } from \"./utils\";\n\n/**\n * Initial state factory function for paged table\n */\nfunction initialPagedState<T>(): PrimeNgPagedTableState<T> {\n  return {\n    data: [],\n    isLoading: false,\n    totalRecords: 0,\n    limit: 15,\n    page: 1\n  };\n}\n\n/**\n * Options for creating PrimengPagedDataTableStateHelper\n */\ntype PrimeNgPagedTableStateOpts = {\n  url: string;\n  httpClient: HttpClient;\n  skipLoadingSpinner?: boolean;\n};\n\n/**\n * Simple paged data table state helper for basic pagination without filtering\n *\n * This helper provides basic table functionality including:\n * - Simple pagination (page and limit only)\n * - Basic state management with NgRx Signals\n * - API integration for paged data\n * - Route parameter support\n * - Query parameter management\n *\n * Use this when you need simple pagination without complex filtering and sorting.\n * For advanced features, use PrimeNgDynamicTableStateHelper instead.\n *\n * @example\n * ```typescript\n * const tableState = PrimengPagedDataTableStateHelper.create<Product>({\n *   url: '/api/products',\n *   httpClient: this.httpClient\n * });\n *\n * // In template\n * <p-table [value]=\"tableState.data()\"\n *          [lazy]=\"true\"\n *          [loading]=\"tableState.isLoading()\"\n *          [totalRecords]=\"tableState.totalRecords()\"\n *          (onLazyLoad)=\"tableState.onLazyLoad($event)\">\n * </p-table>\n * ```\n */\nexport class PrimeNgPagedDataTableStateHelper<T> {\n  readonly #state = signalState<PrimeNgPagedTableState<T>>(initialPagedState<T>());\n  private urlWithOutRouteParam: string;\n  private skipLoadingSpinner: boolean;\n  readonly #uniqueKey = signal(\"id\");\n  readonly uniqueKey = this.#uniqueKey.asReadonly();\n  #queryParams: PrimeNgTableStateHelperQueryParam = {};\n\n  // Public readonly signals\n  readonly totalRecords: Signal<number> = this.#state.totalRecords;\n  readonly isLoading: Signal<boolean> = this.#state.isLoading;\n  readonly data: Signal<Array<T>> = this.#state.data;\n  readonly currentPage = this.#state.page;\n  readonly currentPageSize = this.#state.limit;\n\n  private constructor(\n    private url: string,\n    private readonly httpClient: HttpClient,\n    skipLoadingSpinner: boolean = true\n  ) {\n    this.urlWithOutRouteParam = url;\n    this.skipLoadingSpinner = skipLoadingSpinner;\n  }\n\n  /**\n   * Creates a new instance of PrimengPagedDataTableStateHelper\n   * @param option - Configuration options\n   * @returns New instance of PrimengPagedDataTableStateHelper\n   */\n  public static create<T>(option: PrimeNgPagedTableStateOpts): PrimeNgPagedDataTableStateHelper<T> {\n    return new PrimeNgPagedDataTableStateHelper<T>(\n      option.url,\n      option.httpClient,\n      option.skipLoadingSpinner ?? true\n    );\n  }\n\n  /**\n   * Creates a new instance without initial URL (can be set later)\n   * @param option - Configuration options without URL\n   * @returns New instance of PrimengPagedDataTableStateHelper\n   */\n  public static createWithBlankUrl<T>(\n    option: Omit<PrimeNgPagedTableStateOpts, \"url\">\n  ): PrimeNgPagedDataTableStateHelper<T> {\n    return new PrimeNgPagedDataTableStateHelper<T>(\n      \"\",\n      option.httpClient,\n      option.skipLoadingSpinner ?? true\n    );\n  }\n\n  /**\n   * Sets whether to skip the loading spinner\n   * @param skip - Whether to skip the loading spinner\n   * @returns This instance for method chaining\n   */\n  public setSkipLoadingSpinner(skip: boolean): this {\n    this.skipLoadingSpinner = skip;\n    return this;\n  }\n\n  /**\n   * Sets the unique key field for table rows\n   * @param newUniqueKey - The field name to use as unique identifier\n   * @returns This instance for method chaining\n   */\n  public setUniqueKey(newUniqueKey: string): this {\n    this.#uniqueKey.set(newUniqueKey);\n    return this;\n  }\n\n  /**\n   * Updates the API URL\n   * @param newUrl - The new API URL\n   * @returns This instance for method chaining\n   */\n  public setUrl(newUrl: string): this {\n    this.url = newUrl;\n    this.urlWithOutRouteParam = newUrl;\n    return this;\n  }\n\n  /**\n   * Appends a route parameter to the URL\n   * @param newRouteParam - The route parameter to append\n   * @returns This instance for method chaining\n   */\n  public setRouteParam(newRouteParam: string): this {\n    this.url = routeParamConcat(this.urlWithOutRouteParam, newRouteParam);\n    return this;\n  }\n\n  /**\n   * Patches existing query parameters\n   * @param value - Query parameters to merge\n   * @returns This instance for method chaining\n   */\n  public patchQueryParams(value: PrimeNgTableStateHelperQueryParam): this {\n    this.#queryParams = { ...this.#queryParams, ...value };\n    return this;\n  }\n\n  /**\n   * Removes a specific query parameter\n   * @param key - The key to remove\n   * @returns This instance for method chaining\n   */\n  public removeQueryParam(key: string): this {\n    delete this.#queryParams[key];\n    return this;\n  }\n\n  /**\n   * Removes all query parameters\n   * @returns This instance for method chaining\n   */\n  public removeAllQueryParams(): this {\n    this.#queryParams = {};\n    return this;\n  }\n\n  /**\n   * Sets all query parameters (replaces existing)\n   * @param newQueryParams - New query parameters\n   * @returns This instance for method chaining\n   */\n  public setQueryParams(newQueryParams: PrimeNgTableStateHelperQueryParam): this {\n    this.#queryParams = newQueryParams;\n    return this;\n  }\n\n  /**\n   * Handles PrimeNG table lazy load events\n   * @param event - The lazy load event from PrimeNG table\n   */\n  public async onLazyLoad(event: TableLazyLoadEvent): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    const newPage = Math.floor((event.first || 0) / (event.rows || 15)) + 1;\n    const newLimit = event.rows || 15;\n\n    patchState(this.#state, {\n      limit: newLimit,\n      page: newPage\n    });\n\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Clears table data and resets to first page\n   * @param table - Optional PrimeNG Table reference to reset\n   */\n  public async clearTableData(table?: Table): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    patchState(this.#state, {\n      data: [],\n      totalRecords: 0,\n      page: 1\n    });\n\n    if (table) {\n      table.reset();\n    }\n\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Manually triggers data refresh with current state\n   */\n  public async refresh(): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    await this.fetchData(this.dtoBuilder());\n  }\n\n  /**\n   * Fetches data from the API\n   */\n  private async fetchData(dto: PagedDataQueryDto): Promise<void> {\n    if (this.isLoading()) {\n      return;\n    }\n    try {\n      patchState(this.#state, { isLoading: true });\n\n      const params = new URLSearchParams();\n      Object.entries(this.#queryParams).forEach(([key, value]) => {\n        params.append(key, String(value));\n      });\n      Object.entries(dto).forEach(([key, value]) => {\n        params.append(key, String(value));\n      });\n\n      const urlWithParams = params.toString() ? `${this.url}?${params.toString()}` : this.url;\n\n      const response = await firstValueFrom(\n        this.httpClient.get(urlWithParams, {\n          context: new HttpContext().set(SkipLoadingSpinner, this.skipLoadingSpinner)\n        })\n      );\n\n      const validatedResponse = PagedDataResponseZodSchema.parse(response);\n\n      patchState(this.#state, {\n        data: validatedResponse.payload,\n        totalRecords: validatedResponse.totalCount,\n        isLoading: false\n      });\n    } catch (error) {\n      patchState(this.#state, {\n        data: [],\n        totalRecords: 0,\n        isLoading: false\n      });\n      throw error;\n    }\n  }\n\n  /**\n   * Builds the DTO for API requests\n   */\n  private dtoBuilder(): PagedDataQueryDto {\n    return {\n      limit: this.#state.limit(),\n      page: this.#state.page()\n    };\n  }\n}\n","import { SelectItem } from \"primeng/api\";\nimport {\n  StringFilterType,\n  NumericFilterType,\n  PrimeNgTableHeader,\n  NestableColumn,\n} from \"./types\";\n\n/**\n * Creates PrimeNG SelectItem array for numeric filter match modes\n * @param styleClass - CSS class for styling the options\n * @param disabled - Whether the options should be disabled\n * @returns Array of SelectItem for numeric filters\n */\nexport function createPrimengNumberMatchModes(\n  styleClass: string = \"p-text-capitalize\",\n  disabled: boolean = false\n): SelectItem<NumericFilterType>[] {\n  return [\n    {\n      label: \"Equals\",\n      value: \"equals\",\n      title: \"Equals\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Not Equals\",\n      value: \"notEquals\",\n      title: \"Not Equals\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Greater Than\",\n      value: \"greaterThan\",\n      title: \"Greater Than\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Greater Than Or Equals\",\n      value: \"greaterThanOrEqual\",\n      title: \"Greater Than Or Equals\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Less Than\",\n      value: \"lessThan\",\n      title: \"Less Than\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Less Than Or Equals\",\n      value: \"lessThanOrEqual\",\n      title: \"Less Than Or Equals\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n  ];\n}\n\n/**\n * Creates PrimeNG SelectItem array for string filter match modes\n * @param styleClass - CSS class for styling the options\n * @param disabled - Whether the options should be disabled\n * @returns Array of SelectItem for string filters\n */\nexport function createPrimengStringMatchModes(\n  styleClass: string = \"p-text-capitalize\",\n  disabled: boolean = false\n): SelectItem<StringFilterType>[] {\n  return [\n    {\n      label: \"Contains\",\n      value: \"contains\",\n      title: \"Contains\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Not Contains\",\n      value: \"notContains\",\n      title: \"Not Contains\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Starts With\",\n      value: \"startsWith\",\n      title: \"Starts With\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Not Starts With\",\n      value: \"notStartsWith\",\n      title: \"Not Starts With\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Ends With\",\n      value: \"endsWith\",\n      title: \"Ends With\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n    {\n      label: \"Not Ends With\",\n      value: \"notEndsWith\",\n      title: \"Not Ends With\",\n      styleClass: styleClass,\n      disabled: disabled,\n    },\n  ];\n}\n\n/**\n * Creates a complete table header configuration for text columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createTextColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    matchModeOptions?: SelectItem<StringFilterType>[];\n    defaultMatchMode?: StringFilterType;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"text\",\n      placeholder: options.placeholder ?? `Search by ${label.toLowerCase()}`,\n      matchModeOptions:\n        options.matchModeOptions ?? createPrimengStringMatchModes(),\n      defaultMatchMode: options.defaultMatchMode ?? \"contains\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for numeric columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createNumericColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    matchModeOptions?: SelectItem<NumericFilterType>[];\n    defaultMatchMode?: NumericFilterType;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"numeric\",\n      placeholder: options.placeholder ?? `Filter by ${label.toLowerCase()}`,\n      matchModeOptions:\n        options.matchModeOptions ?? createPrimengNumberMatchModes(),\n      defaultMatchMode: options.defaultMatchMode ?? \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for boolean columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createBooleanColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      isBoolean: true,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"boolean\",\n      defaultMatchMode: \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for date columns (date only)\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createDateColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      isDate: true,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"date\",\n      placeholder: options.placeholder ?? `Select ${label.toLowerCase()}`,\n      defaultMatchMode: \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for datetime columns (date and time)\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createDateTimeColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      isDateTime: true,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"date\",\n      placeholder: options.placeholder ?? `Select ${label.toLowerCase()}`,\n      defaultMatchMode: \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for time-only columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createTimeColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      isTimeOnly: true,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"text\",\n      placeholder: options.placeholder ?? `Filter by ${label.toLowerCase()}`,\n      defaultMatchMode: \"contains\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for dropdown columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param dropdownOptions - Options for the dropdown filter\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createDropdownColumn(\n  field: string,\n  label: string,\n  dropdownOptions: SelectItem[],\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      hasSort: options.hasSort ?? false,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"dropdown\",\n      placeholder: options.placeholder ?? `Select ${label.toLowerCase()}`,\n      matchModeOptions: dropdownOptions,\n      defaultMatchMode: \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a complete table header configuration for multiselect columns\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param multiselectOptions - Options for the multiselect filter\n * @param options - Additional configuration options\n * @returns Complete PrimeNgTableHeader configuration\n */\nexport function createMultiselectColumn(\n  field: string,\n  label: string,\n  multiselectOptions: SelectItem[],\n  options: {\n    hasSort?: boolean;\n    hasFilter?: boolean;\n    placeholder?: string;\n    styleClass?: string;\n    filterStyleClass?: Record<string, string>;\n  } = {}\n): PrimeNgTableHeader {\n  const header: PrimeNgTableHeader = {\n    identifier: {\n      label,\n      field,\n      hasSort: options.hasSort ?? false,\n      styleClass: options.styleClass,\n    },\n  };\n\n  if (options.hasFilter ?? false) {\n    header.filter = {\n      type: \"multiselect\",\n      placeholder: options.placeholder ?? `Select ${label.toLowerCase()}`,\n      matchModeOptions: multiselectOptions,\n      defaultMatchMode: \"equals\",\n      ariaLabel: `Filter by ${label}`,\n      styleClass: options.filterStyleClass,\n    };\n  }\n\n  return header;\n}\n\n/**\n * Creates a simple table header configuration without filtering\n * @param field - The field name for the column\n * @param label - Display label for the column header\n * @param options - Additional configuration options\n * @returns Simple PrimeNgTableHeader configuration\n */\nexport function createSimpleColumn(\n  field: string,\n  label: string,\n  options: {\n    hasSort?: boolean;\n    styleClass?: string;\n  } & NestableColumn = {}\n): PrimeNgTableHeader {\n  return {\n    identifier: {\n      label,\n      field,\n      isNested: options.isNested,\n      hasSort: options.hasSort ?? false,\n      styleClass: options.styleClass,\n    },\n  };\n}\n\n/**\n * Utility function to merge multiple table header configurations\n * @param headers - Array of table header configurations\n * @returns Array of merged headers\n */\nexport function mergeTableHeaders(\n  ...headers: PrimeNgTableHeader[]\n): PrimeNgTableHeader[] {\n  return headers;\n}\n\n/**\n * Utility function to create boolean SelectItem options\n * @param trueLabel - Label for true value\n * @param falseLabel - Label for false value\n * @returns Array of SelectItem for boolean values\n */\nexport function createBooleanSelectItems(\n  trueLabel: string = \"Yes\",\n  falseLabel: string = \"No\"\n): SelectItem[] {\n  return [\n    { label: trueLabel, value: true },\n    { label: falseLabel, value: false },\n  ];\n}\n\n/**\n * Utility function to create status SelectItem options\n * @param statusOptions - Object mapping status values to labels\n * @returns Array of SelectItem for status values\n */\nexport function createStatusSelectItems(\n  statusOptions: Record<string | number, string>\n): SelectItem[] {\n  return Object.entries(statusOptions).map(([value, label]) => ({\n    label,\n    value: isNaN(Number(value)) ? value : Number(value),\n  }));\n}\n","import { signal } from \"@angular/core\";\nimport { HttpClient, HttpContext } from \"@angular/common/http\";\nimport { firstValueFrom } from \"rxjs\";\nimport { SkipLoadingSpinner } from \"./http-context-tokens\";\n\n/**\n * A generic class for memoizing data storage with HTTP caching capabilities\n * Provides methods to load and cache single data objects or arrays with automatic loading states\n * \n * @template T The type of data to be stored and managed\n * \n * @example\n * ```typescript\n * interface User { id: number; name: string; }\n * \n * const userStorage = new MemoizedDataStorage<User>(httpClient);\n * await userStorage.loadSingleData('/api/user/1');\n * console.log(userStorage.singleData()); // User data or null\n * \n * const usersStorage = new MemoizedDataStorage<User>(httpClient);\n * await usersStorage.loadMultipleData('/api/users');\n * console.log(usersStorage.multipleData()); // Array of User data\n * ```\n */\nexport class MemoizedDataStorage<T> {\n  private skipLoadingSpinner: boolean = true;\n\n  /**\n   * Creates a new instance of MemoizedDataStorage\n   * @param httpClient Angular HttpClient instance for making HTTP requests\n   * @param skipLoadingSpinner Whether to skip the loading spinner for HTTP requests\n   */\n  constructor(readonly httpClient: HttpClient, skipLoadingSpinner: boolean = true) {\n    this.skipLoadingSpinner = skipLoadingSpinner;\n  }\n\n  /**\n   * Sets whether to skip the loading spinner for HTTP requests\n   * @param skip Whether to skip the loading spinner\n   * @returns This instance for method chaining\n   */\n  setSkipLoadingSpinner(skip: boolean): this {\n    this.skipLoadingSpinner = skip;\n    return this;\n  }\n  readonly #singleData = signal<T | null>(null);\n  readonly #multipleData = signal<Array<T>>([]);\n  readonly #isLoading = signal<boolean>(false);\n\n  // Public readonly signals for external consumption\n  /**\n   * Read-only signal containing single data object or null\n   */\n  readonly singleData = this.#singleData.asReadonly();\n\n  /**\n   * Read-only signal containing array of data objects\n   */\n  readonly multipleData = this.#multipleData.asReadonly();\n\n  /**\n   * Read-only signal indicating whether a request is currently loading\n   */\n  readonly isLoading = this.#isLoading.asReadonly();\n\n  // Private flag to control memoization behavior\n  #isMemoizationDisabledOnNextRead = false;\n\n  /**\n   * Disables memoization for the next read operation and clears cached data\n   * This forces the next loadSingleData or loadMultipleData call to fetch fresh data\n   * \n   * @example\n   * ```typescript\n   * const storage = new MemoizedDataStorage<User>(httpClient);\n   * await storage.loadSingleData('/api/user/1'); // Fetches data\n   * await storage.loadSingleData('/api/user/1'); // Returns cached data\n   * \n   * storage.disableMemoizationOnNextRead();\n   * await storage.loadSingleData('/api/user/1'); // Fetches fresh data\n   * ```\n   */\n  disableMemoizationOnNextRead(): void {\n    this.#isMemoizationDisabledOnNextRead = true;\n    this.#singleData.set(null);\n    this.#multipleData.set([]);\n  }\n\n  /**\n   * Loads a single data object from the specified URL with optional query parameters\n   * Uses memoization to avoid redundant requests unless explicitly disabled\n   * \n   * @param url The URL to fetch data from\n   * @param queryParams Optional query parameters to include in the request\n   * @returns Promise that resolves when the data is loaded\n   * @throws Error if the HTTP request fails\n   * \n   * @example\n   * ```typescript\n   * const storage = new MemoizedDataStorage<User>(httpClient);\n   * await storage.loadSingleData('/api/user/1', { include: 'profile' });\n   * const user = storage.singleData(); // User data or null\n   * ```\n   */\n  async loadSingleData(\n    url: string,\n    queryParams: Record<string, string | number> = {}\n  ): Promise<void> {\n    // Skip loading if data is already cached and memoization is enabled\n    if (!this.#isMemoizationDisabledOnNextRead && this.#singleData() !== null) {\n      return;\n    }\n\n    try {\n      this.#isLoading.set(true);\n\n      const data = await firstValueFrom(\n        this.httpClient.get<T>(url, {\n          params: queryParams,\n          context: new HttpContext().set(SkipLoadingSpinner, this.skipLoadingSpinner)\n        })\n      );\n      this.#singleData.set(data);\n    } catch (error) {\n      this.#singleData.set(null);\n      throw error;\n    } finally {\n      this.#isLoading.set(false);\n      this.#isMemoizationDisabledOnNextRead = false;\n    }\n  }\n\n  /**\n   * Loads multiple data objects from the specified URL with optional query parameters\n   * Uses memoization to avoid redundant requests unless explicitly disabled\n   * \n   * @param url The URL to fetch data from\n   * @param queryParams Optional query parameters to include in the request\n   * @returns Promise that resolves when the data is loaded\n   * @throws Error if the HTTP request fails\n   * \n   * @example\n   * ```typescript\n   * const storage = new MemoizedDataStorage<User>(httpClient);\n   * await storage.loadMultipleData('/api/users', { page: 1, limit: 10 });\n   * const users = storage.multipleData(); // Array of User data\n   * ```\n   */\n  async loadMultipleData(\n    url: string,\n    queryParams: Record<string, string | number> = {}\n  ): Promise<void> {\n    // Skip loading if data is already cached and memoization is enabled\n    if (\n      !this.#isMemoizationDisabledOnNextRead &&\n      this.#multipleData().length !== 0\n    ) {\n      return;\n    }\n\n    try {\n      this.#isLoading.set(true);\n      \n      const context = new HttpContext();\n      if (this.skipLoadingSpinner) {\n        context.set(SkipLoadingSpinner, true);\n      }\n\n      const data = await firstValueFrom(\n        this.httpClient.get<Array<T>>(url, {\n          params: queryParams,\n          context\n        })\n      );\n      this.#multipleData.set(Array.isArray(data) ? data : []);\n    } catch (error) {\n      this.#multipleData.set([]);\n      throw error;\n    } finally {\n      this.#isLoading.set(false);\n      this.#isMemoizationDisabledOnNextRead = false;\n    }\n  }\n\n  /**\n   * Clears all cached data and resets the storage to initial state\n   * \n   * @example\n   * ```typescript\n   * const storage = new MemoizedDataStorage<User>(httpClient);\n   * await storage.loadSingleData('/api/user/1');\n   * storage.clear(); // Clears cached data\n   * console.log(storage.singleData()); // null\n   * console.log(storage.multipleData()); // []\n   * ```\n   */\n  clear(): void {\n    this.#singleData.set(null);\n    this.#multipleData.set([]);\n    this.#isMemoizationDisabledOnNextRead = false;\n  }\n\n  /**\n   * Checks if single data is currently cached\n   * @returns true if single data is cached, false otherwise\n   */\n  hasSingleData(): boolean {\n    return this.#singleData() !== null;\n  }\n\n  /**\n   * Checks if multiple data is currently cached\n   * @returns true if multiple data is cached (non-empty array), false otherwise\n   */\n  hasMultipleData(): boolean {\n    return this.#multipleData().length > 0;\n  }\n}\n","import { computed, signal } from \"@angular/core\";\nimport { ManipulationType } from \"./types\";\n\n/**\n * A reactive state management class for Angular components using signals\n * Provides common component state properties and computed values\n *\n * @example\n * ```typescript\n * @Component({\n *   selector: 'app-user-management',\n *   template: `\n *     <h2>{{ componentState.componentTitleWithManipulationType() }}</h2>\n *     <p-button\n *       [loading]=\"componentState.isAnyAjaxOperationRunning()\"\n *       [disabled]=\"componentState.isAnyAjaxOperationRunning()\">\n *       Save\n *     </p-button>\n *   `\n * })\n * export class UserManagementComponent {\n *   componentState = new ComponentState()\n *     .updateComponentTitle('User')\n *     .updateCheckBoxSelectionStatus(true);\n * }\n * ```\n */\nexport class ComponentState {\n  readonly isAjaxDataIncoming = signal<boolean>(false);\n  readonly enableCheckBoxSelection = signal<boolean>(false);\n  readonly isSelectableRowEnabled = signal<boolean>(false);\n  readonly isAjaxRequestOutgoing = signal<boolean>(false);\n  readonly hasMultipleSelection = signal<boolean>(false);\n  readonly isCreateOrUpdateDialogOpen = signal<boolean>(false);\n  readonly isUpdateDialogOpen = signal<boolean>(false);\n  readonly isCreateDialogOpen = signal<boolean>(false);\n  readonly manipulationType = signal<ManipulationType>(ManipulationType.Create);\n  readonly componentTitle = signal<string>(\"\");\n\n  readonly isDataManipulationPageOpen = signal<boolean>(false);\n  readonly isCreateOrUpdatePageOpen = signal<boolean>(false);\n  readonly isUpdatePageOpen = signal<boolean>(false);\n  readonly isCreatePageOpen = signal<boolean>(false);\n\n  readonly manipulationTypeLabel = computed(() => {\n    switch (this.manipulationType()) {\n      case ManipulationType.Create:\n        return \"Create\";\n\n      case ManipulationType.Update:\n        return \"Update\";\n\n      case ManipulationType.CreateChild:\n        return \"Create Child\";\n\n      case ManipulationType.Delete:\n        return \"Delete\";\n\n      case ManipulationType.View:\n        return \"View\";\n\n      case ManipulationType.Save:\n        return \"Save\";\n\n      default:\n        return \"\";\n    }\n  });\n\n  /**\n   * Updates the component title\n   * @param componentTitle - The new title for the component\n   * @returns This instance for method chaining\n   */\n  updateComponentTitle = (componentTitle: string) => {\n    this.componentTitle.set(componentTitle);\n    return this;\n  };\n\n  /**\n   * Updates the multiple selection status\n   * @param newStatus - Whether multiple selection is enabled\n   * @returns This instance for method chaining\n   */\n  updateMultipleSelectionStatus = (newStatus: boolean) => {\n    this.hasMultipleSelection.set(newStatus);\n    return this;\n  };\n\n  /**\n   * Updates the checkbox selection status\n   * @param newStatus - Whether checkbox selection is enabled\n   * @returns This instance for method chaining\n   */\n  updateCheckBoxSelectionStatus = (newStatus: boolean) => {\n    this.enableCheckBoxSelection.set(newStatus);\n    return this;\n  };\n\n  /**\n   * Updates the selectable row status\n   * @param newStatus - Whether row selection is enabled\n   * @returns This instance for method chaining\n   */\n  updateSelectableRowStatus = (newStatus: boolean) => {\n    this.isSelectableRowEnabled.set(newStatus);\n    return this;\n  };\n\n  /**\n   * Updates the manipulation type (Create, Update, Delete, View)\n   * @param type - The manipulation type\n   * @returns This instance for method chaining\n   */\n  updateManipulationType = (type: ManipulationType) => {\n    this.manipulationType.set(type);\n    return this;\n  };\n\n  /**\n   * Sets the incoming Ajax data status\n   * @param status - Whether Ajax data is incoming\n   * @returns This instance for method chaining\n   */\n  setAjaxDataIncoming = (status: boolean) => {\n    this.isAjaxDataIncoming.set(status);\n    return this;\n  };\n\n  /**\n   * Sets the outgoing Ajax request status\n   * @param status - Whether Ajax request is outgoing\n   * @returns This instance for method chaining\n   */\n  setAjaxRequestOutgoing = (status: boolean) => {\n    this.isAjaxRequestOutgoing.set(status);\n    return this;\n  };\n\n  /**\n   * Sets the create or update dialog open status\n   * @param status - Whether the dialog is open\n   * @returns This instance for method chaining\n   */\n  setCreateOrUpdateDialogOpen = (status: boolean) => {\n    this.isCreateOrUpdateDialogOpen.set(status);\n    return this;\n  };\n\n  /**\n   * Sets the update dialog open status\n   * @param status - Whether the update dialog is open\n   * @returns This instance for method chaining\n   */\n  setUpdateDialogOpen = (status: boolean) => {\n    this.isUpdateDialogOpen.set(status);\n    return this;\n  };\n\n  /**\n   * Sets the create dialog open status\n   * @param status - Whether the create dialog is open\n   * @returns This instance for method chaining\n   */\n  setCreateDialogOpen = (status: boolean) => {\n    this.isCreateDialogOpen.set(status);\n    return this;\n  };\n\n  /**\n   * Computed signal that combines component title with manipulation type\n   */\n  readonly componentTitleWithManipulationType = computed(() => {\n    return this.manipulationTypeLabel() + \" \" + this.componentTitle();\n  });\n\n  /**\n   * Computed signal that indicates if component is in update state\n   */\n  readonly isOnUpdateState = computed(() => {\n    return this.manipulationType() === ManipulationType.Update;\n  });\n\n  /**\n   * Computed signal that indicates if component is in create state\n   */\n  readonly isOnCreateState = computed(() => {\n    return this.manipulationType() === ManipulationType.Create;\n  });\n\n  /**\n   * Computed signal that indicates if component is in delete state\n   */\n  readonly isOnDeleteState = computed(() => {\n    return this.manipulationType() === ManipulationType.Delete;\n  });\n\n  /**\n   * Computed signal that indicates if component is in view state\n   */\n  readonly isOnViewState = computed(() => {\n    return this.manipulationType() === ManipulationType.View;\n  });\n\n  /**\n   * Computed signal that indicates if any Ajax operation is currently running\n   */\n  readonly isAnyAjaxOperationRunning = computed(() => {\n    return this.isAjaxDataIncoming() || this.isAjaxRequestOutgoing();\n  });\n\n  /**\n   * Computed signal that indicates if any dialog is open\n   */\n  readonly isAnyDialogOpen = computed(() => {\n    return (\n      this.isCreateOrUpdateDialogOpen() || this.isUpdateDialogOpen() || this.isCreateDialogOpen()\n    );\n  });\n\n  /**\n   * Resets all state to default values\n   * @returns This instance for method chaining\n   */\n  reset = () => {\n    this.isAjaxDataIncoming.set(false);\n    this.enableCheckBoxSelection.set(false);\n    this.isSelectableRowEnabled.set(false);\n    this.isAjaxRequestOutgoing.set(false);\n    this.hasMultipleSelection.set(false);\n    this.isCreateOrUpdateDialogOpen.set(false);\n    this.isUpdateDialogOpen.set(false);\n    this.isCreateDialogOpen.set(false);\n    this.manipulationType.set(ManipulationType.Create);\n    this.componentTitle.set(\"\");\n    return this;\n  };\n}","import { computed, signal } from \"@angular/core\";\n\n/**\n * A generic component data storage class using Angular signals\n * Provides reactive data management for both single objects and arrays\n *\n * @template T The type of data to be stored and managed\n *\n * @example\n * ```typescript\n * interface User {\n *   id: number;\n *   name: string;\n *   email: string;\n * }\n *\n * @Component({\n *   selector: 'app-user-list',\n *   template: `\n *     <!-- Single user display -->\n *     @if (dataStorage.singleData(); as user) {\n *       <div>\n *         <h3>{{ user.name }}</h3>\n *         <p>{{ user.email }}</p>\n *       </div>\n *     }\n *\n *     <!-- Multiple users display -->\n *     @for (user of dataStorage.multipleData(); track user.id) {\n *       <div>{{ user.name }} - {{ user.email }}</div>\n *     }\n *   `\n * })\n * export class UserListComponent {\n *   dataStorage = new ComponentDataStorage<User>();\n *\n *   ngOnInit() {\n *     // Set initial data\n *     this.dataStorage\n *       .updateSingleData({ id: 1, name: 'John', email: 'john@example.com' })\n *       .updateMultipleData([\n *         { id: 1, name: 'John', email: 'john@example.com' },\n *         { id: 2, name: 'Jane', email: 'jane@example.com' }\n *       ]);\n *   }\n * }\n * ```\n */\nexport class ComponentDataStorage<T> {\n  readonly singleData = signal<T | null>(null);\n  readonly multipleData = signal<Array<T>>([]);\n\n  /**\n   * Patches multiple data by appending new data to the existing array\n   * @param newData - Array of new data to append\n   * @returns This instance for method chaining\n   *\n   * @example\n   * ```typescript\n   * const storage = new ComponentDataStorage<User>();\n   * storage.updateMultipleData([{ id: 1, name: 'John' }]);\n   * storage.patchMultipleData([{ id: 2, name: 'Jane' }]);\n   * // Result: [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]\n   * ```\n   */\n  public patchMultipleData(newData: Array<T>) {\n    this.multipleData.update((prevData) => {\n      return [...prevData, ...newData];\n    });\n\n    return this;\n  }\n\n  /**\n   * Patches single data by merging new properties with existing data\n   * If no existing data, creates new object with provided data\n   * @param newData - Partial data to merge with existing single data\n   * @returns This instance for method chaining\n   *\n   * @example\n   * ```typescript\n   * const storage = new ComponentDataStorage<User>();\n   * storage.updateSingleData({ id: 1, name: 'John', email: 'john@example.com' });\n   * storage.patchSingleData({ email: 'john.doe@example.com' });\n   * // Result: { id: 1, name: 'John', email: 'john.doe@example.com' }\n   * ```\n   */\n  public patchSingleData(newData: Partial<T>) {\n    this.singleData.update((prev) => (prev ? { ...prev, ...newData } : ({ ...newData } as T)));\n    return this;\n  }\n\n  /**\n   * Replaces the entire multiple data array\n   * @param newData - New array of data to replace existing data\n   * @returns This instance for method chaining\n   */\n  public updateMultipleData(newData: Array<T>) {\n    this.multipleData.set(newData);\n    return this;\n  }\n\n  /**\n   * Replaces the single data object\n   * @param newData - New data object or null to replace existing data\n   * @returns This instance for method chaining\n   */\n  public updateSingleData(newData: T | null) {\n    this.singleData.set(newData);\n    return this;\n  }\n\n  /**\n   * Adds a single item to the multiple data array\n   * @param item - Single item to add to the array\n   * @returns This instance for method chaining\n   */\n  public addToMultipleData(item: T) {\n    this.multipleData.update((prevData) => [...prevData, item]);\n    return this;\n  }\n\n  /**\n   * Removes an item from the multiple data array based on a predicate function\n   * @param predicate - Function that returns true for items to remove\n   * @returns This instance for method chaining\n   *\n   * @example\n   * ```typescript\n   * storage.removeFromMultipleData(user => user.id === 1);\n   * ```\n   */\n  public removeFromMultipleData(predicate: (item: T) => boolean) {\n    this.multipleData.update((prevData) => prevData.filter((item) => !predicate(item)));\n    return this;\n  }\n\n  /**\n   * Updates an item in the multiple data array based on a predicate function\n   * @param predicate - Function that returns true for items to update\n   * @param updateFn - Function that returns the updated item\n   * @returns This instance for method chaining\n   *\n   * @example\n   * ```typescript\n   * storage.updateItemInMultipleData(\n   *   user => user.id === 1,\n   *   user => ({ ...user, name: 'Updated Name' })\n   * );\n   * ```\n   */\n  public updateItemInMultipleData(predicate: (item: T) => boolean, updateFn: (item: T) => T) {\n    this.multipleData.update((prevData) =>\n      prevData.map((item) => (predicate(item) ? updateFn(item) : item))\n    );\n    return this;\n  }\n\n  /**\n   * Clears all data (both single and multiple)\n   * @returns This instance for method chaining\n   */\n  public clearAll() {\n    this.singleData.set(null);\n    this.multipleData.set([]);\n    return this;\n  }\n\n  /**\n   * Clears only the single data\n   * @returns This instance for method chaining\n   */\n  public clearSingleData() {\n    this.singleData.set(null);\n    return this;\n  }\n\n  /**\n   * Clears only the multiple data\n   * @returns This instance for method chaining\n   */\n  public clearMultipleData() {\n    this.multipleData.set([]);\n    return this;\n  }\n\n  /**\n   * Checks if single data exists (is not null)\n   * @returns true if single data exists, false otherwise\n   */\n  public hasSingleData = computed(() => {\n    return this.singleData() !== null;\n  });\n\n  /**\n   * Checks if multiple data has items\n   * @returns true if multiple data array has items, false if empty\n   */\n\n  public hasMultipleData = computed(() => {\n    return !Array.isArray(this.multipleData()) ? false : this.multipleData().length > 0;\n  });\n\n  /**\n   * Gets the count of items in multiple data\n   * @returns Number of items in the multiple data array\n   */\n\n  public getMultipleDataCount = computed(() => {\n    return !this.hasMultipleData() ? 0 : this.multipleData().length;\n  });\n\n  /**\n   * Finds an item in the multiple data array\n   * @param predicate - Function that returns true for the item to find\n   * @returns The found item or undefined\n   */\n  public findInMultipleData(predicate: (item: T) => boolean): T | undefined {\n    return this.multipleData().find(predicate);\n  }\n\n  /**\n   * Checks if an item exists in the multiple data array\n   * @param predicate - Function that returns true for the item to check\n   * @returns true if item exists, false otherwise\n   */\n  public existsInMultipleData(predicate: (item: T) => boolean): boolean {\n    return this.multipleData().some(predicate);\n  }\n}\n","import { HttpClient, HttpContext } from \"@angular/common/http\";\nimport {\n  assertInInjectionContext,\n  DestroyRef,\n  inject,\n  Injector,\n  runInInjectionContext,\n  signal\n} from \"@angular/core\";\nimport {\n  catchError,\n  debounceTime,\n  finalize,\n  first,\n  mergeMap,\n  Observable,\n  of,\n  Subject,\n  Subscription,\n  switchMap,\n  tap\n} from \"rxjs\";\nimport { SkipLoadingSpinner } from \"./http-context-tokens\";\n\n/**\n * Configuration options for NgSelectHelper\n */\ntype NgSelectHelperOpts = {\n  ajaxUrl: string;\n  httpClient: HttpClient;\n  destroyRef: DestroyRef;\n  usePostRequest?: boolean;\n  initialSearchText?: string;\n  limit?: number;\n  useCache?: boolean;\n  skipLoadingSpinner?: boolean;\n};\n\n/**\n * Reset options for NgSelectHelper\n */\ntype NgSelectHelperResetOpts = {\n  resetQueryParams: boolean;\n  resetBody: boolean;\n  resetCache: boolean;\n};\n\n/**\n * Query parameter type for NgSelectHelper\n */\ntype NgSelectHelperQueryParam = Record<string, string | number | boolean>;\n\n/**\n * Body type for NgSelectHelper POST requests\n */\ntype NgSelectHelperBody =\n  | Array<string | number | boolean | null | Record<string, string | number | boolean | null>>\n  | Record<\n      string,\n      | string\n      | number\n      | boolean\n      | null\n      | Array<string | number | boolean | null | Record<string, string | number | boolean | null>>\n    >;\n\n/**\n * Cache key type for internal caching\n */\ntype CacheKey = {\n  ajaxUrl: string;\n  page: number;\n  limit: number;\n  searchText: string;\n  queryParams: NgSelectHelperQueryParam;\n  body: NgSelectHelperBody;\n};\n\n/**\n * Paged data response specifically for ng-select\n */\nexport class NgSelectPagedDataResponse<TData> {\n  constructor(public readonly payload: Array<TData>, public readonly totalCount: number) {}\n}\n\n/**\n * Default reset options\n */\nconst defaultResetOpts: NgSelectHelperResetOpts = {\n  resetQueryParams: false,\n  resetBody: false,\n  resetCache: false\n};\n\n/**\n * NgSelectHelper class for managing ng-select components with HTTP data loading,\n * pagination, caching, and search functionality using Angular signals\n *\n * @template TData The type of data items in the select options\n *\n * @example\n * ```typescript\n * interface User {\n *   id: number;\n *   name: string;\n *   email: string;\n * }\n *\n * @Component({\n *   selector: 'app-user-select',\n *   template: `\n *     <ng-select\n *       [items]=\"selectHelper.loadedData().payload\"\n *       bindLabel=\"name\"\n *       bindValue=\"id\"\n *       [loading]=\"selectHelper.isLoading()\"\n *       [typeahead]=\"selectHelper.inputSubject\"\n *       (open)=\"selectHelper.onOpen()\"\n *       (close)=\"selectHelper.onClose()\"\n *       (clear)=\"selectHelper.onClear()\"\n *       (scrollToEnd)=\"selectHelper.onScrollToEnd()\">\n *     </ng-select>\n *   `\n * })\n * export class UserSelectComponent implements OnInit {\n *   private httpClient = inject(HttpClient);\n *   private destroyRef = inject(DestroyRef);\n *\n *   selectHelper = NgSelectHelper.create<User>({\n *     ajaxUrl: '/api/users',\n *     httpClient: this.httpClient,\n *     destroyRef: this.destroyRef,\n *     usePostRequest: false,\n *     limit: 20\n *   });\n *\n *   ngOnInit() {\n *     this.selectHelper.init();\n *   }\n * }\n *\n * ```\n */\n\n/**\n * @deprecated Migrate to `offsetPaginatedNgSelectState`\n *\n * **Migration Guide:**\n *\n * - `init` method is removed because no manual state initialization is needed.\n * - `resetAll` method is renamed to `reset`.\n * -  Loaded data is exposed as data signal. Use it like: `[items]=\"ngSelectState.data()\"`\n * - `search` event handling is now compulsory with `onSearch`. Handle it like: `(search)=\"ngSelectState.onSearch($event)\"`\n * - `blur` event handling is not required and the method `onBlur` is removed.\n * - `setQueryParams` method is removed.  Current example approach: `ngSelectState.removeAllQueryParams().patchQueryParams({id: 123})`\n * - `setRouteParam` method is removed. If route param needs update, pass a signal of type string in the url and update the signal afterwards.\n * -  Cache is now disabled by default and supports TTL.\n * - `skipLoadingSpinner` is removed. Instead, use the exported `OffsetPaginatedNgSelectNetworkRequest` http context token.\n * - `offsetPaginatedNgSelectState` must be run within injection context. Provide injector manually to run outside injection context.\n */\nexport class NgSelectHelper<TData> {\n  constructor(\n    private ajaxUrl: string,\n    private readonly httpClient: HttpClient,\n    private readonly destroyRef: DestroyRef,\n    public readonly usePostRequest = false,\n    limit: number = 50,\n    private readonly useCache: boolean = true,\n    private skipLoadingSpinner: boolean = true,\n    initialSearchText: string = \"\"\n  ) {\n    this.#searchText = initialSearchText;\n    this.#originalAjaxUrl = ajaxUrl;\n    this.#limit = limit > 0 ? limit : 50;\n    this.destroyRef.onDestroy(() => {\n      this.#ajaxErrorSubject.complete();\n      this.inputSubject.complete();\n      this.#loadMoreDataSubject.complete();\n      this.#cache.clear();\n      if (this.runningApiReq && !this.runningApiReq.closed) {\n        this.runningApiReq.unsubscribe();\n      }\n    });\n  }\n\n  readonly #cache: Map<string, NgSelectPagedDataResponse<TData>> = new Map();\n  readonly #originalAjaxUrl: string;\n  #queryParams: NgSelectHelperQueryParam = {};\n  #body: NgSelectHelperBody = {};\n  #initDone = false;\n  #searchText = \"\";\n  readonly #limit: number;\n  #page = 1;\n  #debounceTimeInSec: number = 1;\n  #totalCount = -1;\n  #isLastApiCallSuccessful = true;\n  #limitReached = false;\n\n  readonly #loadMoreDataSubject = new Subject<void>();\n\n  public readonly inputSubject = new Subject<string>();\n  readonly #ajaxErrorSubject = new Subject<Error>();\n  public readonly ajaxError$ = this.#ajaxErrorSubject.asObservable();\n  readonly #loadedData = signal<NgSelectPagedDataResponse<TData>>(\n    new NgSelectPagedDataResponse<TData>([], 0)\n  );\n  public readonly loadedData = this.#loadedData.asReadonly();\n  readonly #isLoading = signal(false);\n  public readonly isLoading = this.#isLoading.asReadonly();\n  private runningApiReq: Subscription | null = null;\n\n  /**\n   * Creates a new instance of NgSelectHelper\n   * @param options Configuration options\n   * @returns New NgSelectHelper instance\n   */\n  public static create<T>({\n    ajaxUrl,\n    httpClient,\n    destroyRef,\n    usePostRequest = false,\n    limit = 50,\n    useCache = true,\n    skipLoadingSpinner = true,\n    initialSearchText = \"\"\n  }: NgSelectHelperOpts): NgSelectHelper<T> {\n    return new NgSelectHelper<T>(\n      ajaxUrl,\n      httpClient,\n      destroyRef,\n      usePostRequest,\n      limit,\n      useCache,\n      skipLoadingSpinner,\n      initialSearchText\n    );\n  }\n\n  /**\n   * Sets whether to skip the loading spinner for HTTP requests\n   * @param skip Whether to skip the loading spinner\n   * @returns This instance for method chaining\n   */\n  public setSkipLoadingSpinner(skip: boolean): this {\n    this.skipLoadingSpinner = skip;\n    return this;\n  }\n\n  /**\n   * Sets the debounce time for search input in seconds\n   * @param debounceTimeInSecond Debounce time in seconds\n   * @returns This instance for method chaining\n   */\n  public setDebounceTimeInSecond(debounceTimeInSecond: number): this {\n    this.#debounceTimeInSec = debounceTimeInSecond > 0 ? debounceTimeInSecond : 1;\n    return this;\n  }\n\n  /**\n   * Patches the request body (only works with POST requests)\n   * @param value Body data to merge\n   * @returns This instance for method chaining\n   */\n  public patchBody(value: NgSelectHelperBody): this {\n    if (this.usePostRequest) {\n      this.resetAll();\n      this.#body = Object.assign(this.#body, value);\n    }\n    return this;\n  }\n\n  /**\n   * Sets the request body (only works with POST requests)\n   * @param newBody New body data\n   * @returns This instance for method chaining\n   */\n  public setBody(newBody: NgSelectHelperBody): this {\n    if (this.usePostRequest) {\n      this.resetAll();\n      this.#body = newBody;\n    }\n    return this;\n  }\n\n  /**\n   * Clears the internal cache\n   * @returns This instance for method chaining\n   */\n  public clearCache(): this {\n    this.#cache.clear();\n    return this;\n  }\n\n  /**\n   * Sets route parameters for the URL\n   * @param newRouteParam Route parameter to append\n   * @returns This instance for method chaining\n   */\n  public setRouteParam(newRouteParam: string): this {\n    const baseUrl = this.#originalAjaxUrl.endsWith(\"/\")\n      ? this.#originalAjaxUrl.slice(0, -1)\n      : this.#originalAjaxUrl;\n\n    let routeParam = newRouteParam.startsWith(\"/\") ? newRouteParam.slice(1) : newRouteParam;\n\n    this.ajaxUrl = `${baseUrl}/${routeParam}`;\n\n    return this;\n  }\n\n  /**\n   * Patches query parameters\n   * @param value Query parameters to merge\n   * @returns This instance for method chaining\n   */\n  public patchQueryParams(value: NgSelectHelperQueryParam): this {\n    this.resetAll();\n    this.#queryParams = Object.assign(this.#queryParams, value);\n    return this;\n  }\n\n  /**\n   * Removes a query parameter\n   * @param key Query parameter key to remove\n   * @returns This instance for method chaining\n   */\n  public removeQueryParam(key: string): this {\n    this.resetAll();\n    delete this.#queryParams[key];\n    return this;\n  }\n\n  /**\n   * Sets query parameters\n   * @param newQueryParams New query parameters\n   * @returns This instance for method chaining\n   */\n  public setQueryParams(newQueryParams: NgSelectHelperQueryParam): this {\n    this.resetAll();\n    this.#queryParams = newQueryParams;\n    return this;\n  }\n\n  /**\n   * Handler for ng-select blur event\n   */\n  public onBlur(): void {\n    this.resetAll();\n  }\n\n  /**\n   * Handler for ng-select close event\n   */\n  public onClose(): void {\n    this.resetSearchText();\n    if (this.runningApiReq && !this.runningApiReq.closed) {\n      this.runningApiReq.unsubscribe();\n      this.runningApiReq = null;\n    }\n  }\n\n  /**\n   * Handler for ng-select clear event\n   */\n  public async onClear(): Promise<void> {\n    this.resetAll();\n  }\n\n  /**\n   * Handler for ng-select open event\n   */\n  public onOpen(): void {\n    this.#loadMoreDataSubject.next();\n  }\n\n  /**\n   * Handler for ng-select scroll to end event\n   */\n  public onScrollToEnd(): void {\n    if (this.#isLoading()) {\n      return;\n    }\n    if (this.isLastApiCallSuccessful && !this.limitReached) {\n      this.#page += 1;\n    }\n    this.#loadMoreDataSubject.next();\n  }\n\n  /**\n   * Gets whether the last API call was successful\n   */\n  public get isLastApiCallSuccessful(): boolean {\n    return this.#isLastApiCallSuccessful;\n  }\n\n  /**\n   * Gets whether the limit has been reached\n   */\n  public get limitReached(): boolean {\n    return this.#limitReached;\n  }\n\n  /**\n   * Gets current query parameters\n   */\n  public get queryParams(): NgSelectHelperQueryParam {\n    return this.#queryParams;\n  }\n\n  /**\n   * Gets current request body\n   */\n  public get body(): NgSelectHelperBody {\n    return this.#body;\n  }\n\n  /**\n   * Gets current page number\n   */\n  public get page(): number {\n    return this.#page;\n  }\n\n  /**\n   * Gets total count of available items\n   */\n  public get totalCount(): number {\n    return this.#totalCount;\n  }\n\n  /**\n   * Gets whether initialization is complete\n   */\n  public get isInitDone(): boolean {\n    return this.#initDone;\n  }\n\n  /**\n   * Initializes the NgSelectHelper with event handlers\n   * Should be called in ngOnInit or similar lifecycle method\n   */\n  public init(): void {\n    if (this.#initDone) {\n      return;\n    }\n    this.#initDone = true;\n\n    // Handle search input with debouncing\n    this.inputSubject\n      .pipe(\n        debounceTime(this.#debounceTimeInSec * 500),\n        switchMap((term) => {\n          this.resetAll();\n          this.#searchText = term;\n          return this.loadDataFromApi(this.page, this.#limit, term).pipe(\n            catchError(() => of(null))\n          );\n        })\n      )\n      .subscribe({\n        next: (res) => {\n          if (res) {\n            this.updateStateOnSuccessfulInitialApiCall(res);\n          } else {\n            this.updateStateOnFailedApiCall();\n          }\n        }\n      });\n\n    // Trigger initial search if initialSearchText was provided\n    if (this.#searchText !== \"\") {\n      this.inputSubject.next(this.#searchText);\n    }\n\n    // Handle load more requests\n    this.#loadMoreDataSubject\n      .pipe(\n        switchMap(() => {\n          if (this.#isLoading()) {\n            return of(null);\n          }\n\n          this.runLimitReachedCheck();\n\n          if (this.limitReached) {\n            return of(null);\n          }\n\n          return this.loadDataFromApi(this.page, this.#limit, this.#searchText).pipe(\n            catchError(() => of(null))\n          );\n        })\n      )\n      .subscribe({\n        next: (res) => {\n          if (res) {\n            this.updateStateOnSuccessfulSubsequentApiCall(res);\n          } else {\n            this.updateStateOnFailedApiCall();\n          }\n        }\n      });\n  }\n\n  /**\n   * Loads data from the API\n   * @param page Page number\n   * @param limit Items per page\n   * @param searchText Search term\n   * @returns Observable of paged data response\n   */\n  private loadDataFromApi(\n    page: number,\n    limit: number,\n    searchText?: string\n  ): Observable<NgSelectPagedDataResponse<TData> | null> {\n    const queryParams: Record<string, string | number> = { page, limit };\n\n    if (searchText) {\n      queryParams[\"searchText\"] = searchText;\n    }\n\n    const key: CacheKey = {\n      ajaxUrl: this.ajaxUrl,\n      page: page,\n      limit: limit,\n      searchText: searchText ?? \"\",\n      queryParams: { ...queryParams, ...this.#queryParams },\n      body: this.#body\n    };\n\n    let strKey: string | null = null;\n\n    if (this.useCache) {\n      strKey = JSON.stringify(key);\n      const cacheData = this.#cache.get(strKey);\n\n      if (cacheData !== undefined) {\n        return of(cacheData);\n      }\n    }\n\n    this.#isLoading.set(true);\n\n    let req: Observable<NgSelectPagedDataResponse<TData> | null>;\n\n    if (this.usePostRequest) {\n      req = this.httpClient.post<NgSelectPagedDataResponse<TData>>(key.ajaxUrl, key.body, {\n        params: key.queryParams,\n        context: new HttpContext().set(SkipLoadingSpinner, this.skipLoadingSpinner)\n      });\n    } else {\n      req = this.httpClient.get<NgSelectPagedDataResponse<TData>>(key.ajaxUrl, {\n        params: key.queryParams,\n        context: new HttpContext().set(SkipLoadingSpinner, this.skipLoadingSpinner)\n      });\n    }\n\n    return req.pipe(\n      first(),\n      mergeMap((val) => {\n        if (!val) {\n          throw new Error(\"Invalid response body for ng-select\");\n        }\n        if (!Object.hasOwn(val, \"payload\") || !Object.hasOwn(val, \"totalCount\")) {\n          throw new Error(\"Invalid response body for ng-select\");\n        }\n\n        if (!Array.isArray(Reflect.get(val, \"payload\"))) {\n          throw new Error(\"Invalid response body for ng-select\");\n        }\n\n        return of(val);\n      }),\n      tap((val) => {\n        if (this.useCache && strKey && val) {\n          this.#cache.set(strKey, val);\n        }\n      }),\n      catchError((error) => {\n        this.#ajaxErrorSubject.next(error);\n        return of(null);\n      }),\n      finalize(() => this.#isLoading.set(false))\n    );\n  }\n\n  /**\n\n\n  /**\n   * Checks if the limit has been reached\n   */\n  private runLimitReachedCheck(): void {\n    if (this.totalCount !== -1) {\n      this.#limitReached = this.#loadedData().payload.length >= this.totalCount;\n    }\n  }\n\n  /**\n   * Updates state after successful initial API call\n   * @param data Response data\n   */\n  private updateStateOnSuccessfulInitialApiCall(data: NgSelectPagedDataResponse<TData>): void {\n    this.#loadedData.set(new NgSelectPagedDataResponse(data.payload, data.totalCount));\n    this.#totalCount = data.totalCount;\n    this.#isLastApiCallSuccessful = true;\n  }\n\n  /**\n   * Updates state after successful subsequent API call\n   * @param data Response data\n   */\n  private updateStateOnSuccessfulSubsequentApiCall(data: NgSelectPagedDataResponse<TData>): void {\n    this.#loadedData.update((val) => {\n      return new NgSelectPagedDataResponse<TData>(\n        [...val.payload, ...data.payload],\n        data.totalCount\n      );\n    });\n\n    this.#totalCount = data.totalCount;\n    this.#isLastApiCallSuccessful = true;\n  }\n\n  /**\n   * Updates state after failed API call\n   */\n  private updateStateOnFailedApiCall(): void {\n    this.#isLastApiCallSuccessful = false;\n  }\n\n  /**\n   * Resets all state to initial values\n   * @param opts Reset options\n   */\n  public resetAll(opts: NgSelectHelperResetOpts = defaultResetOpts): void {\n    // Cancel any running request\n    if (this.runningApiReq && !this.runningApiReq.closed) {\n      this.runningApiReq.unsubscribe();\n      this.runningApiReq = null;\n    }\n\n    this.#isLastApiCallSuccessful = true;\n    this.#page = 1;\n    this.#totalCount = -1;\n    this.#limitReached = false;\n    this.#searchText = \"\";\n\n    if (opts.resetCache) {\n      this.#cache.clear();\n    }\n\n    this.#loadedData.set(new NgSelectPagedDataResponse<TData>([], 0));\n    this.#isLoading.set(false);\n\n    if (opts.resetQueryParams) {\n      this.#queryParams = {};\n    }\n\n    if (opts.resetBody) {\n      this.#body = {};\n    }\n  }\n\n  /**\n   * Resets search text\n   */\n  private resetSearchText(): void {\n    this.#searchText = \"\";\n  }\n}\n\n/**\n * @deprecated Migrate to `offsetPaginatedNgSelectState`\n *\n * **Migration Guide:**\n *\n * - `init` method is removed because no manual state initialization is needed.\n * - `resetAll` method is renamed to `reset`.\n * -  Loaded data is exposed as data signal. Use it like: `[items]=\"ngSelectState.data()\"`\n * - `search` event handling is now compulsory with `onSearch`. Handle it like: `(search)=\"ngSelectState.onSearch($event)\"`\n * - `blur` event handling is not required and the method `onBlur` is removed.\n * - `setQueryParams` method is removed.  Current example approach: `ngSelectState.removeAllQueryParams().patchQueryParams({id: 123})`\n * - `setRouteParam` method is removed. If route param needs update, pass a signal of type string in the url and update the signal afterwards.\n * -  Cache is now disabled by default and supports TTL.\n * - `skipLoadingSpinner` is removed. Instead, use the exported `OffsetPaginatedNgSelectNetworkRequest` http context token.\n * - `offsetPaginatedNgSelectState` must be run within injection context. Provide injector manually to run outside injection context.\n */\nexport function createNgSelectHelper<T>(\n  options: Omit<NgSelectHelperOpts, \"httpClient\" | \"destroyRef\"> & { injector?: Injector }\n) {\n  !options.injector && assertInInjectionContext(createNgSelectHelper);\n  const assertedInjector = options.injector ?? inject(Injector);\n\n  return runInInjectionContext(assertedInjector, () => {\n    const httpClient = inject(HttpClient);\n    const destroyRef = inject(DestroyRef);\n    return NgSelectHelper.create<T>({\n      ...options,\n      httpClient,\n      destroyRef\n    });\n  });\n}\n","import { HttpClient, HttpContext, HttpContextToken, HttpParams } from \"@angular/common/http\";\nimport {\n  assertInInjectionContext,\n  computed,\n  DestroyRef,\n  inject,\n  InjectionToken,\n  Injector,\n  isDevMode,\n  isSignal,\n  Provider,\n  runInInjectionContext,\n  Signal,\n  signal\n} from \"@angular/core\";\nimport { takeUntilDestroyed, toObservable } from \"@angular/core/rxjs-interop\";\nimport {\n  catchError,\n  combineLatestWith,\n  debounceTime,\n  defer,\n  filter,\n  finalize,\n  interval,\n  Observable,\n  of,\n  Subject,\n  switchMap,\n  takeUntil,\n  tap\n} from \"rxjs\";\nimport { cleanNullishFromObject } from \"./utils\";\n\ntype OffsetPaginatedNgSelectStateResetOptions = {\n  resetQueryParams: boolean;\n  resetBody: boolean;\n  resetCache: boolean;\n};\n\ntype QueryParamPrimitive = string | number | boolean;\ntype QueryParamValue = QueryParamPrimitive | ReadonlyArray<QueryParamPrimitive>;\ntype QueryParams = Record<string, QueryParamValue>;\n\ntype CacheKey = {\n  url: string;\n  queryParams: string;\n  body: any;\n};\n\nexport type OffsetPaginatedNgSelectStateOptions = {\n  searchOnlyMode?: boolean;\n  searchQueryParamKey?: string;\n  pageQueryParamKey?: string;\n  limitQueryParamKey?: string;\n  dataArrayKey?: string;\n  totalDataCountKey?: string;\n  requestMethod?: \"GET\" | \"POST\";\n  queryParams?: QueryParams;\n  postRequestBody?: any;\n  dataLimitPerRequest?: number;\n  debounceTimeMs?: number;\n  useCache?: boolean;\n  cacheTtlSec?: number;\n  disableCacheExpiration?: boolean;\n  injector?: Injector;\n  onCloseReset?: { reset: boolean; resetOpts?: OffsetPaginatedNgSelectStateResetOptions };\n  httpContext?: HttpContext;\n  onError?: (error: Error) => void;\n};\n\nexport type OffsetPaginatedNgSelectStateConfig = Omit<\n  OffsetPaginatedNgSelectStateOptions,\n  \"injector\" | \"httpContext\" | \"queryParams\" | \"postRequestBody\"\n>;\n\ntype DefaultOptions = Omit<\n  Required<OffsetPaginatedNgSelectStateOptions>,\n  \"injector\" | \"httpContext\" | \"onError\"\n> & {\n  onError?: (error: Error) => void;\n};\n\nconst optionsWithDefaultValue: DefaultOptions = {\n  searchQueryParamKey: \"searchText\",\n  pageQueryParamKey: \"page\",\n  limitQueryParamKey: \"limit\",\n  dataArrayKey: \"payload\",\n  totalDataCountKey: \"totalCount\",\n  debounceTimeMs: 500,\n  searchOnlyMode: false,\n  requestMethod: \"GET\",\n  queryParams: {},\n  onCloseReset: { reset: false },\n  postRequestBody: null,\n  dataLimitPerRequest: 20,\n  useCache: false,\n  cacheTtlSec: 60,\n  disableCacheExpiration: false\n};\n\nconst OFFSET_PAGINATED_NG_SELECT_STATE_CONFIG = new InjectionToken<DefaultOptions>(\n  \"OFFSET_PAGINATED_NG_SELECT_STATE_CONFIG\",\n  {\n    providedIn: \"root\",\n    factory: () => optionsWithDefaultValue\n  }\n);\n\nexport function provideOffsetPaginatedNgSelectStateConfig(\n  configFactory: () => OffsetPaginatedNgSelectStateConfig\n): Provider {\n  return {\n    provide: OFFSET_PAGINATED_NG_SELECT_STATE_CONFIG,\n    useFactory: () => {\n      const config = configFactory();\n      return { ...optionsWithDefaultValue, ...config };\n    }\n  };\n}\n\nexport const OffsetPaginatedNgSelectNetworkRequest = new HttpContextToken(() => false);\n\nfunction isValidData(dataArrayKey: string, dataCountKey: string, rawData: any): boolean {\n  if (typeof rawData !== \"object\" || rawData === null || Array.isArray(rawData)) {\n    return false;\n  }\n\n  // Check for either the configured dataArrayKey, or fallback to 'payload' or 'data'\n  const hasData = dataArrayKey in rawData || \"payload\" in rawData || \"data\" in rawData;\n  if (!hasData || !(dataCountKey in rawData)) {\n    return false;\n  }\n\n  const dataArray = rawData[dataArrayKey] ?? rawData[\"payload\"] ?? rawData[\"data\"];\n  if (!Array.isArray(dataArray)) {\n    return false;\n  }\n\n  if (typeof rawData[dataCountKey] !== \"number\") {\n    return false;\n  }\n\n  return true;\n}\n\nfunction defaultData<T>(): { payload: T[]; totalCount: number } {\n  return {\n    payload: [] as T[],\n    totalCount: 0\n  };\n}\n\nconst defaultResetOpts = {\n  resetQueryParams: false,\n  resetBody: false,\n  resetCache: false\n};\n\nexport interface OffsetPaginatedNgSelectStateRef<TData> {\n  // Data state\n  typeaheadSubject: Subject<string>;\n  data: Signal<TData[]>;\n  isLoading: Signal<boolean>;\n  queryParams: Signal<QueryParams>;\n  postRequestBody: Signal<any>;\n\n  // Event handler methods\n  clearCache(): this;\n  onOpen(): void;\n  onClose(): void;\n  onClear(): void;\n  onSearch({ term }: { term: string }): void;\n  onScrollToEnd(): void;\n\n  // methods\n  reset(options?: OffsetPaginatedNgSelectStateResetOptions): void;\n  setBody(value: any): this;\n  clearBody(): this;\n  patchQueryParams(value: QueryParams): this;\n  removeQueryParam(key: string): this;\n  removeAllQueryParams(): this;\n}\n\nfunction httpParamsToObject(params: HttpParams): QueryParams {\n  const result: QueryParams = {};\n\n  params.keys().forEach((key) => {\n    const values = params.getAll(key);\n    if (values === null) {\n      return;\n    }\n\n    result[key] = values.length > 1 ? values : values[0];\n  });\n\n  return result;\n}\n\nfunction removeBlacklistedParams(params: HttpParams, blacklistedQueryKeys: string[]): HttpParams {\n  let current = params;\n\n  params.keys().forEach((key) => {\n    if (blacklistedQueryKeys.includes(key.toLowerCase())) {\n      current = current.delete(key);\n    }\n  });\n\n  return current;\n}\n\nexport function offsetPaginatedNgSelectState<TData>(\n  url: string | Signal<string | null>,\n  options?: OffsetPaginatedNgSelectStateOptions\n): OffsetPaginatedNgSelectStateRef<TData> {\n  if (isDevMode() && !options?.injector) {\n    assertInInjectionContext(offsetPaginatedNgSelectState);\n  }\n\n  const assertedInjector = options?.injector ?? inject(Injector);\n\n  return runInInjectionContext(assertedInjector, () => {\n    const destroyRef = inject(DestroyRef);\n    const http = inject(HttpClient);\n    const configFromDi = inject(OFFSET_PAGINATED_NG_SELECT_STATE_CONFIG);\n    const typeaheadSubject = new Subject<string>();\n    const typeAhead$ = typeaheadSubject.asObservable();\n\n    const mergedOptions: DefaultOptions & {\n      httpContext: HttpContext;\n    } = {\n      ...configFromDi,\n      ...cleanNullishFromObject(options),\n      httpContext: options?.httpContext ?? new HttpContext(),\n      onError: options?.onError ?? configFromDi.onError\n    };\n\n    const blackListedQueryKeys = [\n      mergedOptions.searchQueryParamKey,\n      mergedOptions.pageQueryParamKey,\n      mergedOptions.limitQueryParamKey\n    ].map((elem) => elem.toLowerCase());\n\n    const sanitizedMergedQueryParams = removeBlacklistedParams(\n      new HttpParams({ fromObject: mergedOptions.queryParams }),\n      blackListedQueryKeys\n    );\n\n    const internalState = Object.seal({\n      apiCallNotification: new Subject<void>(),\n      apiCallAbortNotifier: new Subject<void>(),\n      currentPage: signal(1),\n      isCurrentPageSuccessful: signal(false),\n      isAllDataLoaded: signal(false),\n      isLoading: signal(false),\n      searchTermFromSearchEvent: signal<string | null>(null),\n      isSelectPanelOpen: signal(false),\n      loadedData: signal(defaultData<TData>()),\n      searchText: signal<string | null>(null),\n      cache: new Map<string, { payload: TData[]; totalCount: number }>(),\n      postRequestBody: signal(mergedOptions.postRequestBody),\n      queryParamsFromConsumer: signal(sanitizedMergedQueryParams)\n    });\n\n    const finalQueryParams = computed(() => {\n      let val = internalState\n        .queryParamsFromConsumer()\n        .set(mergedOptions.pageQueryParamKey, String(internalState.currentPage()))\n        .set(mergedOptions.limitQueryParamKey, String(mergedOptions.dataLimitPerRequest));\n\n      const searchText = internalState.searchText();\n      if (searchText !== null) {\n        val = val.set(mergedOptions.searchQueryParamKey, searchText);\n      } else {\n        val = val.delete(mergedOptions.searchQueryParamKey);\n      }\n\n      return val;\n    });\n\n    destroyRef.onDestroy(() => {\n      if (!typeaheadSubject.closed) {\n        typeaheadSubject.complete();\n      }\n\n      if (!internalState.apiCallAbortNotifier.closed) {\n        internalState.apiCallAbortNotifier.next();\n        internalState.apiCallAbortNotifier.complete();\n      }\n\n      if (!internalState.apiCallNotification.closed) {\n        internalState.apiCallNotification.complete();\n      }\n\n      internalState.cache.clear();\n    });\n\n    if (mergedOptions.useCache && !mergedOptions.disableCacheExpiration) {\n      interval(mergedOptions.cacheTtlSec * 1000)\n        .pipe(takeUntilDestroyed(destroyRef))\n        .subscribe(() => {\n          internalState.cache.clear();\n        });\n    }\n\n    function reset(options: OffsetPaginatedNgSelectStateResetOptions = defaultResetOpts) {\n      internalState.apiCallAbortNotifier.next();\n      internalState.currentPage.set(1);\n      internalState.isCurrentPageSuccessful.set(false);\n      internalState.searchText.set(null);\n\n      internalState.loadedData.set(defaultData());\n      internalState.isAllDataLoaded.set(false);\n      internalState.isLoading.set(false);\n\n      if (options.resetBody) {\n        internalState.postRequestBody.set(mergedOptions.postRequestBody);\n      }\n\n      if (options.resetQueryParams) {\n        internalState.queryParamsFromConsumer.set(sanitizedMergedQueryParams);\n      }\n\n      if (options.resetCache) {\n        internalState.cache.clear();\n      }\n    }\n\n    const notifyApiCall = () => {\n      internalState.apiCallNotification.next();\n    };\n\n    const handleApiResponse = (newData: { payload: TData[]; totalCount: number }) => {\n      internalState.isCurrentPageSuccessful.set(true);\n\n      if (newData.payload.length > 0) {\n        internalState.loadedData.update((val) => {\n          return {\n            payload: [...val.payload, ...newData.payload],\n            totalCount: newData.totalCount\n          };\n        });\n      }\n\n      internalState.isAllDataLoaded.set(\n        internalState.loadedData().payload.length === newData.totalCount\n      );\n    };\n\n    const loadDataFromApi = () => {\n      const finalUrl = isSignal(url) ? url() : url;\n      if (finalUrl === null) {\n        return of(null);\n      }\n      const key: CacheKey = {\n        url: finalUrl,\n        body: internalState.postRequestBody(),\n        queryParams: finalQueryParams().toString()\n      };\n\n      if (mergedOptions.requestMethod !== \"POST\") {\n        delete key[\"body\"];\n      }\n\n      let strKey: string | null = null;\n\n      if (mergedOptions.useCache) {\n        strKey = JSON.stringify(key);\n        const cacheData = internalState.cache.get(strKey);\n\n        if (cacheData !== undefined) {\n          return of(cacheData);\n        }\n      }\n\n      let req: Observable<Object>;\n\n      switch (mergedOptions.requestMethod) {\n        case \"GET\":\n          req = defer(() => {\n            internalState.isLoading.set(true);\n            return http.get(finalUrl, {\n              params: finalQueryParams(),\n              context: mergedOptions.httpContext.set(OffsetPaginatedNgSelectNetworkRequest, true)\n            });\n          });\n          break;\n\n        case \"POST\":\n          req = defer(() => {\n            internalState.isLoading.set(true);\n            return http.post(finalUrl, internalState.postRequestBody(), {\n              params: finalQueryParams(),\n              context: mergedOptions.httpContext.set(OffsetPaginatedNgSelectNetworkRequest, true)\n            });\n          });\n          break;\n\n        default:\n          throw new Error(\"Invalid/unsupported request method\");\n      }\n\n      return req.pipe(\n        switchMap((rawData: any) => {\n          if (!isValidData(mergedOptions.dataArrayKey, mergedOptions.totalDataCountKey, rawData)) {\n            throw new Error(\n              `The response body must be an object. Valid example: { ${mergedOptions.dataArrayKey}: [], ${mergedOptions.totalDataCountKey}: 0 } or { payload: [], ${mergedOptions.totalDataCountKey}: 0 } or { data: [], ${mergedOptions.totalDataCountKey}: 0 }`\n            );\n          }\n\n          // Extract data array - support configured key, 'payload', or 'data'\n          const dataArray =\n            rawData[mergedOptions.dataArrayKey] ?? rawData[\"payload\"] ?? rawData[\"data\"] ?? [];\n\n          const dataInContainer: { payload: TData[]; totalCount: number } = {\n            payload: dataArray,\n            totalCount: rawData[mergedOptions.totalDataCountKey] ?? 0\n          };\n\n          return of(dataInContainer);\n        }),\n        tap((data) => {\n          if (mergedOptions.useCache && strKey && data) {\n            internalState.cache.set(strKey, data);\n          }\n        }),\n        catchError((error) => {\n          if (mergedOptions.onError) {\n            try {\n              mergedOptions.onError(error);\n            } catch (errorFromHandler) {\n              console.warn(\n                \"Exception in onError is handled internally to keep observable running.\",\n                errorFromHandler\n              );\n            }\n          }\n          console.error(error);\n          return of(null);\n        }),\n        finalize(() => internalState.isLoading.set(false)),\n        takeUntil(internalState.apiCallAbortNotifier)\n      );\n    };\n\n    internalState.apiCallNotification\n      .pipe(\n        switchMap(() =>\n          internalState.isLoading() ||\n          internalState.isAllDataLoaded() ||\n          !internalState.isSelectPanelOpen()\n            ? of(null)\n            : loadDataFromApi()\n        ),\n        filter((val) => val !== null),\n        takeUntilDestroyed(destroyRef)\n      )\n      .subscribe((data) => {\n        handleApiResponse(data);\n      });\n\n    typeAhead$\n      .pipe(\n        combineLatestWith(toObservable(internalState.searchTermFromSearchEvent)),\n        debounceTime(mergedOptions.debounceTimeMs),\n        switchMap(([typeaheadValue, searchEventValue]) => {\n          if (typeaheadValue === searchEventValue) {\n            return of(typeaheadValue.trim());\n          }\n          if (typeaheadValue !== searchEventValue && searchEventValue === \"\") {\n            return of(\"\");\n          }\n          return of(null);\n        }),\n        filter((val) => val !== null),\n        takeUntilDestroyed(destroyRef)\n      )\n      .subscribe((finalValue) => {\n        reset();\n\n        if (mergedOptions.searchOnlyMode && finalValue === \"\") {\n          return;\n        }\n\n        internalState.searchText.set(finalValue);\n\n        notifyApiCall();\n      });\n\n    return Object.seal({\n      // data state\n      reset,\n      queryParams: computed(() => {\n        return httpParamsToObject(finalQueryParams());\n      }),\n      postRequestBody: internalState.postRequestBody.asReadonly(),\n      typeaheadSubject,\n      data: computed(() => {\n        return internalState.loadedData().payload;\n      }),\n      isLoading: internalState.isLoading.asReadonly(),\n      // event handlers\n      clearCache() {\n        internalState.cache.clear();\n        return this;\n      },\n\n      onOpen() {\n        internalState.isSelectPanelOpen.set(true);\n        if (!mergedOptions.searchOnlyMode) {\n          notifyApiCall();\n        }\n      },\n\n      onClose() {\n        internalState.isSelectPanelOpen.set(false);\n        if (mergedOptions.onCloseReset.reset) {\n          reset(mergedOptions.onCloseReset.resetOpts);\n        }\n      },\n\n      onClear() {\n        reset();\n      },\n\n      onSearch(event: Record<string, unknown> & { term: string }) {\n        if (Object.hasOwn(event, \"term\")) {\n          internalState.searchTermFromSearchEvent.set(event.term);\n        }\n      },\n\n      onScrollToEnd() {\n        if (\n          internalState.isAllDataLoaded() ||\n          internalState.isLoading() ||\n          !internalState.isSelectPanelOpen()\n        ) {\n          return;\n        }\n\n        if (internalState.isCurrentPageSuccessful()) {\n          internalState.currentPage.update((currentValue) => {\n            return currentValue + 1;\n          });\n        }\n\n        notifyApiCall();\n      },\n      // chainable methods\n      setBody(value: any) {\n        if (mergedOptions.requestMethod === \"POST\") {\n          reset();\n          internalState.postRequestBody.set(value);\n        }\n        return this;\n      },\n      clearBody() {\n        if (mergedOptions.requestMethod === \"POST\") {\n          reset();\n          internalState.postRequestBody.set(null);\n        }\n        return this;\n      },\n\n      patchQueryParams(value: QueryParams) {\n        const newValue = { ...value };\n\n        Object.keys(newValue).forEach((key) => {\n          if (blackListedQueryKeys.includes(key.toLowerCase())) {\n            delete newValue[key];\n          }\n        });\n\n        const keys = Object.keys(newValue);\n\n        if (keys.length === 0) {\n          return this;\n        }\n\n        reset();\n\n        internalState.queryParamsFromConsumer.update((current) => {\n          let next = current;\n\n          keys.forEach((key) => {\n            next = next.delete(key);\n          });\n\n          return next.appendAll(newValue);\n        });\n\n        return this;\n      },\n\n      removeQueryParam(key: string) {\n        reset();\n        internalState.queryParamsFromConsumer.update((currentValue) => {\n          return currentValue.delete(key);\n        });\n        return this;\n      },\n      removeAllQueryParams() {\n        reset();\n        internalState.queryParamsFromConsumer.set(new HttpParams());\n        return this;\n      }\n    });\n  });\n}\n","import {\n  assertInInjectionContext,\n  DestroyRef,\n  inject,\n  Injector,\n  runInInjectionContext,\n  Signal\n} from \"@angular/core\";\nimport { takeUntilDestroyed, toObservable } from \"@angular/core/rxjs-interop\";\nimport { Observable } from \"rxjs\";\nimport { NgSelectHelper } from \"./ng-select-helper\";\n\n/**\n * @deprecated Use `initNgSelectHelper` instead.\n */\nexport function initNgSelect(\n  helpers$: Observable<NgSelectHelper<unknown>[]>,\n  destroyRef: DestroyRef,\n  onAjaxError: (err: Error) => void\n): void {\n  helpers$.pipe(takeUntilDestroyed(destroyRef)).subscribe({\n    next: (helpers) => {\n      helpers\n        .filter((elem) => elem instanceof NgSelectHelper && !elem.isInitDone)\n        .forEach((elem) => {\n          elem.init();\n          elem.ajaxError$.pipe(takeUntilDestroyed(destroyRef)).subscribe(onAjaxError);\n        });\n    }\n  });\n}\n\ntype InitNgSelectHelperOptions = {\n  /** Optional Callback function to handle AJAX errors */\n  onAjaxError?: (err: Error) => void;\n  /** Optional Angular Injector */\n  injector?: Injector;\n};\n\n/**\n * Utility function to initialize NgSelect helpers with error handling\n *\n * This function streamlines the initialization process for multiple NgSelect helpers\n * by automatically initializing them and setting up error handling subscriptions.\n\n * @example\n * ```typescript\n * import { Component, inject, signal } from '@angular/core';\n * import { HttpClient } from '@angular/common/http';\n * import { DestroyRef } from '@angular/core';\n * import { toObservable } from '@angular/core/rxjs-interop';\n * import { NgSelectHelper, initNgSelectHelper } from 'ngx-primeng-toolkit';\n *\n * @Component({\n *   selector: 'app-example'\n * })\n * export class ExampleComponent {\n *   private readonly httpClient = inject(HttpClient);\n *   private readonly destroyRef = inject(DestroyRef);\n *   private readonly toastService = inject(ToastService);\n *\n *   readonly userSelectHelper = new NgSelectHelper<User>(\n *     '/api/users',\n *     this.httpClient,\n *     this.destroyRef,\n *     false, // requiresSearch\n *     50,    // pageSize\n *     false  // isLazyLoad\n *   );\n *\n *   readonly departmentSelectHelper = new NgSelectHelper<Department>(\n *     '/api/departments',\n *     this.httpClient,\n *     this.destroyRef,\n *     true,  // requiresSearch\n *     25,    // pageSize\n *     true   // isLazyLoad\n *   );\n *\n *   readonly ngSelectHelpers = signal([\n *     this.userSelectHelper,\n *     this.departmentSelectHelper\n *   ]);\n *\n * constructor() {\n *   initNgSelectHelper(this.ngSelectHelpers, {\n *     onAjaxError: (err) => this.toastService.showAjaxErrorToast(err)\n *   });\n * }\n * }\n * ```\n */\n\nexport function initNgSelectHelper(\n  items: Signal<NgSelectHelper<unknown>[]>,\n  options: InitNgSelectHelperOptions = {}\n): void {\n  !options.injector && assertInInjectionContext(initNgSelectHelper);\n  const assertedInjector = options.injector ?? inject(Injector);\n\n  runInInjectionContext(assertedInjector, () => {\n    const destroyRef = inject(DestroyRef);\n    toObservable(items)\n      .pipe(takeUntilDestroyed(destroyRef))\n      .subscribe((elem) => {\n        elem\n          .filter((elem) => elem instanceof NgSelectHelper && !elem.isInitDone)\n          .forEach((elem) => {\n            elem.init();\n\n            if (!options.onAjaxError) {\n              return;\n            }\n\n            elem.ajaxError$.pipe(takeUntilDestroyed(destroyRef)).subscribe((payload) => {\n              if (options.onAjaxError) {\n                options.onAjaxError(payload);\n              }\n            });\n          });\n      });\n  });\n}\n","import { HttpClient, HttpContext, HttpContextToken, HttpParams } from \"@angular/common/http\";\nimport {\n  assertInInjectionContext,\n  computed,\n  DestroyRef,\n  effect,\n  inject,\n  InjectionToken,\n  Injector,\n  isDevMode,\n  isSignal,\n  Provider,\n  runInInjectionContext,\n  signal,\n  Signal,\n  untracked\n} from \"@angular/core\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\nimport { LazyLoadMeta } from \"primeng/api\";\nimport { TableLazyLoadEvent } from \"primeng/table\";\nimport {\n  catchError,\n  defer,\n  filter,\n  finalize,\n  Observable,\n  of,\n  Subject,\n  switchMap,\n  takeUntil\n} from \"rxjs\";\nimport { cleanNullishFromObject } from \"./utils\";\n\nexport const OffsetPaginatedPrimeNgTableStateNetworkRequest = new HttpContextToken(() => false);\n\ntype DataContainer<T> = {\n  payload: T[];\n  totalCount: number;\n};\nexport class PostRequestBody {\n  constructor(public readonly payload: any) {}\n}\n\nexport type FilterAndSortFn = (meta: LazyLoadMeta) => HttpParams | PostRequestBody;\n\nexport type OffsetPaginatedPrimeNgTableStateOptions = {\n  predicate?: Signal<boolean>;\n  pageQueryParamKey?: string;\n  limitQueryParamKey?: string;\n  dataArrayKey?: string;\n  totalDataCountKey?: string;\n  requestMethod?: \"GET\" | \"POST\";\n  queryParams?: Record<string, string | number | boolean>;\n  injector?: Injector;\n  httpContext?: HttpContext;\n  filterAndSortHandler?: FilterAndSortFn;\n  onError?: (error: Error) => void;\n};\n\nexport type OffsetPaginatedPrimeNgTableStateConfig = Omit<\n  OffsetPaginatedPrimeNgTableStateOptions,\n  \"injector\" | \"httpContext\" | \"predicate\" | \"queryParams\"\n>;\n\ntype DefaultOptions = Omit<\n  Required<OffsetPaginatedPrimeNgTableStateOptions>,\n  \"injector\" | \"httpContext\" | \"predicate\" | \"onError\" | \"filterAndSortHandler\"\n> & {\n  onError?: (error: Error) => void;\n};\n\nconst optionsWithDefaultValue: DefaultOptions = {\n  pageQueryParamKey: \"page\",\n  limitQueryParamKey: \"limit\",\n  dataArrayKey: \"payload\",\n  totalDataCountKey: \"totalCount\",\n  requestMethod: \"GET\",\n  queryParams: {}\n};\n\nconst OFFSET_PAGINATED_PRIME_NG_TABLE_STATE_CONFIG = new InjectionToken<DefaultOptions>(\n  \"OFFSET_PAGINATED_PRIME_NG_TABLE_STATE_CONFIG\",\n  {\n    providedIn: \"root\",\n    factory: () => optionsWithDefaultValue\n  }\n);\n\nexport function provideOffsetPaginatedPrimeNgTableStateConfig(\n  configFactory: () => OffsetPaginatedPrimeNgTableStateConfig\n): Provider {\n  return {\n    provide: OFFSET_PAGINATED_PRIME_NG_TABLE_STATE_CONFIG,\n    useFactory: () => {\n      const config = configFactory();\n      return { ...optionsWithDefaultValue, ...config };\n    }\n  };\n}\n\nexport interface OffsetPaginatedPrimeNgTableStateRef<T> {\n  predicate: Signal<boolean>;\n  totalRecords: Signal<number>;\n  data: Signal<T[]>;\n  isLoading: Signal<boolean>;\n  queryParams: Signal<Record<string, string | number | boolean>>;\n  onLazyLoad(event: TableLazyLoadEvent): void;\n  patchQueryParams(value: Record<string, string | number | boolean>): this;\n  removeQueryParam(key: string): this;\n  removeAllQueryParams(): this;\n}\n\nfunction isValidData(dataArrayKey: string, dataCountKey: string, rawData: any): boolean {\n  if (typeof rawData !== \"object\" || rawData === null || Array.isArray(rawData)) {\n    return false;\n  }\n\n  if (!(dataArrayKey in rawData) || !(dataCountKey in rawData)) {\n    return false;\n  }\n\n  if (!Array.isArray(rawData[dataArrayKey])) {\n    return false;\n  }\n\n  if (typeof rawData[dataCountKey] !== \"number\") {\n    return false;\n  }\n\n  return true;\n}\n\nfunction defaultData<T>() {\n  return {\n    payload: [] as T[],\n    totalCount: 0\n  } satisfies DataContainer<T>;\n}\n\nexport function offsetPaginatedPrimeNgTableState<T>(\n  url: string | Signal<string>,\n  options?: OffsetPaginatedPrimeNgTableStateOptions\n): OffsetPaginatedPrimeNgTableStateRef<T> {\n  if (isDevMode() && !options?.injector) {\n    assertInInjectionContext(offsetPaginatedPrimeNgTableState);\n  }\n\n  const assertedInjector = options?.injector ?? inject(Injector);\n\n  return runInInjectionContext(assertedInjector, () => {\n    const http = inject(HttpClient);\n    const destroyRef = inject(DestroyRef);\n    const configFromDi = inject(OFFSET_PAGINATED_PRIME_NG_TABLE_STATE_CONFIG);\n\n    const mergedOptions: DefaultOptions & {\n      httpContext: HttpContext;\n      predicate?: Signal<boolean>;\n      filterAndSortHandler?: FilterAndSortFn;\n    } = {\n      ...configFromDi,\n      ...cleanNullishFromObject(options),\n      httpContext: options?.httpContext ?? new HttpContext(),\n      onError: options?.onError ?? configFromDi.onError\n    };\n\n    const blackListedQueryKeys = [\n      mergedOptions.pageQueryParamKey,\n      mergedOptions.limitQueryParamKey\n    ].map((elem) => elem.toLowerCase());\n\n    Object.keys(mergedOptions.queryParams).forEach((key) => {\n      if (blackListedQueryKeys.includes(key.toLowerCase())) {\n        delete mergedOptions.queryParams[key];\n      }\n    });\n\n    const internalState = Object.seal({\n      apiCallNotification: new Subject<void>(),\n      apiCallAbortNotifier: new Subject<void>(),\n      isLoading: signal(false),\n      currentPage: signal(1),\n      currentLimit: signal(15),\n      totalRecords: signal(0),\n      loadedData: signal(defaultData<T>()),\n      predicate: mergedOptions.predicate ?? signal(true),\n      queryParamsFromUser: signal<Record<string, string | number | boolean>>(\n        mergedOptions.queryParams\n      ),\n      postRequestBodyFromLazyLoad: signal<any>(null),\n      queryParamsFromLazyLoad: signal<HttpParams | null>(null)\n    });\n\n    const finalQueryParams = computed(() => {\n      const val: Record<string, string | number | boolean> = {\n        [mergedOptions.pageQueryParamKey]: internalState.currentPage(),\n        [mergedOptions.limitQueryParamKey]: internalState.currentLimit(),\n        ...cleanNullishFromObject(internalState.queryParamsFromUser()),\n        ...cleanNullishFromObject(internalState.queryParamsFromLazyLoad() ?? {})\n      };\n\n      return val;\n    });\n\n    effect(() => {\n      const predicate = internalState.predicate();\n      untracked(() => {\n        if (!predicate) {\n          internalState.apiCallAbortNotifier.next();\n        }\n      });\n    });\n\n    destroyRef.onDestroy(() => {\n      if (!internalState.apiCallNotification.closed) {\n        internalState.apiCallNotification.complete();\n      }\n\n      if (!internalState.apiCallAbortNotifier.closed) {\n        internalState.apiCallAbortNotifier.next();\n        internalState.apiCallAbortNotifier.complete();\n      }\n    });\n\n    const loadDataFromApi = () => {\n      const apiUrl = isSignal(url) ? url() : url;\n      let req: Observable<Object>;\n\n      switch (mergedOptions.requestMethod) {\n        case \"GET\":\n          req = defer(() => {\n            internalState.isLoading.set(true);\n            return http.get(apiUrl, {\n              params: { ...finalQueryParams() },\n              context: mergedOptions.httpContext.set(\n                OffsetPaginatedPrimeNgTableStateNetworkRequest,\n                true\n              )\n            });\n          });\n          break;\n\n        case \"POST\":\n          req = defer(() => {\n            internalState.isLoading.set(true);\n            return http.post(apiUrl, internalState.postRequestBodyFromLazyLoad(), {\n              params: { ...finalQueryParams() },\n              context: mergedOptions.httpContext.set(\n                OffsetPaginatedPrimeNgTableStateNetworkRequest,\n                true\n              )\n            });\n          });\n          break;\n\n        default:\n          throw new Error(\"Invalid/unsupported request method\");\n      }\n\n      return req.pipe(\n        switchMap((rawData: any) => {\n          if (!isValidData(mergedOptions.dataArrayKey, mergedOptions.totalDataCountKey, rawData)) {\n            throw new Error(\n              `The response body must be an object. Valid example: { ${mergedOptions.dataArrayKey}: [], ${mergedOptions.totalDataCountKey}: 0 }`\n            );\n          }\n\n          const dataInContainer: DataContainer<T> = {\n            payload: rawData[mergedOptions.dataArrayKey] ?? [],\n            totalCount: rawData[mergedOptions.totalDataCountKey] ?? 0\n          };\n\n          return of(dataInContainer);\n        }),\n        catchError((error) => {\n          if (mergedOptions.onError) {\n            try {\n              mergedOptions.onError(error);\n            } catch (errorFromHandler) {\n              console.warn(\n                \"Exception in onError is handled internally to keep observable running.\",\n                errorFromHandler\n              );\n            }\n          }\n          console.error(error);\n          return of(null);\n        }),\n        finalize(() => internalState.isLoading.set(false)),\n        takeUntil(internalState.apiCallAbortNotifier)\n      );\n    };\n\n    const handleApiResponse = (newData: DataContainer<T>) => {\n      internalState.loadedData.set({\n        payload: newData.payload,\n        totalCount: newData.totalCount\n      } satisfies DataContainer<T>);\n\n      internalState.totalRecords.set(newData.totalCount);\n    };\n\n    internalState.apiCallNotification\n      .pipe(\n        switchMap(() => {\n          if (internalState.isLoading()) {\n            return of(null);\n          } else if (!internalState.predicate()) {\n            return of(defaultData<T>());\n          } else {\n            return loadDataFromApi();\n          }\n        }),\n        filter((val) => val !== null),\n        takeUntilDestroyed(destroyRef)\n      )\n      .subscribe((data) => {\n        handleApiResponse(data);\n      });\n\n    return Object.seal({\n      queryParams: finalQueryParams,\n      predicate: internalState.predicate,\n      totalRecords: internalState.totalRecords.asReadonly(),\n      data: computed(() => {\n        return internalState.loadedData().payload;\n      }),\n      isLoading: internalState.isLoading.asReadonly(),\n      onLazyLoad(event: TableLazyLoadEvent) {\n        const offset = event.first || 0;\n        const limit = event.rows || 15;\n        const currentPage = Math.floor(offset / limit) + 1;\n\n        internalState.currentPage.set(currentPage);\n        internalState.currentLimit.set(limit);\n\n        if (mergedOptions.filterAndSortHandler) {\n          const handledResult = mergedOptions.filterAndSortHandler(event);\n          if (handledResult instanceof HttpParams) {\n            internalState.queryParamsFromLazyLoad.set(handledResult);\n          } else if (handledResult instanceof PostRequestBody) {\n            internalState.postRequestBodyFromLazyLoad.set(handledResult.payload);\n          }\n        }\n\n        internalState.apiCallNotification.next();\n      },\n\n      patchQueryParams(value: Record<string, string | number | boolean>) {\n        const newValue = { ...value };\n\n        Object.keys(newValue).forEach((key) => {\n          if (blackListedQueryKeys.includes(key.toLowerCase())) {\n            delete newValue[key];\n          }\n        });\n\n        if (Object.keys(newValue).length > 0) {\n          internalState.queryParamsFromUser.update((currentValue) => {\n            return {\n              ...currentValue,\n              ...newValue\n            };\n          });\n        }\n\n        return this;\n      },\n      removeQueryParam(key: string) {\n        internalState.queryParamsFromUser.update((currentValue) => {\n          const { [key]: _, ...rest } = currentValue;\n          return rest;\n        });\n        return this;\n      },\n      removeAllQueryParams() {\n        internalState.queryParamsFromUser.set({});\n        return this;\n      }\n    });\n  });\n}\n\nexport const UrlBasedDynamicQuery = {\n  Contains: \"con\",\n  NotContains: \"ntcon\",\n  StartsWith: \"sw\",\n  NotStartsWith: \"ntsw\",\n  EndsWith: \"ew\",\n  NotEndsWith: \"ntew\",\n  Equal: \"eq\",\n  NotEquals: \"nteq\",\n  GreaterThan: \"gt\",\n  GreaterThanEqual: \"gte\",\n  LessThan: \"lt\",\n  LessThanEqual: \"lte\"\n} as const;\n\ninterface FilterDto {\n  field: string;\n  type: string;\n  value: string;\n}\n\ninterface SortDto {\n  field: string;\n  isDesc: boolean;\n  serial: number;\n}\n\ninterface DynamicQueryRequest {\n  filters: FilterDto[];\n  sorts: SortDto[];\n}\n\nfunction evaluateFilter(input: string): string | null {\n  const filterMap: Record<string, string> = {\n    startsWith: UrlBasedDynamicQuery.StartsWith,\n    notStartsWith: UrlBasedDynamicQuery.NotStartsWith,\n    endsWith: UrlBasedDynamicQuery.EndsWith,\n    notEndsWith: UrlBasedDynamicQuery.NotEndsWith,\n    contains: UrlBasedDynamicQuery.Contains,\n    notContains: UrlBasedDynamicQuery.NotContains,\n    equals: UrlBasedDynamicQuery.Equal,\n    notEquals: UrlBasedDynamicQuery.NotEquals,\n    greaterThan: UrlBasedDynamicQuery.GreaterThan,\n    lessThan: UrlBasedDynamicQuery.LessThan,\n    greaterThanOrEqual: UrlBasedDynamicQuery.GreaterThanEqual,\n    lessThanOrEqual: UrlBasedDynamicQuery.LessThanEqual\n  };\n\n  return filterMap[input] || null;\n}\n\nfunction extractMeta(dto: LazyLoadMeta): DynamicQueryRequest {\n  const filters: FilterDto[] = [];\n  const sorts: SortDto[] = [];\n\n  // Process filters\n  if (dto.filters) {\n    for (const [field, filterData] of Object.entries(dto.filters)) {\n      if (!filterData) {\n        continue;\n      }\n\n      // Handle both single filter and array of filters\n      const filterArray = Array.isArray(filterData) ? filterData : [filterData];\n\n      filterArray.forEach((filter) => {\n        if (\n          !filter.matchMode ||\n          filter.value === null ||\n          filter.value === undefined ||\n          filter.value === \"\"\n        ) {\n          return;\n        }\n\n        const filterType = evaluateFilter(filter.matchMode);\n\n        if (filterType) {\n          filters.push({\n            field,\n            type: filterType,\n            value: String(filter.value)\n          });\n        }\n      });\n    }\n  }\n\n  // Process sorting\n  if (dto.multiSortMeta && dto.multiSortMeta.length > 0) {\n    dto.multiSortMeta.forEach((sort, index) => {\n      sorts.push({\n        field: sort.field,\n        isDesc: sort.order === 1 ? false : true,\n        serial: index + 1\n      });\n    });\n  } else if (dto.sortField && dto.sortOrder) {\n    // Handle single column sort\n    const field = Array.isArray(dto.sortField) ? dto.sortField[0] : dto.sortField;\n    sorts.push({\n      field,\n      isDesc: dto.sortOrder === 1 ? false : true,\n      serial: 1\n    });\n  }\n\n  return { filters, sorts };\n}\n\nconst DynamicUrlBuilder: FilterAndSortFn = (meta: LazyLoadMeta): HttpParams => {\n  const dto = extractMeta(meta);\n  const usp = new HttpParams();\n\n  dto.filters.forEach((item) => {\n    const paramKey = `${item.field}__${item.type}`;\n    usp.append(paramKey, item.value);\n  });\n\n  dto.sorts.forEach((item) => {\n    const paramKey = `$sort__${item.serial}__${item.isDesc ? \"desc\" : \"asc\"}`;\n    usp.append(paramKey, item.field);\n  });\n\n  return usp;\n};\n"],"mappings":"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","names":["ManipulationType","filter","HttpContext","signal","patchState","signalState","firstValueFrom","signalState","signal","patchState","firstValueFrom","HttpContext","signal","HttpContext","firstValueFrom","signal","firstValueFrom","HttpContext","signal","signal","computed","signal","HttpClient","HttpContext","signal","signal","HttpContext","HttpClient","HttpClient","HttpContext","HttpContextToken","assertInInjectionContext","computed","DestroyRef","inject","Injector","runInInjectionContext","signal","catchError","debounceTime","finalize","of","Subject","switchMap","tap","HttpContextToken","defaultResetOpts","assertInInjectionContext","inject","Injector","runInInjectionContext","DestroyRef","HttpClient","Subject","HttpContext","signal","computed","options","of","switchMap","tap","catchError","finalize","debounceTime","assertInInjectionContext","DestroyRef","inject","Injector","runInInjectionContext","takeUntilDestroyed","toObservable","takeUntilDestroyed","assertInInjectionContext","inject","Injector","runInInjectionContext","DestroyRef","toObservable","elem","HttpClient","HttpContext","HttpContextToken","HttpParams","assertInInjectionContext","computed","DestroyRef","inject","InjectionToken","Injector","isDevMode","isSignal","runInInjectionContext","signal","takeUntilDestroyed","catchError","defer","filter","finalize","of","Subject","switchMap","takeUntil","HttpContextToken","optionsWithDefaultValue","InjectionToken","isValidData","defaultData","isDevMode","assertInInjectionContext","inject","Injector","runInInjectionContext","HttpClient","DestroyRef","HttpContext","Subject","signal","computed","isSignal","defer","switchMap","of","catchError","finalize","takeUntil","filter","takeUntilDestroyed","HttpParams"]}