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

@howuse/feedback

v0.5.0

Published

Node.js/Electron SDK for user feedback and activation management

Readme

@howuse/feedback

Node.js/Electron SDK for user feedback and activation management.

安装

npm install @howuse/feedback

或者使用本地路径安装:

npm install ./feedback-sdk

快速开始

Node.js 示例

import { initFeedbackClient } from '@howuse/feedback';

async function main() {
  // 初始化客户端
  const client = await initFeedbackClient({
    baseUrl: 'http://localhost:8080',
    softwareId: 1,
    version: '1.0.0',
  });

  // 检查是否可用
  if (!client.enabled) {
    console.warn('SDK is disabled, some features may not work');
    return;
  }

  // 提交反馈
  const feedbackResult = await client.feedback({
    content: 'This is a test feedback',
    email: '[email protected]', // 可选
  });
  console.log('Feedback result:', feedbackResult);

  // 激活软件
  const activateResult = await client.activate({
    machineCode: 'your-machine-code',
    code: 'your-activation-code',
  });
  console.log('Activation result:', activateResult);

  // 检查激活状态
  const checkResult = await client.check({
    machineCode: 'your-machine-code',
  });
  if (checkResult.expired) {
    console.log('License expired:', checkResult.reason);
  } else {
    console.log('License valid until:', checkResult.expireAt);
  }
}

main().catch(console.error);

Electron 主进程示例

在 Electron 的 main.jsmain.ts 中:

import { app, BrowserWindow } from 'electron';
import { initFeedbackClient } from '@howuse/feedback';

let feedbackClient: any;

async function initApp() {
  // 初始化 SDK
  feedbackClient = await initFeedbackClient({
    baseUrl: 'http://localhost:8080',
    softwareId: 1,
    version: app.getVersion(),
  });

  // 根据 enabled 状态决定是否显示反馈入口
  if (feedbackClient.enabled) {
    // 可以设置全局菜单或窗口中的反馈按钮
  }
}

app.whenReady().then(() => {
  initApp();
  createWindow();
});

API 参考

initFeedbackClient(options: InitOptions): Promise<FeedbackClient>

初始化 Feedback 客户端。

参数:

  • options.baseUrl (string): 服务器基础 URL
  • options.softwareId (number): 软件 ID
  • options.version (string): 软件版本号
  • options.timeoutMs (number, 可选): 请求超时时间(毫秒),默认 30000

返回值:

返回一个 FeedbackClient 实例。即使初始化失败,也不会抛出异常,而是返回 enabled=false 的客户端。

FeedbackClient

属性

  • enabled: boolean - 指示 SDK 是否可用

方法

feedback(data: FeedbackPayload): Promise<FeedbackResult>

提交用户反馈。

参数:

  • data.content (string): 反馈内容(必填)
  • data.email (string, 可选): 邮箱地址

返回值:

{
  success: boolean;
  id?: number;
  error?: string;
}
activate(data: ActivationRequest): Promise<ActivationResult>

激活软件。

参数:

  • data.machineCode (string): 机器码
  • data.code (string): 激活码

返回值:

{
  success: boolean;
  expireAt?: string;
  error?: string;
}
check(data: ActivationCheckRequest): Promise<ActivationCheckResponse>

检查激活状态。

重要: 如果调用失败(网络错误或服务器返回非 2xx),SDK 会直接返回 expired: true,而不是抛出异常。这确保了在无法联系服务端时,默认按"授权已到期"处理。

参数:

  • data.machineCode (string): 机器码

返回值:

{
  expired: boolean;
  activated?: boolean;
  expireAt?: string;
  reason?: string;
}

错误处理

SDK 采用"安全降级"策略:

  1. 初始化失败:不会抛出异常,而是返回 enabled=false 的客户端
  2. 方法调用:当 enabled=false 时,所有方法都会返回失败结果,而不是抛出异常
  3. 激活检查失败check 方法在失败时会返回 expired: true,确保在无法联系服务端时默认按"授权已到期"处理

动态库支持

SDK 支持通过 Go 语言实现的动态库(native library)提供所有 HTTP 请求功能。如果动态库可用,SDK 会自动使用;否则会回退到纯 HTTP 实现。

动态库构建

动态库使用 Go 语言实现,源码位于项目根目录的 native-sdk/ 目录。构建方法:

# macOS/Linux
cd native-sdk
./build.sh

# Windows
cd native-sdk
build.bat

构建完成后,动态库文件会输出到 feedback-sdk/native/ 目录:

  • macOS: native/libhowuse_feedback.dylib
  • Windows: native/howuse_feedback.dll
  • Linux: native/libhowuse_feedback.so

动态库优势

  • 性能优化:所有 HTTP 请求在 Go 层执行,性能更好
  • 代码保护:业务逻辑在编译后的动态库中,不易被逆向
  • 统一实现:HTTP 客户端逻辑统一在 Go 层管理

详细构建说明请参考 native-sdk/README.md

类型定义

所有类型都可以从包中导入:

import type {
  InitOptions,
  FeedbackPayload,
  ActivationRequest,
  ActivationCheckRequest,
  // ... 其他类型
} from '@howuse/feedback';

许可证

MIT