npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@qqsl/qqsl-utils

v0.0.13

Published

这个库是一个纯工具库,为业务的不同部分提供相应的工具方法。 src目录下的每一个子目录都是独立的一部分,子目录中既有工具方法的实现,也有对应的单元测试。 再次开发时也应以此为准

Readme

QqslUtils

这个库是一个纯工具库,为业务的不同部分提供相应的工具方法。 src目录下的每一个子目录都是独立的一部分,子目录中既有工具方法的实现,也有对应的单元测试。 再次开发时也应以此为准

更新历史

0.0.10

  1. MapboxGeoJsonSource新增配置项sourceOptions?: mapboxgl.GeoJSONSourceOptions。可用来配置promoteId等属性

0.0.9

  1. 新增装饰器AutoUpdate和工具函数AutoBatch

0.0.8

  1. fix bugs

0.0.7

  1. 修改创建气泡时参数online为onPoint
  2. 新增工具函数centerAndZoom
// 当指定zoom时,如果当前zoom小于指定zoom,则不设置zoom。
// 该方法可在地图实例化之前调用,会等待地图实例化完成,如果在地图实例化之前多次调用,则只触发最后一次。
centerAndZoom(coors: [number, number], zoom?: number): void

0.0.6

  1. 若气泡由地图创建,则当静态气泡打开时,默认禁止打开临时气泡。(对应方法修改如下)
createTemporaryPop<T>(
    createContent: (data: T) => HTMLElement | string,
    onPoint = false,
    disabledWhenStaticPopActived = true // 当静态气泡激活时,是否禁止临时气泡
  ):TemporaryPopControl<T>

0.0.5

  1. 修复filter新旧语法在cluster中不兼容的问题
  2. 修复气泡未打开时,调用close报错

0.0.4

  1. 支持在将气泡绑定至图层时(调用bingPopControl)的时候,指定参数update、destroy,来配置气泡的同步行为。(update为true则会自动更新气泡,destroy为true则会自动关闭气泡)

0.0.3

  1. 向外暴露函数isNormalAreaMapPaint,该函数用于判断样式配置是否是pattern
  2. 新增函数getAreaConfig,用于用户自己便捷构建面图层配置,该函数返回AutoCreatedFillpaintConfig,如果面配置为pattern,则返回值中包含fill-pattern,否则返回值包含fill-color
  3. 修复面图层数据未与自动边界outline绑定
  4. 修复面图层修改visiblity后未同步至自动边界的visibility

0.0.2

  1. MapboxGeoJsonSource支持传入Observable<mapboxgl.Map>作为参数,异步初始化数据源
  2. BaseMapLayer.bindPopControl 支持气泡与图层绑定,当图层所依赖的数据源变化时,自动对比该气泡与新的数据源,如果气泡所依赖的数据项被移除,则自动关闭气泡。由于数据对比是通过features里的properties,所以请确保properties中可以取得对应的用来与气泡对比的唯一值

目录结构

- src
  -- mapbox-utils // mapbox相关的工具方法
  -- store // 配合Store使用的相关工具
  // 其他。。。

mapbox-utils相关方法介绍

该目录下主要包含:

  1. 针对mapbox地图初始化与地图实例控制的类( MapboxControl )
  2. 针对mapbox数据源初始化与控制的类 ( MapboxGeoJsonSource )
  3. 针对不同类型图层初始化与控制的类 ( BaseMapLayer、PointMapLayer、PointClusterMapLayer、LineMapLayer、FillMapLayer )
  4. 针对不同类型气泡的控制类(StaticPopControl、TemporaryPopControl、PopControl)
  5. 辅助控制图层的相关类 (LayerGather、LayerGroup、LayerArray)
  6. 特殊情境下控制气泡的相关类 (raceFactory)

MapboxControl

useNotes
class App {
  constructor(){
    // tianToken天地图token,scale是否开启
    this.mapControl = new MapboxControl(tianToken, { scale: true })
  }
}

