vunk-shared

website·Indexed 30 days ago

https://eralchen.github.io/vunk-shared

A collection of shared utilities and types covering TypeScript morphing, Vite plugins, Vike Vue integration, UnoCSS settings, and general-purpose object and string manipulation helpers.

Tokens
32.9K
Snippets
213
Records
220
Agent score
75%

What's inside vunk-shared

  1. Use DemoContainer to display Vue examples in Markdown

    The DemoContainer component (provided by demoContainerPlugin) is used to render Vue code examples. In markdown files, it can be invoked using the :::demo custom container. The syntax allows specifying the path to the demo index and optional sub-sources.
    :::demo
    DemoContainer/basic/index
    >>>subs
    [custom-check-tree/data]
    >>>
    :::
  2. Manage linked list data structures with manageLinkedList

    The manageLinkedList function from @vunk/shared/data/link is used to process and manage data structured as a linked list. It takes an array of nodes (where each node typically contains an id and a nextId) and returns a processed data structure. This is useful for resolving sequences or chains of related items in a dataset.
    <script lang="ts" setup>
    import { LinkedNode } from '@vunk/shared/types'
    import { computed, ref } from 'vue'
    import { manageLinkedList } from '@vunk/shared/data/link'
    
    // Define a list of nodes where each node points to the next via nextId
    const list = ref(
      [
        { id: '3', nextId: '4' },
        { id: '4', nextId: '1' },
        { id: '1', nextId: '2' },
        { id: '2', nextId: '3' },
        { id: '5', nextId: '6' },
        { id: '6', nextId: '7' },
        { id: '7', nextId: '' },
      ] as LinkedNode[],
    )
    
    // Use manageLinkedList to resolve the linked structure
    const links = computed(() => {
      const { data } = manageLinkedList(list.value)
      return data
    })
    </script>
    
    <template>
      <div>{{ links }}</div>
    </template>
  3. Install @vunk/shared utility library

    @vunk/shared is a comprehensive JavaScript utility library. It is organized by category to allow for tree-shaking; you can import only the specific functions you need to keep your bundle size small.
    pnpm install @vunk/shared
  4. Use scriptSetupRE to match Vue script setup blocks

    The scriptSetupRE regular expression is used to identify <script setup> blocks within HTML strings. It captures the attributes before and after the setup keyword, as well as the inner code content of the script block. It is designed to handle multi-line content and case-insensitive/global matching via the mg flags.
    export const scriptSetupRE = /<\s*script([^>]*)\bsetup\b([^>]*)>([\s\S]*)<\/script>/mg
  5. Convert spatial files to GeoJSON using fileToGeojson

    The fileToGeojson function converts a file object (such as a .shp or .dxf file) into a GeoJSON FeatureCollection object. Because it relies on GDAL, you must first configure the gdalConfig.paths with the correct URLs for the GDAL WebAssembly data, WASM binary, and JS worker files.
    import { fileToGeojson, gdalConfig } from '@vunk/shared/gis/browser/gdal'
    import workerUrl from 'gdal3.js/dist/package/gdal3.js?url'
    import dataUrl from 'gdal3.js/dist/package/gdal3WebAssembly.data?url'
    import wasmUrl from 'gdal3.js/dist/package/gdal3WebAssembly.wasm?url'
    
    // 1. Configure GDAL paths (can be done in main.ts)
    gdalConfig.paths = {
      data: dataUrl,
      wasm: wasmUrl,
      js: workerUrl,
    }
    
    // 2. Convert a file to GeoJSON
    const handleFile = async (event: Event) => {
      const target = event.target as HTMLInputElement
      const file = target.files?.[0]
      if (file) {
        try {
          const geojson = await fileToGeojson(file)
          console.log('GeoJSON Result:', geojson)
        } catch (error) {
          console.error('Conversion failed:', error)
        }
      }
    }
  6. Configure success and error messages for requests

    The plugin integrates Element Plus Message components. You can enable a default success message, provide a custom success string, or define a custom error handler via onerror.
    // Enable default success prompt
    request({
      url: '/api',
      method: 'POST'
    }, {
      successMessage: true
    })
    
    // Custom success prompt text
    request({
      url: '/api',
      method: 'POST'
    }, {
      successMessage: 'Saved successfully'
    })
    
    // Custom error handling
    request({
      url: '/api',
      method: 'POST'
    }, {
      error: true,
      onerror: (err) => {
        ElMessage.error(err.message)
      }
    })
  7. Implement copy-to-clipboard for code blocks using useCopyCode

    The useCopyCode function is a built-in utility of the copyableFencePlugin. It attaches a click event listener to button.copy elements located within div elements that have a class starting with language- (e.g., div[class*="language-"] > button.copy). When the button is clicked, the associated code content is copied to the system clipboard.
    // This function is typically called within the component lifecycle 
    // to initialize the copy event listeners for code fences.
    useCopyCode();
  8. Manage request concurrency with queues

    RestFetch supports request queuing to control how multiple requests with the same queue ID are handled. There are three modes:

    1. abort: Aborts the previous request with the same ID before starting the new one.
    2. wait: Waits for the previous request with the same ID to complete.
    3. parallel: Executes requests in parallel (default behavior).
    // Abort previous request with ID 'search'
    await client.request({
      method: 'GET',
      url: '/search',
      queue: { id: 'search', mode: 'abort' }
    })
    
    // Wait for previous request with ID 'search'
    await client.request({
      method: 'GET',
      url: '/search',
      queue: { id: 'search', mode: 'wait' }
    })
  9. Extract CSS files using createCssOnlyPlugin in Rollup

    The createCssOnlyPlugin is a Rollup plugin (forked from rollup-plugin-css-only) that enables the output of CSS files from the build process. It can be configured to output a single bundled CSS file or multiple files based on the input entry points.
    import { createCssOnlyPlugin } from 'vunk-shared'; // Adjust import path based on package
    
    // In rollup.config.js
    export default {
      input: 'src/index.ts',
      plugins: [
        createCssOnlyPlugin({
          fileName: 'styles.css'
        })
      ]
    };
  10. Import required styles for createMarkdownPlugin

    To ensure the Markdown content renders correctly with the expected styling (including VitePress-like themes and Element Plus components), import the following CSS files in your main entry point.
    import 'element-plus/dist/index.css'
    import 'vitepress/dist/client/theme-default/styles/vars.css'
    import 'vitepress/dist/client/theme-default/styles/base.css'
    import 'vitepress/dist/client/theme-default/styles/icons.css'
    import 'vitepress/dist/client/theme-default/styles/components/vp-doc.css'
    import 'vitepress/dist/client/theme-default/styles/components/custom-block.css'
    import 'vitepress/dist/client/theme-default/styles/components/vp-code.css'
  11. Install and configure ElementPlusRestFetchPlugin

    The ElementPlusRestFetchPlugin integrates Element Plus Loading and Message components into RestFetch. It can be configured globally during the .use() call, such as defining a custom success condition for business responses via customOk.
    import { RestFetch } from '@vunk-shared/fetch'
    import { ElementPlusRestFetchPlugin } from '@vunk-shared/fetch/ElementPlusRestFetchPlugin'
    
    const restFetch = new RestFetch({
      baseURL: 'https://api.example.com'
    })
    
    restFetch.use(ElementPlusRestFetchPlugin, {
      customOk: res => res.code === 200 // Custom business success condition
    })