open-index/open-npm huggingface dataset:
npm package: @hunwalk/reclipse
Description: reclipse CLI
Latest version: 0.0.1

# reclipse CLI

A CLI for reclipse.

## Customizing your CLI

Check out the documentation at https://github.com/infinitered/gluegun/tree/master/docs.

## Publishing to NPM

To package your CLI up for NPM, do this:

```shell
$ npm login
$ npm whoami
$ npm lint
$ npm test
(if typescript, run `npm run build` here)
$ npm publish
```

# License

MIT - see LICENSE
npm package: @hunzaker/markdown
Description: My markdown formatter
Latest version: 1.1.2

# My markdown generator

This script generates nice looking, client-friendly markdown
documents. Here's how I have it configured:

First, install the required JavaScript packages with npm:

```bash
cd ~/path/to/this/script
npm install
```

While that installs, set up `markdown-mode`, with the following settings:

```lisp
;; Shells out to a provided command with the buffer as stdin
(setq-default markdown-command "node ~/path/to/script")
;; Properly decode special typographic characters
(setq-default markdown-content-type "utf-8")
```

Finally, run the `markdown-preview` interactive Emacs command:

```emacs-lsip
(markdown-preview)
```

And voilà!

![Preview](./preview.png)
npm package: @huo-shan/cli
Description: 一个持续进化的 CLI 工具集
Latest version: 0.2.0

# @huo-shan/cli

一个持续进化的 CLI 工具集，目前支持项目创建、代码生成、配置初始化和 OpenSpec 可视化面板。

## 特性

- 🚀 快速创建项目，支持 Vue3 和 Nuxt3 模板
- 🛠️ 交互式命令行界面，简单易用
- 🔧 代码生成，支持组件、页面、服务、Hook
- ✨ 支持模板特性选择，按需生成项目
- 🖥️ OpenSpec 面板，支持命令行/TUI 与 Web 两种模式
- ⌨️ OpenSpec Web 面板支持项目中心、全局搜索与快捷键操作

## 安装

```bash
# 全局安装
npm install -g @huo-shan/cli

# 或者直接使用 npx
npx @huo-shan/cli
```

## 使用方法

### 创建新项目

```bash
npx hs-cli create
```

执行命令后，会出现交互式提示：
1. 选择项目模板（Vue3 或 Nuxt3）
2. 选择项目特性（TypeScript、Router、Pinia 等）
3. 输入项目名称
4. 自动创建项目结构

### 可用命令

```bash
# 创建一个新项目
hs-cli create

# 生成代码文件（component / page / service / hook）
hs-cli generate <type> <name>
hs-cli g component Button
hs-cli g page Home
hs-cli g service User
hs-cli g hook useAuth

# 在当前目录初始化配置文件
hs-cli init

# 启动 OpenSpec 面板（默认 auto）
hs-cli openspec

# 强制使用 Web 面板
hs-cli openspec --ui web

# 强制使用命令行面板
hs-cli openspec --ui tui

# 指定文档路径和主题
hs-cli openspec --doc ./openspec/project.md --theme light

# 查看帮助
hs-cli --help
```

### OpenSpec 命令参数

```bash
hs-cli openspec [options]
```

- `-d, --doc <path>`: 指定 OpenSpec 文档路径
- `-t, --theme <theme>`: 主题，`dark|light`，默认 `dark`
- `-u, --ui <mode>`: 面板模式，`auto|tui|web`，默认 `auto`
- `--no-watch`: 关闭 Web 热更新（默认开启）

### OpenSpec Web 快捷键

- `Cmd/Ctrl + K`: 打开全局搜索
- `/`: 聚焦左侧搜索框
- `1/2/3/4`: 切换 概览/提案/变更/归档
- `j/k` 或 `↑/↓`: 列表上下导航
- `f`: 循环切换筛选条件（提案/变更页）
- `p`: 打开项目中心
- `o`: 打开动作中心（变更页）

## 项目模板

### Vue3 模板

基于 Vue 3 + Vite，可选特性：

- TypeScript
- JSX 支持
- Vue Router
- Pinia
- UnoCSS
- Vitest
- Auto Import
- 组件自动注册

### Nuxt3 模板

基于 Nuxt 3，可选特性：

- TypeScript
- UnoCSS
- Sass
- VueUse
- Nuxt Image
- Auto Import
- 组件自动注册

## 本地开发

```bash
# 安装依赖
pnpm install

# 开发模式运行
pnpm dev

# 构建
pnpm build

# 链接到全局测试
npm link
```

## 许可证

MIT
npm package: @huobiwallet-js/contract
Description: contract libraries for huobiwallet
Latest version: 0.0.12

# @huobiwallet-js/contract

This package provides a collection of apis to create, deploy, and interact with smart contracts. In Huobiwallet, smart contracts all fully EVM compatible and the formats and terminologies match 1-to-1 with EVM smart contracts.

## Installation

```
npm install @huobiwallet-js/contract
```

## Usage



Estimate gas for contract methods
```javascript
const options1 = { gasPrice: '0x3B9ACA00' }; // gas price in hex corresponds to 1 Gwei or 1000000000

contract.methods.getCount().estimateGas(options1).then(gas => {
  console.log('gas required for getCount is ' + hexToNumber(gas));
});
```

Call contract read-only methods. Huobiwallet uses 1 Gwei gas price and gas limit of 21000 by default. Use the estimate gas api to correctly set the gas limit.
```javascript
const options1 = { gasPrice: '0x3B9ACA00' }; // gas price in hex corresponds to 1 Gwei or 1000000000
let options2 = { gasPrice: 1000000000, gasLimit: 21000 }; // setting the default gas limit, but changing later based on estimate gas

contract.methods.getCount().estimateGas(options1).then(gas => {
  options2 = {...options2, gasLimit: hexToNumber(gas)};
  contract.methods.getCount().call(options2).then(count => {
    console.log('counter value: ' + count);
  });
});
```