MapboxControl的实例上的方法:

  1. mapLoad。请使用该方法作为mapbox的load的回调,并将地图实例作为参数
  2. centerAndZoom。使用该方法进行定位和缩放,如果当前缩放比例大于指定值,则不会缩放
  3. createStaticPop。构建一个静态气泡并返回。可以多次调用该方法创建多个静态气泡,MapboxControl会控制这些气泡保证每次只能有一个开启
  4. createTemporaryPop。构建一个动态气泡并返回。其他同上
  5. connectQueue。用于批量绑定数据源和图层。为connect的变种。
  6. connect。单次绑定数据源和图层。params:source,layer,index。第三个参数index为指定图层的层级,理解为zIndex即可
  7. 除此之外还有一些内部方法,如需了解,自行查看源码

图层相关类介绍:BaseMapLayer、PointMapLayer、PointClusterMapLayer、LineMapLayer、FillMapLayer

// 该类为其他图层类的基类,如下的属性与方法基本涵盖了使用所需。除此之外,还有一些内部方法未在下方展示,有需要可以查看源码
interface class BaseMapLayer{
  // 由该类自行生成的递增id
  id: string
  // 由用户在初始化时传入的别名,用于
  alias?: string
  constructor(
    options:{
      layer?: LayerConfig, // 图层配置
      alias?: string // 别名
    },
    dynamicConfig: {
      // 是否动态配置图层属性
      isDynamic: boolean,
      // 每个feature的property中标识其样式类型的字段
      typeKey?: string,
      // 如果typeKey不满足需求,通过该回调函数返回每一个feature对应的type
      typeCreater?(p: P): string,
      // 最终通过filter对比type时,需要将原数据的type和代码设置动态样式配置时提供的type相对比。
      // 例如,数据源中有一个数据,{ type: 'old' };与其相匹配的样式类型为{ type: 'newOld' }
      // 本着尽量不修改原数据的原则,尽管我们通过typeCreater,从'old'转换出了"newOld",从而获取到了真实的样式配置。但是在filter中对比时,仍然需要将"newOld"通过typeTransformer转换为"old"
      typeTransformer?(type: string): string,
      // 用户提供的获取图层配置的方法
      getConfig?: (type: string) => Observable<GeometryStyleConfig|undefined>
    } = { isDynamic: false }
  ){}

  /**
   * @description 将静态气泡绑定至图层, 如果图层元素有显示或隐藏的变化,将同步修改气泡的显隐性。
   * @param staticPop 静态气泡实例
   * @param force boolean 是否强制绑定
   */
  bindPopControl(staticPop: StaticPopControl<any>, force = false):void
  setFilter(filter: any[] | null):void
  setLayoutProperty(paint: { [key: string]: any }):void
  setPaintProperty(paint: { [key: string]: any }):void
  resetLayerStyle():void
  // 在地图上移除当前图层,并在数据源中清理该图层
  removeSelf():void

  on<T extends keyof mapboxgl.MapLayerEventType>(
    type: T,
    listener: (ev: mapboxgl.MapLayerEventType[T] & mapboxgl.EventData) => void,
    // 是否禁止点击穿透
    onlySelf = false,
    interceptor?: (e: mapboxgl.MapLayerEventType[T] & mapboxgl.EventData) => boolean | Observable<boolean>
  ):void

  off<T extends keyof mapboxgl.MapLayerEventType>(
    type: T,
  ): void

  once<T extends keyof mapboxgl.MapLayerEventType>(
    type: T,
    listener: (ev: mapboxgl.MapLayerEventType[T] & mapboxgl.EventData) => void,
  ):void
}
useNotes
class App {
  constructor(){
    // 不需要动态配置时,自己指定图层的layout与paint配置
    this.pointLayerControl = new PointMapLayer(
      {
        layer: {
          layout: {
            'icon-image': 'icon1'
          }
        },
        alias: '业务图层别名'
      }
    )
    // 启用动态配置
    this.pointLayerControl = new PointMapLayer(
      {
        alias: '业务图层别名'
      },
      {
        isDynamic: true,
        typeKey: 'type',
        getConfig: someFunction //...函数
      }
    )
    // 如果想要启用聚合,将PointMapLayer替换为PointClusterMapLayer即可。并且对应的数据源也需要开启cluster

  }
}

MapboxGeoJsonSource

