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 🙏

© 2026 – Pkg Stats / Ryan Hefner

gs-search

v0.1.8

Published

可以在现代浏览器运行,且会自动存储索引的极小纯前端搜索库,可以配合其它强大的分词库使用效果更好

Readme

gs-search

可以在现代浏览器运行,且会自动存储索引的极小纯前端搜索库,可以配合其它强大的分词库使用效果更好

其他语言

特性

  • 🔍 全文搜索 支持多语言分词
  • 📦 轻量级 无任何第三方依赖,体积小
  • 高性能 快速搜索与索引构建
  • 📱 浏览器兼容 支持现代浏览器
  • 🗄️ 自定义存储 支持灵活的存储实现
  • 📊 批处理操作 批量添加文档更高效

安装

# 使用yarn
yarn add gs-search

# 使用npm
npm install gs-search

快速开始

import { SimpleSearch } from 'gs-search';

// 批量添加文档
await SimpleSearch.addDocuments([
  { id: 1, text: 'Hello world!' },
  { id: 2, text: '这是一个测试文档' },
  { id: 3, text: '另一个用于测试的文档' }
]);

// 添加单个文档
await SimpleSearch.addDocument({ id: 4, text: '单个文档添加示例' });

// 搜索
const results = await SimpleSearch.search('测试');
console.log(results);
// 输出: [{ id: 2, score: 1.5, tokens: ['测试'] }, { id: 3, score: 1.5, tokens: ['测试'] }]

// 删除文档
await SimpleSearch.removeDocument(1);

// 获取搜索引擎状态
const status = await SimpleSearch.getStatus();
console.log(status);

高级用法

SearchEngine

如需更多控制和高级功能,可以使用 SearchEngine

import { SearchEngine, NodeStorage } from 'gs-search';

// 创建带有自定义存储的引擎
const engine = new SearchEngine({
  storage: new NodeStorage('./search-data')
});

// 初始化引擎
await engine.init();

// 批处理添加文档
await engine.startBatch();
try {
  await engine.addDocuments([
    // ... 文档
  ]);
} catch (error) {
  // 处理错误
} finally {
  // 始终结束批处理以确保索引正确重建
  await engine.endBatch();
}

自定义存储

您可以实现自定义存储来持久化数据:

import { StorageInterface } from 'gs-search';

class CustomStorage implements StorageInterface {
  async saveIndex(index: any): Promise<void> {
    // 保存索引到自定义存储
  }

  async loadIndex(): Promise<any | null> {
    // 从自定义存储加载索引
    return null;
  }

  async clear(): Promise<void> {
    // 清空存储
  }
}

// 使用自定义存储
const storage = new CustomStorage();
const engine = new SearchEngine({ storage });

批处理操作

使用批处理操作进行高效的文档索引:

// 开始批处理操作
await engine.startBatch();

try {
  // 批量添加文档
  for (let i = 0; i < 1000; i++) {
    await engine.addDocuments([{ id: i, text: `文档 ${i}` }]);
  }
} catch (error) {
  // 处理错误
  console.error('批处理操作失败:', error);
} finally {
  // 无论是否发生错误,都必须结束批处理以确保索引正常重建
  await engine.endBatch();
}

自定义分词器

支持完整文档对象的分词器

您可以通过配置自定义分词器来支持特定的语言或分词需求。分词器可以访问完整的文档对象,让您能够基于文档的多个属性进行分词:

import { SearchEngine } from 'gs-search';

// 自定义索引分词器:使用文档的text和category字段进行分词
const indexingTokenizer = (doc: { id: string; text: string; category: string; author: string }): string[] => {
  // 可以访问文档的所有属性
  const fullText = `${doc.text} ${doc.category} ${doc.author}`;
  return fullText.toLowerCase().split(/\s+/);
};