Invoking contract modification methods using `send` api. Need to add a signing account to the contract wallet, otherwise `send` api will not work.
```javascript
const options1 = { gasPrice: '0x3B9ACA00' }; // gas price in hex corresponds to 1 Gwei or 1000000000
let options2 = { gasPrice: 1000000000, gasLimit: 21000 }; // setting the default gas limit, but changing later based on estimate gas

contract.wallet.addByPrivateKey('1f054c21a0f57ebc402c00e14bd1707ddf45542d4ed9989933dbefc4ea96ca68');

contract.methods.incrementCounter().estimateGas(options1).then(gas => {
  options2 = {...options2, gasLimit: hexToNumber(gas)};
  contract.methods.incrementCounter().send(options2).then(response => {
    console.log(response.transaction.receipt);
  });
});
```

All the above apis can also be asynchronously executed using `async` and `await`.
npm package: @huobiwallet-js/crypto
Description: crypto libraries for huobiwallet
Latest version: 0.0.12

# @huobiwallet-js/crypto

This package provides a collection of apis related to address management, kestore, encoding, and encrypt/decrypt.

## Installation

```
npm install @huobiwallet-js/crypto
```

## Usage

```javascript
const {
  encode,
  decode,
  randomBytes,
  toBech32,
  fromBech32,
  HuobiwalletAddress,
  generatePrivateKey,
  getPubkeyFromPrivateKey,
  getAddressFromPublicKey,
  getAddressFromPrivateKey,
  encryptPhrase,
  decryptPhrase
} = require('@huobiwallet-js/crypto');
const { isPrivateKey, isAddress, isPublicKey } = require('@huobiwallet-js/utils');
```

Address apis
```javascript
const bytes = randomBytes(20);
const addr = new HuobiwalletAddress(bytes);

console.log(addr.checksum);
console.log(addr.bech32);

console.log(HuobiwalletAddress.isValidBech32(addr.bech32));
```

RLP apis
```javascript
const encoded = '0x89010101010101010101';
const decoded = '0x010101010101010101';
console.log(encode(decoded));
console.log(decode(encoded));
```

Keystore apis
```javascript
const prv = generatePrivateKey();
const pub = getPubkeyFromPrivateKey(prv);
const addr = getAddressFromPublicKey(pub);
const addrPrv = getAddressFromPrivateKey(prv);
console.log(isPrivateKey(prv));
console.log(isPublicKey(pub));
console.log(isAddress(addr));
console.log(isAddress(addrPrv));
```

Encrypt/decrypt apis
```javascript
const { Wallet } = require('@huobiwallet-js/account');

const myPhrase = new Wallet().newMnemonic();
console.log(myPhrase);
const pwd = '1234';
encryptPhrase(myPhrase, pwd).then((value) => {
  console.log(value);
  decryptPhrase(JSON.parse(value), pwd).then(value => {
    console.log(value);
  });
});
```
npm package: @huobiwallet-js/network
Description: network suites for huobiwallet
Latest version: 0.0.12

# @huobiwallet-js/network

This package provides a collection of apis to create messengers (HTTP, WebSocket) to connect to blockchain networks.

## Installation

```
npm install @huobiwallet-js/network
```

## Usage

```javascript
const { Messenger, HttpProvider, WSProvider } = require('@huobiwallet-js/network');
const { ChainID, ChainType } = require('@huobiwallet-js/utils');
const testnetHTTP = 'https://http-testnet.hecochain.com';
const testnetWS = 'wss://ws.s0.b.hmny.io';
const localHTTP = 'https://http-testnet.hecochain.com/';
const localWS = 'http://localhost:9800/';
const http = new HttpProvider(testnetHTTP); // for local use localHTTP
const ws = new WSProvider(testnetWS); // for local use testnetWS
const customHTTPMessenger = new Messenger(http, ChainType.Huobi, ChainID.HecoTestnet); // for local ChainID.HecoLocal
const customWSMessenger = new Messenger(ws, ChainType.Huobi, ChainID.HecoTestnet); // for local ChainID.HecoLocal
```
npm package: @huobiwallet-js/utils
Description: utils for huobiwallet
Latest version: 0.0.12

# @huobiwallet-js/utils

This package provides a collection of utility apis for unit conversions like `fromWei`, `toWei`, `hexToNumber`, `numberToHex`, `isAddress`, etc.

## Installation

```
npm install @huobiwallet-js/utils
```

## Usage

Available units
```
const { Units } = require('@huobiwallet-js/utils');

[Units.wei, '1'], // 1 wei
[Units.Kwei, '1000'], // 1e3 wei
[Units.Mwei, '1000000'], // 1e6 wei
[Units.Gwei, '1000000000'], // 1e9 wei
[Units.szabo, '1000000000000'], // 1e12 wei
[Units.finney, '1000000000000000'], // 1e15 wei
[Units.ether, '1000000000000000000'], // 1e18 wei
[Units.Kether, '1000000000000000000000'], // 1e21 wei
[Units.Mether, '1000000000000000000000000'], // 1e24 wei
[Units.Gether, '1000000000000000000000000000'], // 1e27 wei
[Units.Tether, '1000000000000000000000000000000'], // 1e30 wei
```

Converting between different units
```javascript
const { Units, Unit, numberToString, add0xToString, fromWei, toWei, numToStr} = require('@huobiwallet-js/utils');
const { BN } = require('@huobiwallet-js/crypto');

const one = new Unit('1').asEther();
const oneToGwei = one.toGwei();
console.log(oneToGwei);

// numberToString
const num = 123;
const str = numberToString(num)
console.log(str);

// add0xToString
const str = '12345';
const expected = add0xToString(str)
console.log(expected);

// fromWei
const Wei = new BN('1000000000000000000');
const expected = fromWei(Wei, Units.ether);
console.log(expected);

// toWei
const one = new BN('1');
const expected = toWei(one, Heco.utils.Units.ether);
const num = numToStr(expected);
console.log(num);
```
npm package: @huodeming/wx_uni_request
Description: 基于 Promise 的小程序网路请求库
Author: huodeming
Latest version: 1.0.0

## 安装

```bash
npm install @huodeming/wx_uni_request
```

## 导入

```js
// 按需导入 $http 对象
import { $http } from '@huodeming/wx_uni_request'

// 如果是在微信小程序项目中:将按需导入的 $http 挂载到 wx 顶级对象之上，方便全局调用
wx.$http = $http

// 如果是在 uni-app 项目中，可以把 $http 挂载到 uni 顶级对象之上，方便全局调用
uni.$http = $http
```

## 使用

### 支持的请求方法