useNotes
class App {
  constructor(){
    this.sourceControl = new MapboxGeoJsonSource(
      {
        mapApi: api // 或者api$ 即Observable<api>,
        alias: '业务别名',
        sourceOptions: {} // 其他配置,如promoteId
      },
      true // 该数据源开启了聚合
    )
    // 更新数据
    this.sourceControl.setData(data)

    // 注意,在完成数据源和图层的初始化后,需要调用mapboxControl上的connect或connectQueue方法将将二者绑定
    this.mapboxControl.connect(this.sourceControl, this.layerControl, 1)
  }
}

气泡相关类介绍

useNotes

const pop = new StaticPopControl(
  mapApi$: api$,
  createContent: someFunction, // 用于构建气泡内容,返回字符串或者dom
  true, // 气泡在线上还是点上,线上为true,默认为false
  {
    key: 'id' // 提供key用于打开该气泡的数据的唯一标识。或者使用keySelector,动态构建id
  }
)
pop.show(data)
pop.close()
pop.update(newData) // 更新气泡,内部会通过新旧数据的id判断是否更新
pop.close('id1') // 关闭指定id的气泡

其他工具类

  1. 批量管理图层:LayerGather、LayerGroup、LayerArray
  2. 异步方法动态竞争:raceFactory
  3. 数据源数据构建:createPointFeatures、createMultiPointFeeatures、createHashLineFeatures、createHashMultiLineFeatures、createHashAreaFeatures、createHashMultiAreaFeatures

const layerGroup1 = new LayerGroup()
// 添加layer不需要指定key
layerGroup1.addTo(
  layer1
)

const layerGroup2 = new LayerGroup()
// LayerGroup、LayerArray可以互相嵌套,必须指定key
layerGroup2.addTo(layerGroup1, 'group1')

// 可以通过这种方式批量地操作图层
layerGroup2.setFilter(filters)

// raceFactory接收一个回调函数作为参数,可以在race上push可观察对象,每当当前队列中有可观察对象返回时,该回调被调用。其他可观察对象被取消,队列清空。
const race = raceFactory((v) => console.log(v))

const after100ms$ = new Observable(function(next){
  setTimeout(function(){
    next('100ms')
  }, 100)
})

// 最终会仅打印出100ms
race.push(after100ms$)
race.push(after200ms$)
race.push(after300ms$)

store

  1. 装饰器AutoUpdate

与Store中的装饰器Action连用,自动将返回内容更新至store实例当中


class A extends Store<{ a: number }>{

  constructor(){
    super({ a: 1 })
  }

  // 会自动同步返回的store中的a。当然,也可以返回一个简单对象,而非Observable
  @Autoupdate()
  @Action()
  exampleA(): Observable<{ a: string }> {
    return of({ a: 2 })
  }

}

2. 工具函数AutoBatch
与被AutoUpdate装饰的函数配合使用,将多个函数批量顺序调用,并将每个函数返回的store顺序合并,最终构建一个新的store并更新至实例

````.js

class AStore extends Store<{ a: number, b: number }>{

  constructor(){
    super({ a: 1, b: 5 })
  }

  // 会自动同步返回的store中的a。当然,也可以返回一个简单对象,而非Observable
  // 特别注意:使用Autoupdate装饰的函数最终的返回值应当是{ store: any, payload: any }, 其中store代表要更新的内容,payload为其他任意参数,例如,请求回来的信息
  @Autoupdate()
  @Action()
  exampleA(): Observable<{ store: any, paylaod: any}> {
    return of({ store: { a: 2 }, payload: { message: 'success' } })
  }

  @Autoupdate()
  @Action()
  exampleA(): Observable<{ store: any, paylaod: any }> {
    return of({ store: { b: 3 }, payload: { message: 'success' } })
  }

}

class BComponent{
  constructor(
    private store: AStore
  ){

  }
  doSomething(){
    // 特别注意:这里需要对函数作this的绑定
    AutoBatch([store.exampleA.bind(store), store.exampleA.bind(store)]).subscribe(res => {
      // res 这里的res是每一个函数的返回值构成的数组,顺序与函数调用顺序相同
    })
  }
}