// 自定义搜索分词器:支持搜索上下文
const searchTokenizer = (query: { text: string; language?: string; context?: string }): string[] => {
  // 可以根据查询的语言或上下文调整分词
  const tokens = query.text.toLowerCase().split(/\s+/);
  // 根据上下文添加额外的搜索词
  if (query.context === 'technical') {
    tokens.push('technical');
  }
  return tokens;
};

// 创建引擎并配置自定义分词器
const engine = new SearchEngine({
  baseDir: 'search-data',
  indexingTokenizer,
  searchTokenizer
});

// 索引包含额外属性的文档
await engine.addDocument({
  id: '1',
  text: '这是一个技术文档',
  category: '技术',
  author: '张三'
});

// 使用包含上下文的查询进行搜索
const results = await engine.search({
  text: '技术',
  language: 'zh',
  context: 'technical'
});

简单的字符/空格分词器

以下是一个简单的正则分词器示例,按空格和字符分词,且最长token不超过5字符:

import { SimpleSearch } from 'gs-search';

// 自定义分词器:按空格和字符分词,最长token不超过5字符
const customTokenizer = (text: string): string[] => {
  // 按空格分词
  const tokens: string[] = [];
  const words = text.toLowerCase().split(/\s+/);
  
  // 对每个单词,按字符切分,最长不超过5字符
  for (const word of words) {
    if (word.length <= 5) {
      tokens.push(word);
    } else {
      // 超过5字符的单词按字符切分
      for (let i = 0; i < word.length; i++) {
        tokens.push(word[i]);
      }
    }
  }
  
  return tokens;
};

// 配置自定义分词器
SimpleSearch.configure({
  indexingTokenizer: customTokenizer,
  searchTokenizer: customTokenizer
});

API参考

SimpleSearch

静态方法(无需实例创建):

  • configure(config: Partial<ISearchEngineOption>): void: 配置搜索引擎
  • addDocument(doc: IDocument): Promise<void>: 添加单个文档
  • addDocuments(docs: IDocument[]): Promise<void>: 添加多个文档
  • addDocumentIfMissing(doc: IDocument): Promise<void>: 如果文档不存在则添加单个文档
  • addDocumentsIfMissing(docs: IDocument[]): Promise<void>: 添加多个文档,跳过已存在的文档
  • removeDocument(id: number): Promise<void>: 删除文档
  • search(query: string, limit?: number): Promise<IResult[]>: 搜索文档
  • getStatus(): Promise<IStatus>: 获取搜索引擎状态
  • hasDocument(id: number): Promise<boolean>: 检查文档ID是否曾经添加过(包括已删除的)
  • startBatch(): void: 开始批量操作
  • endBatch(): Promise<void>: 结束批处理操作

SearchEngine

  • constructor(options: ISearchEngineOption): 创建一个新的核心引擎实例
  • init(): Promise<void>: 初始化引擎
  • addDocument(doc: IDocument): Promise<void>: 添加单个文档
  • addDocuments(docs: IDocument[]): Promise<void>: 添加多个文档
  • addDocumentIfMissing(doc: IDocument): Promise<void>: 如果文档不存在则添加单个文档
  • addDocumentsIfMissing(docs: IDocument[]): Promise<void>: 添加多个文档,跳过已存在的文档
  • removeDocument(id: number): Promise<void>: 删除文档
  • search(query: string, limit?: number): Promise<IResult[]>: 搜索文档
  • getStatus(): Promise<IStatus>: 获取搜索引擎状态
  • startBatch(): void: 开始批处理
  • endBatch(): Promise<void>: 结束批处理

存储支持

gs-search支持多种存储方式:

  • InMemoryStorage:内存存储(默认)
  • LocalStorage:浏览器本地存储
  • IndexedDBStorage:浏览器IndexedDB存储
  • 自定义存储:实现StorageInterface接口

浏览器支持

  • Chrome (最新)
  • Firefox (最新)
  • Safari (最新)
  • Edge (最新)

许可证

MIT License

贡献

欢迎贡献代码!请查看GitHub仓库了解更多信息。

联系方式