DictManager — Dictionary Request and Cache Manager

website·Indexed 31 days ago

https://dict-manager.vercel.app

A high-performance tool for dictionary data request merging, caching, retries, degradation, and LRU management. It is designed for backend configuration dictionaries, status enumerations, and option lists. The ecosystem includes @anyfu/dict-core for native JavaScript/TypeScript usage and @anyfu/dict-vue for Vue Hooks integration.

Tokens
6.8K
Snippets
46
Records
53
Agent score
75%

What's inside DictManager

  1. Overview of @anyfu/dict-core capabilities

    @anyfu/dict-core is a high-performance utility designed for managing dictionary data requests, specifically for scenarios like backend configuration dictionaries, status enumerations, and option lists. It provides the following core capabilities:

    • Request Merging: Automatically merges multiple dictionary requests within a mergeDelay window into a single HTTP request.
    • LRU Caching: Supports a maximum number of cache entries with Least Recently Used (LRU) eviction.
    • Expiration Control: Uses cacheTime to manage cache expiration.
    • SWR Mode: Stale-While-Revalidate; returns old data first while refreshing in the background.
    • Fallback/Degradation: Automatically falls back to cached data if a request fails.
    • Automatic Retries: Supports failure retries with customizable retry conditions.
    • Request Cancellation: Ability to cancel pending or in-flight requests.
    • Interceptors: Supports both request and response interceptors.
    • Custom Parsing: Allows customization of response structures and dictionary parsing logic.
  2. Understand the @anyfu/dict-vue architecture

    The dictionary hooks are structured in three layers:

    1. Core Layer: createDictManager handles the base logic.
    2. Plugin Layer: setupDictPlugin handles global configuration and namespaces.
    3. Hook Layer: useDict utilizes useDictManager to create a manager instance, which allows for overriding global configuration options.
  3. Optimize dictionary data fetching via request merging

    The system automatically merges multiple dictionary data requests occurring within a specific merge window into a single request. This mechanism reduces the total number of network requests sent to the server.
  4. Initialize and use DictManager for dictionary requests

    DictManager handles the fetching of dictionary data with built-in support for merging multiple requests into a single HTTP call and caching results. Use createDictManager to initialize the manager and fetchDict to retrieve specific dictionary codes.
    const dictManager = createDictManager<TDict, TResponse>({
      url: '/api/dict/base',
    });
    
    // Fetch a single dictionary
    await dictManager.fetchDict('DICT_ONE');
    
    // Fetch multiple dictionaries (will be merged if within mergeDelay)
    await dictManager.fetchDict('DICT_ONE', 'DICT_SECOND');
  5. Fetch dictionaries using a specific namespace

    To fetch dictionary data from a non-default source, pass the namespace option to the useDict hook. This ensures the request uses the configuration associated with that namespace defined during plugin setup.
    // Use 'as const' to ensure the array is treated as a readonly tuple
    const codes = ['DICT_STYLES', 'DICT_REASON'] as const;
    
    const { loading, data, dictMap } = useDict(codes, { namespace: 'external' });
    console.info(loading, data, dictMap);
  6. Define custom retry conditions using retryOn

    By default, the dictionary manager only retries requests that result in HTTP status codes 5xx or 429. To expand this behavior (for example, to include 404 or 405 errors), provide a custom retryOn function that returns true when the error meets your specific criteria.
  7. Configure DictManager request and interceptor settings

    DictManager allows customization of the HTTP request behavior, including the method, headers, and how to parse the response to extract dictionary data.
    const dictManager = createDictManager({
      url: '/api/dict/base',
      method: 'post', // Default: 'post'
      fieldName: 'codes', // Field name used to send dictionary codes
      dictCodeKey: 'dictCode', // Field name identifying the dictionary code in the response
      requestFn: customFetchFn, // Custom request function (e.g., axios)
      requestInterceptor: (config) => { /* ... */ },
      responseInterceptor: (res) => { /* ... */ },
      isSuccess: (res) => res && res.success !== false, // Success validation
      parseResponseData: (res) => res.data, // Extract dictionary list from response
      parseDict: (dictList, code, codeKey) => dictList.find(it => it[codeKey] === code) // Extract specific dict by code
    });
  8. Initialize a dictionary manager with createDictManager

    Use createDictManager to configure the base URL and endpoint for dictionary data fetching. Once initialized, you can use the fetchDict method to retrieve specific dictionary data by its code.
    import { createDictManager } from '@anyfu/dict-core';
    
    const dictManager = createDictManager({
      baseURL: 'https://useful-event-b654f7bc61.strapiapp.com',
      url: '/api/dict/base',
    });
    
    const res = await dictManager.fetchDict('DICT_FIRST');
    console.log('DICT_FIRST', res);
  9. Manually trigger dictionary data fetching

    By default, useDict automatically initiates a request. To prevent this and fetch data manually at a specific time, set the immediate option to false and call the returned load method.
    <script lang="tsx" setup>
    const code = 'DICT_FIRST';
    const { loading, data, dictMap, load } = useDict(code, {
      immediate: false,
    });
    </script>
    
    <template>
      <ElButton type="primary" @click="load">获取字典</ElButton>
    </template>