```js
// 发起 GET 请求，data 是可选的参数对象
$http.get(url, data?)

// 发起 POST 请求，data 是可选的参数对象
$http.post(url, data?)

// 发起 PUT 请求，data 是可选的参数对象
$http.put(url, data?)

// 发起 DELETE 请求，data 是可选的参数对象
$http.delete(url, data?)
```

### 配置请求根路径

```js
$http.baseUrl = 'https://www.xitnds.com'
```

### 请求拦截器

```js
// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  // do somethimg...
}
```

例 1，展示 loading 效果：

```js
// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  wx.showLoading({
    title: '数据加载中...',
  })
}
```

例 2，自定义 header 请求头：

```js
// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  if (options.url.indexOf('/home/catitems') !== -1) {
    options.header = {
      'X-Test': 'AAA',
    }
  }
}
```

### 响应拦截器

```js
// 请求完成之后做一些事情
$http.afterRequest = function (res) {
  // 做你想做的事情
  // 最后记得返回处理后的res,例: return res.data
  return res
}
```

例如，隐藏 loading 效果：

```js
// 请求完成之后做一些事情
$http.afterRequest = function (res) {
  wx.hideLoading()
  return res
}
```

## 开源协议

![MIT](https://img.shields.io/badge/License-MIT-blue)

**enjoy!**
npm package: @huohua/huohua-component-log
Description: huohua component record client log info
Author: twinklej
Latest version: 0.0.14

# huohua-component-log

> 火花素材日志上报组件

[![Build Status](https://travis-ci.org/zhiguoBao/huohua-component-log.svg?branch=master)](https://travis-ci.org/zhiguoBao/huohua-component-log)
[![NPM version](https://img.shields.io/npm/v/@huohua/huohua-component-log.svg)](https://www.npmjs.com/package/@huohua/huohua-component-log)
![Downloads](https://img.shields.io/npm/dm/@huohua/huohua-component-log.svg)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)

---

## ✨ Features

- 收集运行环境信息
- 上报当前信息到指定服务器

## 🔧 Installation

```sh
yarn add @huohua/huohua-component-log
```

## 🎬 Getting started

```ts
import { Environment, Log } from '@huohua/huohua-component-log'

// 初始化环境信息，env.hardware有可能获取不到
const env = new Environment()

// 初始化上传日志方法，6秒后上传日志
Log.getInstance(url?: string, time?: number)
```

## 📜 API

> coming soon
npm package: @huohua/huohua-plugin-locale
Description: huohua plugin i18n
Author: bzg0382@gmail.com
Latest version: 0.1.0

<p align="center">
  <img src="./i8n-logo.png" width="300" alt="huohua-plugin-locale">
</p>

# huohua-plugin-locale

> 火花插件 国际化组件

[![Build Status](https://travis-ci.org/bzg0382@gmail.com/huopreprehua-plugin-locale.svg?branch=master)](https://travis-ci.org/bzg0382@gmail.com/huohua-plugin-locale)
[![NPM version](https://img.shields.io/npm/v/@huohua/huohua-plugin-locale.svg)](https://www.npmjs.com/package/@huohua/huohua-plugin-locale)
![Downloads](https://img.shields.io/npm/dm/@huohua/huohua-plugin-locale.svg)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)

---

## ✨ Features

插件国际化分两个部分

- 软件界面国际化, 所有插件的界面文字需要在 /lang/zh-cn.json 文件中,打包时需要一并打入 dist 根目录.
  在代码读取 zh-cn.json 时需要调用 Locale 组件 来获取正确的 json 语言包

  ```ts
  const uiDir = 'D:\\widget\\lang\\'
  // D:\\widget\\lang\\zh-cn.json
  const uiJson = Locale.getUIConfigPath(uiDir)
  ```

- 插件生成的 json 数据国际化,插件生成的数据文件与界面国际化定义规则不同,插件生成默认命名规则时/xxx.json,
  国际化时需要在文件名上追加编码 如 /xxx_en-US.json ,如果编码是 zh-cn 则默认会省略

  ```ts
  const path = 'D:\\widget\\data.json'
  // D:\\widget\\data_en-US.json
  const actual = Locale.getContentDataPath(path)
  ```

## 🔧 Installation

```sh
yarn add @huohua/huohua-plugin-locale
```

## 🎓 Guides

- 生成的语言编码均为小写
- 默认语言为 zh-cn, 各个插件需要判断文件是否存在

## 🥂 License

[MIT](./LICENSE.md) as always
npm package: @huohua/rrwidget
Description: Record and Replay Widget plugin
Author: zhiguo
Latest version: 0.0.7

# rrwidget

> Typescript &

[![Build Status](https://travis-ci.org/Xiyue-team/rrwidget.svg?branch=master)](https://travis-ci.org/Xiyue-team/rrwidget)
[![NPM version](https://img.shields.io/npm/v/@huohua/rrwidget.svg)](https://www.npmjs.com/package/@huohua/rrwidget)
![Downloads](https://img.shields.io/npm/dm/@huohua/rrwidget.svg)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)

---

## ✨ Features

- Record PBL Widget User Operations
- Replay Widget by User Data

## 🔧 Installation

```sh
yarn add @huohua/rrwidget
```

## 🎬 Getting started

Let's demonstrate simple usage with ... example:

```ts
// your code example
```

## 🎭 Examples

Go checkout [examples](./examples) !

## 📜 API

> Document your API here

### `publicMethodOne(value:string): string`

This methods does foo bar moo...

**Example:**

```ts
// example
```

## 🎓 Guides

<details>
<summary>How to do Foo</summary>
Today we're gonna build Foo....
</details>

### 🕵️ Troubleshooting

## 🥂 License

[MIT](./LICENSE.md) as always
npm package: @huolala-tech/custom-error
Description: Used to fix the odd behaviors of native Error object inheritance code compiled to ES5
Author: YanagiEiichi
Latest version: 1.0.0

# CustomError · [![LICENSE](https://img.shields.io/npm/l/@huolala-tech/custom-error)](LICENSE.txt)

Used to fix the odd behaviors of native Error object inheritance code compiled to ES5.

## Why?

If your code is compiled to ES5 target, you may encounter an unexpected behavior.

```typescript
class MyError extends Error {
  // blah blah blah
}

const error = new MyError();

console.log(error instanceof Error); // true
console.log(error instanceof MyError); // false <!-- should be true
```

see https://babeljs.io/docs/en/caveats/#classes

## Include

```bash
yarn add @huolala-tech/custom-error
```

or

```bash
npm install @huolala-tech/custom-error --save
```

## Use the CustomError

```typescript
import { CustomError } from '@huolala-tech/custom-error';

class MyError extends CustomError {
  // blah blah blah
}

const error = new MyError();

console.log(error instanceof Error); // true
console.log(error instanceof MyError); // true
console.log(error instanceof CustomError); // true
console.log(Object.prototype.toString.call(error)); // [object Error]
```
npm package: @huolala-tech/eval5
Description: A JavaScript vm written in JavaScript. Forked from eval5
Latest version: 0.0.2

# eval5

[中文](./README_ZH.md) | English

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/HuolalaTech/eval5/blob/master/LICENSE)
[![npm](https://img.shields.io/npm/v/@huolala-tech/eval5)](https://www.npmjs.com/package/@huolala-tech/eval5)
[![npm bundle size](https://img.shields.io/bundlephobia/min/eval5)](https://unpkg.com/browse/@huolala-tech/eval5/dist/umd/index.min.js)


A JavaScript interpreter written in TypeScript, Supports full ES5 syntax.

> [!NOTE]
> Forked from [eval5](https://github.com/bplok20010/eval5)

## Features

The purpose of this package is to reduce the code size, so as to compare with the original package, we removed the transpile from code to AST, 

## License

MIT
npm package: @huolala-tech/hooks
Description: Some hooks
Author: YanagiEiichi
Latest version: 1.0.0

# hooks

## Install

```bash
yarn add @huolala-tech/hooks
```

or

```bash
npm install @huolala-tech/hooks --save
```

## Hooks

### [useEventListener](./src/use-event-listener/README.md)

### [useSlot / useSlotWriter](./src/use-slot/README.md)
npm package: @huolala-tech/nad-builder
Description: Convert the Java AST to client-side code
Author: YanagiEiichi
Latest version: 1.1.3

# nad-builder · [![LICENSE](https://img.shields.io/npm/l/@huolala-tech/nad-builder)](../../LICENSE.txt) [![codecov](https://codecov.io/gh/HuolalaTech/nad/branch/main/graph/badge.svg?token=3YnCtwfAzL&flag=nad-builder)](https://app.codecov.io/gh/HuolalaTech/nad/tree/main/nad-builder)

Convert the Java AST to client-side code.

## Include

```shell
yarn add @huolala-tech/nad-builder
```

or

```shell
npm install @huolala-tech/nad-builder --save
```

## Demo

```typescript
import { Builder } from '@huolala-tech/nad-builder';

// You don't need to write this manually, as it can be obtained from the Java service.
const defs = {
  routes: [
    {
      name: 'foo',
      bean: 'test.Demo',
      methods: ['POST'],
      patterns: ['/foo'],
      parameters: [{ name: 'id', type: 'java.lang.Long' }],
      returnType: 'java.lang.Long',
    },
  ],
};
const base = 'http://localhost';
const target = 'ts';

const { code } = new Builder({ defs, target, base });

console.log(code); // Output the generated TypeScript code
```
npm package: @huolala-tech/nad-cli
Description: The CLI Tools of Nad Project
Author: YanagiEiichi
Latest version: 1.1.1

# nad-cli · [![LICENSE](https://img.shields.io/npm/l/@huolala-tech/nad-cli)](../../LICENSE.txt) [![codecov](https://codecov.io/gh/HuolalaTech/nad/branch/main/graph/badge.svg?token=3YnCtwfAzL&flag=nad-cli)](https://app.codecov.io/gh/HuolalaTech/nad/tree/main/nad-cli)

A CLI tool, can generate client code from an API service
that has installed and enabled the [nad-java-sdk](../../nad-java-sdk).

## Include

```bash
yarn add @huolala-tech/nad-cli -D
```

or

```bash
npm install @huolala-tech/nad-cli --save-dev
```

## Usage

```
Usage: nad [Options] <URL>
       nad --config <Path>
       nad -c <Path>

Example: nad http://localhost:8080
         nad -t oc http://localhost:8080

Options:
  -t, --target <target>     Specify the output file format ("ts", "oc", "raw"), defaults to "ts".
  -o, --output <path>       Specify the output file path, defaults to stdout.
  -c, --config <path>       Path to configuration file. If specified, all other arguments will be ignored.
  -h, --help                Display this help message.
```

## Config File

```ts
type Target = 'ts' | 'oc' | 'raw';

export interface ConfigFile {
  /**
   * Specify the output file format.
   * @default ts
   */
  target?: Target;

  /**
   * Specify the API definition file URL.
   * @required
   */
  url: string;

  /**
   * Specify the output file path.
   * @default stdout
   */
  output?: string;

  /**
   * Specify which APIs should be generated.
   * @default All
   */
  apis?: string[];

  /**
   * Define some special types to map to other types.
   */
  typeMapping?: Record<string, string>;
}
```
npm package: @huolala-tech/nad-runtime
Description: The runtime lib of the Nad project
Author: YanagiEiichi
Latest version: 1.0.10

# nad-runtime · [![LICENSE](https://img.shields.io/npm/l/@huolala-tech/nad-runtime)](../../LICENSE.txt) [![codecov](https://codecov.io/gh/HuolalaTech/nad/branch/main/graph/badge.svg?token=3YnCtwfAzL&flag=nad-runtime)](https://app.codecov.io/gh/HuolalaTech/nad/tree/main/nad-runtime)

The runtime lib of the Nad project.

## Include

```bash
yarn add @huolala-tech/nad-runtime
```

or

```bash
npm install @huolala-tech/nad-runtime --save
```

## Useage

### 1. @PathVariable

```typescript
import { NadInvoker } from '@huolala-tech/nad-runtime';

// This code will request http://localhost/users/123 with GET mtehod.
const getUserInfo = async () => {
  return await new NadInvoker('http://localhost').open('GET', '/users/{id}').addPathVariable('id', 123).execute();
};
```

### 2. @RequestParam

```typescript
import { NadInvoker } from '@huolala-tech/nad-runtime';

// This code will request http://localhost/getUser?id=123 with GET mtehod.
const getUserInfo = async () => {
  return await new NadInvoker('http://localhost').open('GET', '/getUser').addRequestParam('id', id).execute();
};
```

### 2. @ModelAttribute

```typescript
import { NadInvoker } from '@huolala-tech/nad-runtime';

// This code will request http://localhost/getUser?id=1&type=2 with GET mtehod.
const getUserInfo = async () => {
  return await new NadInvoker('http://localhost')
    .open('GET', '/getUser')
    .addModelAttribute({ id: 1, type: 2 })
    .execute();
};
```

### 4. @RequestBody

```typescript
import { NadInvoker } from '@huolala-tech/nad-runtime';

// This code will request http://localhost/userService with POST mtehod and send payload {"id":123}.
const getUserInfo = async () => {
  return await new NadInvoker('http://localhost').open('POST', '/userService').addRequestBody({ id: 123 }).execute();
};
```
npm package: @huolala-tech/page-spy-alipay
Description: A developer tool for debugging alipay miniprogram
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-alipay?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-alipay
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-alipay
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-alipay/dist/iife/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-alipay`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

The client SDK of [PageSpy](https://www.pagespy.org) used in alipay miniprogram environment.

## Usage

```ts
import PageSpy from '@huolala-tech/page-spy-alipay';

const pageSpy = new PageSpy({
  api: 'example.com',
});
```

Please refer to the official documentation for more details [PageSpy API](https://www.pagespy.org/#/docs/api)。

## Other SDKs

If you are using UniAPP or Taro, we recommend using below SDKs respectively:

- [@huolala-tech/page-spy-uniapp](https://www.npmjs.com/package/@huolala-tech/page-spy-uniapp)
- [@huolala-tech/page-spy-taro](https://www.npmjs.com/package/@huolala-tech/page-spy-taro)
npm package: @huolala-tech/page-spy-plugin-mp-data-harbor
Description: Used for caching data and downloading.
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-plugin-mp-data-harbor?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-plugin-mp-data-harbor
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-plugin-mp-data-harbor
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-plugin-mp-data-harbor/dist/esm/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-plugin-mp-data-harbor`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

This plugin is used in miniprogram environment, providing offline caching and data downloading capabilities.

In the past, remote debugging had a prerequisite that "both the client and debugging server must be online simultaneously." By utilizing the `mp-data-harbor` plugin, it internally listens for the `"public-data"` event ([what is the `public-data` event?](../../docs/plugin.md#behavioral-conventions)), allowing the offline caching of data. This innovation breaks the previous prerequisite of both the client and debugging server needing to be online simultaneously. When issues are identified by the client, testing colleagues can directly upload the data, marking a significant departure from the historical requirement of simultaneous online status for both the client and debugging server.

`mp-data-harbor` plugin starts collecting data when `new PageSpy()` is called. The collected data is stored in client-side memory.

## Definition

```ts
import { PageSpyPlugin } from '@huolala-tech/page-spy-types';

type DataType = 'console' | 'network' | 'system' | 'storage';

interface DataHarborConfig {
  // Specify which types of data should be collected
  caredData?: Record<DataType, boolean>;

  // Customize the log's filename
  filename?: () => string;
}

declare class DataHarborPlugin implements PageSpyPlugin {
  constructor(config?: DataHarborConfig);
}

export default DataHarborPlugin;
```

## Usage

### Load plugin

```ts
import PageSpy from '@huolala-tech/page-spy-uniapp';
// Import the plugin in your entry file like "main.ts".
import DataHarborPlugin from '@huolala-tech/page-spy-plugin-mp-data-harbor';

// Init and register the plugin before the PageSpy sdk initiated.
const harbor = new DataHarborPlugin(config);
PageSpy.registerPlugin(harbor);

// Init PageSpy
new PageSpy();
```

### Upload data

There are 2 ways to upload the offline data:

1. call `upload` method of the plugin:

```js
harbor.plugin.upload().then((res) => {
  conssole.log('upload successfully');
});
```

2. Upload via PageSpy's control panel:

With the `mp-data-harbor` plugin, there will be an upload button in the PageSpy control panel.

<img src="./screenshots/modal.png" alt="Download" height="400" />

### Replay log

Goto the debugger's log list page and click the "Replay log" button, select the file uploaded in prev step, now you can use the replay to debug.

<img src="./screenshots/guide-en.png" alt="Entry" height="400" />
npm package: @huolala-tech/page-spy-plugin-mp-eval
Description: Used for code evaluation in mini program.
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-plugin-mp-eval?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-plugin-mp-eval
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-plugin-mp-eval
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-plugin-mp-eval/dist/iife/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-plugin-mp-eval`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

The `MPEvalPlugin` is used in mini program SDK of PageSpy, making it possible to run dynamic scripts in the mini program environment.

Available mini program SDKs include:

- [@huolala-tech/page-spy-wechat](https://www.npmjs.com/package/@huolala-tech/page-spy-wechat)
- [@huolala-tech/page-spy-alipay](https://www.npmjs.com/package/@huolala-tech/page-spy-alipay)
- [@huolala-tech/page-spy-uniapp](https://www.npmjs.com/package/@huolala-tech/page-spy-uniapp)
- [@huolala-tech/page-spy-taro](https://www.npmjs.com/package/@huolala-tech/page-spy-taro)

> [!CAUTION]
> When submitting the mini program for review, be sure to delete this plugin in the code, otherwise the review will fail.

## Usage

```ts
// In your entry file like "main.ts"
import PageSpy from '@huolala-tech/page-spy-wechat';
import MPEvalPlugin from '@huolala-tech/page-spy-plugin-mp-eval';

// Register plugin
PageSpy.registerPlugin(new MPEvalPlugin());
// Init PageSpy
const pageSpy = new PageSpy();
```
npm package: @huolala-tech/page-spy-plugin-ospy
Description: Offline-fist PageSpy, plug and play. Only available in browser.
Latest version: 2.2.11

# `@huolala-tech/page-spy-plugin-ospy`

![Screenshot](./.github/screenshots/image.png)

## Usage

See https://www.pagespy.org/#/o-spy.
npm package: @huolala-tech/page-spy-plugin-rn-async-storage
Description: A PageSpy plugin, used for React Native app with async-storage.
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-plugin-rn-async-storage?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-plugin-rn-async-storage
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-plugin-rn-async-storage
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-plugin-rn-async-storage/dist/iife/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-plugin-rn-async-storage`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

This plugin is used in React Native environment to inspect the data in AsyncStorage.

This plugin can only be registered in PageSpy ReactNative SDK: [`@huolala-tech/page-spy-react-native`](https://www.npmjs.com/package/@huolala-tech/page-spy-react-native).

## Usage

```ts
// In your entry file like "main.ts"
import PageSpy from '@huolala-tech/page-spy-react-native';
import AsyncStoragePlugin from '@huolala-tech/page-spy-plugin-rn-async-storage';

// Register plugin
PageSpy.registerPlugin(new AsyncStoragePlugin());
// Init PageSpy
const pageSpy = new PageSpy();
```

After that, enter the debug room on PageSpy web page and you can see the data in Storage -> AsyncStorage.
npm package: @huolala-tech/page-spy-plugin-rrweb
Description: Record the DOM mutation within PageSpy.
Latest version: 2.2.5

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-plugin-rrweb?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-plugin-rrweb
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-plugin-rrweb
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-plugin-rrweb/dist/iife/index.min.js
[rrweb-repo]: https://github.com/rrweb-io/rrweb
[rrweb-record-options]: https://github.com/rrweb-io/rrweb/blob/master/guide.md#options

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-plugin-rrweb`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

> Use `rrweb` under the hood, record the DOM mutation within PageSpy, only be available in browser environment.

## Definition

```ts
import { PageSpyPlugin } from '@huolala-tech/page-spy-types';
import type { recordOptions } from 'rrweb/typings/types';
import type { eventWithTime } from '@rrweb/types';

interface Options extends recordOptions<eventWithTime> {}

declare class RRWebPlugin implements PageSpyPlugin {
  constructor(options?: Options);
}

export default RRWebPlugin;
```

`RRWebPlugin` use [`rrweb-record`][rrweb-repo] under the hood, the instantiate options reference [record options][rrweb-record-options].

## Usage

### Load plugin

- Options 1: Load with script

  ```html
  <html>
    <head>
      <!-- 1. Load PageSpy -->
      <script src="https://<your-host>/page-spy/index.min.js"></script>
      <!-- 2. Load the DataHarborPlugin plugin -->
      <script src="https://<your-host>/plugin/data-harbor/index.min.js"></script>
      <!-- 3. Load the RRWebPlugin plugin -->
      <script src="https://<your-host>/plugin/rrweb/index.min.js"></script>
      <!-- 4. Register plugin && Init PageSpy -->
      <script>
        // 1. Register DataHarborPlugin plugin
        PageSpy.registerPlugin(new DataHarborPlugin(config));
        // 2. Register RRWebPlugin plugin
        PageSpy.registerPlugin(new RRWebPlugin(options));
        // 3. Init PageSpy
        window.$pageSpy = new PageSpy();
      </script>
    </head>
  </html>
  ```

- Option 2: Import within ESM

  ```ts
  // In your entry file like "main.ts"
  import PageSpy from '@huolala-tech/page-spy-browser';
  import RRWebPlugin from '@huolala-tech/page-spy-plugin-rrweb';

  // Register plugin
  PageSpy.registerPlugin(new RRWebPlugin(options));
  // Init PageSpy
  window.$pageSpy = new PageSpy();
  ```

### Replay

The data from 'rrweb-event' is typically larger (more interactions and complex webpage structures result in larger data). When developers debug, real-time transmission can impose a burden on network overhead, and page interactions are not always critical information. Considering these factors, this plugin only dispatch the 'public-data' event ([what's the `public-data` event?](../../docs/plugin.md#behavioral-conventions)) for statistical plugins to collect.
npm package: @huolala-tech/page-spy-plugin-whole-bundle
Description: Packed 3 packages: page-spy-browser / page-spy-plugin-data-harbor / page-spy-plugin-rrweb. Only available in browser.
Latest version: 2.1.11
Deprecated: The package is deprecated, please use @huolala-tech/page-spy-plugin-ospy instead. See https://www.pagespy.org/#/o-spy.

# `@huolala-tech/page-spy-plugin-whole-bundle`

> [!WARNING]
> 此包已经更名为 [`@huolala-tech/page-spy-plugin-ospy`](../page-spy-plugin-ospy)，后续不会再在这个包里新增功能。

![Screenshot](./.github/screenshots/image.png)

插件打包了三个依赖，一个脚本实现 _离线模式的 PageSpy、录制操作轨迹、支持导出离线日志_ 的功能:

- [@huolala-tech/page-spy-browser](../page-spy-browser/);
- [@huolala-tech/page-spy-plugin-data-harbor](../page-spy-plugin-data-harbor/);
- [@huolala-tech/page-spy-plugin-rrweb](../page-spy-plugin-rrweb/);

## 使用

### CDN 引入

- jsdelivr: https://cdn.jsdelivr.net/npm/@huolala-tech/page-spy-plugin-whole-bundle
- unpkg: https://unpkg.com/@huolala-tech/page-spy-plugin-whole-bundle

```html
<head>
  ...
  <!-- 以 jsdelivr 为例 -->
  >
  <script
    src="https://cdn.jsdelivr.net/npm/@huolala-tech/page-spy-plugin-whole-bundle"
    crossorigin="anonymous"
  ></script>

  <script>
    const $wholeBundle = new WholeBundle({
      /**
       * 悬浮球和弹窗上显示
       */
      title?: string;
      /**
       * - 在线图片: 'https://example.com/xxx.jpg'
       * - 相对路径: '../xxx.jpg'
       * - Data url: 'data:image/png;base64,xxxx...'
       */
      logo?: string;
      /**
       * 定制主题色
       */
      primaryColor?: string;
      /**
       * 是否自动渲染悬浮球
       */
      autoRender?: boolean;
    })
  </script>
</head>
```

### ESM 引入

- 安装

```bash
yarn add @huolala-tech/page-spy-plugin-whole-bundle

# OR

npm install @huolala-tech/page-spy-plugin-whole-bundle
```

- 使用

```ts
import WholeBundle from '@huolala-tech/page-spy-plugin-whole-bundle';
import '@huolala-tech/page-spy-plugin-whole-bundle/dist/index.css';

const $wholeBundle = new WholeBundle({
  /**
   * 悬浮球和弹窗上显示的标题
   */
  title?: string;
  /**
   * - 在线图片: 'https://example.com/xxx.jpg'
   * - 相对路径: '../xxx.jpg'
   * - Data url: 'data:image/png;base64,xxxx...'
   */
  logo?: string;
  /**
   * 定制主题色
   */
  primaryColor?: string;
  /**
   * 是否自动渲染悬浮球
   */
  autoRender?: boolean;
})
```
npm package: @huolala-tech/page-spy-react-native
Description: An SDK of PageSpy for debugging react native app
Latest version: 2.2.5

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-react-native?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-react-native
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-react-native
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-react-native/dist/esm/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-react-native`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

> The SDK used in React Native apps.

> [!CAUTION]
> When submitting the mini program for review, be sure to delete the SDK in the code, otherwise the review will fail.

## Usage

```ts
import PageSpy from '@huolala-tech/page-spy-react-native'

const pageSpy = new PageSpy(config?: InitConfig)
```

## `InitConfig` definition

Except for the `api` parameter is required, all others parameters are optional:

```ts
interface InitConfig {
  // Server domain, must be provided。
  // Example："example.com"
  api: string;

  // "project" is an aggregation of information that can be searched in the room list on the debug side.
  // default: 'default'
  project?: string;

  // "title" is a user-defined parameter that can be used to distinguish the current debugging client,
  // and the corresponding information is displayed under the "device id" in each debugging connection panel.
  // default: '--'
  title?: string;

  // Manually specify the scheme of the PageSpy service.
  // Note that except for development environment, mini-program requires the scheme to be set to "https", so:
  //  - By default, pass the value undefined or null, the SDK will parse it to TRUE;
  //  - true: the SDK will access the PageSpy service via ["https://", "wss://"];
  //  - false: the SDK will access the PageSpy service via ["http://", "wss://"].
  enableSSL?: boolean | null;

  // All internal plugins are carried with PageSpy by default out of the box.
  // You can disable some plugins as needed.
  disabledPlugins?: (InternalPlugins | string)[];
}

type InternalPlugins =
  | 'ConsolePlugin'
  | 'ErrorPlugin'
  | 'NetworkPlugin'
  | 'SystemPlugin';
```

## Other topics

### https

iOS and Android only support HTTPS by default. If the page-spy service you deploy doesn't have HTTPS enabled, it will result in being unable to connect to the page-spy service.

And here's the link: https://reactnative.dev/docs/network

### storage

This package does not include a default storage plugin, since the latest React Native removed the official storage APIs.

If you use the official recommended storage library `@react-native-async-storage/async-storage`, we provide an independent plugin for you: [`@huolala-tech/page-spy-plugin-rn-async-storage`](https://www.npmjs.com/package/@huolala-tech/page-spy-plugin-rn-async-storage)
npm package: @huolala-tech/page-spy-taro
Description: A developer tool for debugging taro miniprogram
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-taro?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-taro
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-taro
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-taro/dist/esm/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-taro`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

The client SDK of [PageSpy](https://www.pagespy.org) used with Taro.

## Usage

```ts
import PageSpy from '@huolala-tech/page-spy-taro';

const pageSpy = new PageSpy({
  api: 'example.com',
});
```

Please refer to the official documentation for more details [PageSpy API](https://www.pagespy.org/#/docs/api)。
npm package: @huolala-tech/page-spy-types
Description: Types for PageSpy SDK
Latest version: 2.2.4

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-types`

> Types for PageSpy SDK.

## Usage

```ts
import * as PageSpyTypes from '@huolala-tech/page-spy-types'

class SomePlugin implements PageSpyTypes.PageSpyPlugin {
  ...
}
```
npm package: @huolala-tech/page-spy-uniapp
Description: A developer tool for debugging uniapp miniprogram
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-uniapp?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-uniapp
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-uniapp
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-uniapp/dist/esm/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-uniapp`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

The client SDK of [PageSpy](https://www.pagespy.org) used with UniAPP.

## Usage

```ts
import PageSpy from '@huolala-tech/page-spy-uniapp';

const pageSpy = new PageSpy({
  api: 'example.com',
});
```

Please refer to the official documentation for more details [PageSpy API](https://www.pagespy.org/#/docs/api)。
npm package: @huolala-tech/page-spy-wechat
Description: A developer tool for debugging wechat miniprogram
Latest version: 2.2.4

[npm-image]: https://img.shields.io/npm/v/@huolala-tech/page-spy-wechat?logo=npm&label=version
[npm-url]: https://www.npmjs.com/package/@huolala-tech/page-spy-wechat
[minified-image]: https://img.shields.io/bundlephobia/min/@huolala-tech/page-spy-wechat
[minified-url]: https://unpkg.com/browse/@huolala-tech/page-spy-wechat/dist/iife/index.min.js

English | [中文](./README_ZH.md)

# `@huolala-tech/page-spy-wechat`

[![SDK version][npm-image]][npm-url]
[![SDK size][minified-image]][minified-url]

The client SDK of [PageSpy](https://www.pagespy.org) used in wechat miniprogram environment.

## Usage

```ts
import PageSpy from '@huolala-tech/page-spy-wechat';

const pageSpy = new PageSpy({
  api: 'example.com',
});
```

Please refer to the official documentation for more details [PageSpy API](https://www.pagespy.org/#/docs/api)。

## Other SDKs

If you are using UniAPP or Taro, we recommend using below SDKs respectively:

- [@huolala-tech/page-spy-uniapp](https://www.npmjs.com/package/@huolala-tech/page-spy-uniapp)
- [@huolala-tech/page-spy-taro](https://www.npmjs.com/package/@huolala-tech/page-spy-taro)
npm package: @huolala-tech/preload-js
Description: 页面数据预请求与缓存
Latest version: 1.1.0

# @huolala-tech/preload-js

[English](./README_EN.md) | 中文

## 介绍

预请求和缓存接口数据。

## 开始

```bash
npm i @huolala-tech/preload-js
```

## 使用

### 函数签名

```typescript
import { preload, usePreload } from '@huolala-tech/preload-js';
function preload(
  key: string | number,
  request: () => any,
  deps: (string | number | boolean | symbol)[],
): Promise<any>;

function usePreload(
  key: string | number,
  request: () => any,
  deps: (string | number | boolean | symbol)[],
): Promise<any>;
```

- key: 用以标识, 类似 localStorage
- request: 一个函数，可以返回任意数据，Promise/字符串/数字/数组/对象……
- deps: 依赖数组，不传默认每次都重新调用 request，如果传入则只有在依赖发生变化时才会请求，内部使用 `Object.is` 对比前后依赖。

### 例子:

#### 1. A 页面跳转 B 页面，预加载 B 页面请求数据。

A 页面：

```javascript
import { preload } from '@huolala-tech/preload-js';

preload('pageB', () => pageBRequest({ key: 'value' }));
navigateTo('pageB');
```

B 页面：

```javascript
import { usePreload } from '@huolala-tech/preload-js';

const data = await usePreload('pageB', () => pageBRequest({ key: 'value' }));
```

#### 2. A 页面跳转 B 页面，直接传递已有数据

A 页面：

```javascript
import { preload } from '@huolala-tech/preload-js';

preload('pageB', () => ({ key: 'pageAData' }));
navigateTo('pageB');
```

B 页面：

```javascript
import { usePreload } from '@huolala-tech/preload-js';

const data = await usePreload('pageB', () => pageBRequest({ key: 'value' }));
// data: { key: 'pageAData' }
```

如果直接进入 B 页面，会正常发起 `pageBRequest`，如果先经过 A 页面，则 B 页面会先使用 A 页面传递的数据，B 页面第二次请求时才会发起 `pageBRequest` 更新数据。

通常我们需要包装数据以便和请求返回结构一样，类似：

```javascript
const data = {
  ret: 0,
  data: {
    key: 'somePageData',
  },
};
preload('pageB', () => data);
navigateTo('pageB');
```

#### 3. 传入用户 ID 作为依赖

```javascript
import { usePreload } from '@huolala-tech/preload-js';

const userId = 1001;
const userInfo = await usePreload('userInfo', () => getUserInfo({ userId }), [
  userId,
]);
```

只有 userId 发生变化后，再次调用才会发起 `getUserInfo` 请求（注：并不是 userId 变化会自动发起请求)。

在传入依赖数组时 `usePreload` 可以单独调用，第一次调用发起请求后会保存依赖，再次调用时如果依赖不变，直接返回第一次调用的结果。

#### 4. 应用生命周期内只请求一次

```javascript
import { usePreload } from '@huolala-tech/preload-js';

const data = await usePreload('requestOnlyOnce', () => requestData(), [
  'requestOnlyOnce', // 传任意静态值都一样, 只要 Object.is 对比没有变化, 就会返回缓存
]);
```

#### 5. 使用 useDep

```javascript
import { usePreload, useDep } from '@huolala-tech/preload-js';

const [dep, setDep] = useDep(); // 默认使用 Date.now()

const userInfo = await usePreload('userInfo', () => getUserInfo({ userId }), [
  dep,
]);

setDep(); // 默认使用 Date.now()
```

##### 6. setConfig 和 removeOnCatch

默认情况下，传入的 promise 被 catch 时会自动销毁缓存，如果你想在 catch 时也依然使用缓存，可以使用 setConfig 设置：

```javascript
import { setConfig } from '@huolala-tech/preload-js';
setConfig({ removeOnCatch: false }); // 此设置为全局生效
```

如果你只想让某个请求被 catch 时依然缓存，可以传入依赖：

```javascript
import { removeOnCatch } from '@huolala-tech/preload-js';
const data = await usePreload('userInfo', () => getUserInfo({ userId }), [
  removeOnCatch(false), // 不传默认为 true，和全局配置默认值为 true 一致
]);
```
npm package: @huolala-tech/react-json-view
Description: A react component for displaying JSON data
Author: Blucas Wu
Latest version: 1.2.5

Engligh | [中文](./README_CN.md)

## @huolala-tech/react-json-view

`<ReactJsonView />` is a React component for displaying serializable data.

## Install

```bash
# Yarn
yarn add @huolala-tech/react-json-view

# NPM
npm install @huolala-tech/react-json-view

# pnpm
pnpm install @huolala-tech/react-json-view
```

## Usage

See [examples](./examples/)

```tsx
imoprt React from 'react';
import ReactDOM from 'react-dom';

import ReactJsonView from '@huolala-tech/react-json-view';
import '@huolala-tech/react-json-view/dist/style.css';

const data = [1,2,3,4]

const App = () => {
  return (
    <div id="app">
      <ReactJsonView
        source={data}
        darkMode={false}
        rootLabel="Response data"
        keyCount={200}
        defaultExpand={false}
        maxTitleSize={100}
      />
    </div>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root') as HTMLElement
)
```

## Config

The default configuration usage:

```tsx
<ReactJsonView
  source={data}
  darkMode={false}
  rootLabel=""
  defaultExpand={false}
  keyCount={200}
  maxTitleSize={100}
  copyable={true}
  expandable={true}
/>
```

| Name            | Type               | Default value | Description                                                  |
| --------------- | ------------------ | ------------- | ------------------------------------------------------------ |
| `source`        | `object`           | None          | Origin serializable data.                                    |
| `darkMode`      | `boolean`          | `false`       | Indicate whether enable dark mode.                           |
| `rootLabel`     | `React.ReactNode`  | `""`          | Root node's label.                                           |
| `defaultExpand` | `boolean / number` | `false`       | Whether expand property panel. Expand at a particular depth if you pass a integer value. |
| `keyCount`      | `number / "all"`   | `200`         | `ReactJsonView` supports lazily loading more properties. The parameter indicates how many properties to show at a time, and you can pass `"all"` to show all properties. |
| `maxTitleSize`  | `number`           | `100`         | The max length of abbreviated title in collapse.             |
| `copyable`      | `boolean`          | `true`        | Indicate whether enable copy function.                       |
| `expandable`    | `boolean`          | `true`        | Indicate whether enable expand function.                     |
| `stringEllipse` | `boolean`          | `true`        | Ellipse if the string type value's length is more than 100 or show all text when you pass false. |

## License

[MIT](./LICENSE)