@jsdevlab/classnames 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,13 +35,13 @@ yarn add @jsdevlab/classnames
35
35
  ```ts
36
36
  import { classNames, cx, createClassNames } from '@jsdevlab/classnames';
37
37
 
38
- classNames('btn', 'btn-primary'); // 'btn btn-primary'
38
+ classNames('btn', 'btn-primary'); // 'btn btn-primary'
39
39
  classNames('btn', { 'btn-primary': true, 'is-loading': false }); // 'btn btn-primary'
40
- classNames('btn', ['btn-lg', ['rounded']]); // 'btn btn-lg rounded'
41
- classNames('btn', new Set(['btn-lg', 'rounded'])); // 'btn btn-lg rounded'
42
- classNames('btn', 'btn'); // 'btn'
40
+ classNames('btn', ['btn-lg', ['rounded']]); // 'btn btn-lg rounded'
41
+ classNames('btn', new Set(['btn-lg', 'rounded'])); // 'btn btn-lg rounded'
42
+ classNames('btn', 'btn'); // 'btn'
43
43
 
44
- cx('btn', { disabled: true }); // 'btn disabled'
44
+ cx('btn', { disabled: true }); // 'btn disabled'
45
45
  ```
46
46
 
47
47
  There is **no default export** — use named imports:
@@ -86,8 +86,8 @@ classNames({ zero: 0, one: 1 }); // 'one'
86
86
  Arrays are flattened recursively, and `Set`s are supported directly:
87
87
 
88
88
  ```ts
89
- classNames(['a', ['b', ['c']]]); // 'a b c'
90
- classNames(new Set(['a', 'b'])); // 'a b'
89
+ classNames(['a', ['b', ['c']]]); // 'a b c'
90
+ classNames(new Set(['a', 'b'])); // 'a b'
91
91
  classNames([new Set(['a']), { b: true }]); // 'a b'
92
92
  ```
93
93
 
@@ -128,8 +128,8 @@ import { createClassNames } from '@jsdevlab/classnames';
128
128
 
129
129
  const join = createClassNames({ unique: false });
130
130
 
131
- join('a', 'a'); // 'a a'
132
- classNames('a', 'a'); // 'a'
131
+ join('a', 'a'); // 'a a'
132
+ classNames('a', 'a'); // 'a'
133
133
  ```
134
134
 
135
135
  Options are resolved when the factory is created, so the returned function is
@@ -137,7 +137,7 @@ bound to them:
137
137
 
138
138
  ```ts
139
139
  const cls = createClassNames(); // unique defaults to true
140
- cls('a', 'a'); // 'a'
140
+ cls('a', 'a'); // 'a'
141
141
  ```
142
142
 
143
143
  ### React
@@ -153,12 +153,7 @@ interface ButtonProps {
153
153
  children: ReactNode;
154
154
  }
155
155
 
156
- export function Button({
157
- primary,
158
- loading,
159
- className,
160
- children,
161
- }: ButtonProps) {
156
+ export function Button({ primary, loading, className, children }: ButtonProps) {
162
157
  return (
163
158
  <button
164
159
  className={cx(
@@ -203,7 +198,7 @@ Accepts any mix of supported values and returns a single space-separated class
203
198
  name string. Returns `''` when nothing matches:
204
199
 
205
200
  ```ts
206
- classNames(); // ''
201
+ classNames(); // ''
207
202
  classNames(null, false, undefined); // ''
208
203
  ```
209
204
 
@@ -221,13 +216,13 @@ Returns a `classNames`-style function bound to the given options.
221
216
 
222
217
  #### `ClassNamesOptions`
223
218
 
224
- | Option | Type | Default | Description |
225
- | -------- | --------- | ------- | ------------------------------------------------- |
219
+ | Option | Type | Default | Description |
220
+ | -------- | --------- | ------- | ----------------------------------------------------------- |
226
221
  | `unique` | `boolean` | `true` | Deduplicate class names, preserving first-occurrence order. |
227
222
 
228
223
  ```ts
229
- const defaultJoin = createClassNames(); // unique: true
230
- const keepAll = createClassNames({ unique: false }); // keeps duplicates
224
+ const defaultJoin = createClassNames(); // unique: true
225
+ const keepAll = createClassNames({ unique: false }); // keeps duplicates
231
226
  ```
232
227
 
233
228
  ## Types
@@ -256,18 +251,18 @@ export interface ClassNamesOptions {
256
251
 
257
252
  ## Behavior reference
258
253
 
259
- | Input | Output |
260
- | -------------------------------------------------------------- | ---------- |
261
- | `classNames('a', 'b')` | `'a b'` |
262
- | `classNames('a', '', null, undefined, false, true)` | `'a'` |
263
- | `classNames(0, 1)` | `'0 1'` |
264
- | `classNames({ a: true, b: false, c: 1, d: 0 })` | `'a c'` |
265
- | `classNames(['a', [{ b: true }]])` | `'a b'` |
266
- | `classNames(new Set(['a', 'b']))` | `'a b'` |
267
- | `classNames({ active: () => true, hidden: () => false })` | `'active'` |
268
- | `classNames('a', 'b', 'a')` | `'a b'` |
269
- | `createClassNames({ unique: false })('a', 'a')` | `'a a'` |
270
- | `classNames()` | `''` |
254
+ | Input | Output |
255
+ | --------------------------------------------------------- | ---------- |
256
+ | `classNames('a', 'b')` | `'a b'` |
257
+ | `classNames('a', '', null, undefined, false, true)` | `'a'` |
258
+ | `classNames(0, 1)` | `'0 1'` |
259
+ | `classNames({ a: true, b: false, c: 1, d: 0 })` | `'a c'` |
260
+ | `classNames(['a', [{ b: true }]])` | `'a b'` |
261
+ | `classNames(new Set(['a', 'b']))` | `'a b'` |
262
+ | `classNames({ active: () => true, hidden: () => false })` | `'active'` |
263
+ | `classNames('a', 'b', 'a')` | `'a b'` |
264
+ | `createClassNames({ unique: false })('a', 'a')` | `'a a'` |
265
+ | `classNames()` | `''` |
271
266
 
272
267
  ## Notes and edge cases
273
268
 
@@ -295,18 +290,18 @@ export interface ClassNamesOptions {
295
290
  +import { classNames } from '@jsdevlab/classnames';
296
291
  ```
297
292
 
298
- | Capability | `classnames` | `@jsdevlab/classnames` |
299
- | ----------------------------------- | ------------------------------- | ----------------------------------- |
300
- | Strings / numbers | ✅ | ✅ |
301
- | Objects with truthy keys | ✅ | ✅ |
302
- | Nested arrays | ✅ | ✅ |
303
- | Skips `null` / `undefined` / `false` / `''` | ✅ | ✅ |
304
- | `Set` input | — | ✅ |
305
- | Function values in objects | Not evaluated (functions are truthy) | Evaluated at call time |
306
- | Duplicate removal | via `classnames/dedupe` | Default |
307
- | Keep duplicates | Default | `createClassNames({ unique: false })` |
308
- | Custom separator | — | — |
309
- | Default export | ✅ | — (named exports only) |
293
+ | Capability | `classnames` | `@jsdevlab/classnames` |
294
+ | ------------------------------------------- | ------------------------------------ | ------------------------------------- |
295
+ | Strings / numbers | ✅ | ✅ |
296
+ | Objects with truthy keys | ✅ | ✅ |
297
+ | Nested arrays | ✅ | ✅ |
298
+ | Skips `null` / `undefined` / `false` / `''` | ✅ | ✅ |
299
+ | `Set` input | — | ✅ |
300
+ | Function values in objects | Not evaluated (functions are truthy) | Evaluated at call time |
301
+ | Duplicate removal | via `classnames/dedupe` | Default |
302
+ | Keep duplicates | Default | `createClassNames({ unique: false })` |
303
+ | Custom separator | — | — |
304
+ | Default export | ✅ | — (named exports only) |
310
305
 
311
306
  If you relied on the default duplicate-preserving behavior of `classnames`, bind
312
307
  your own instance:
@@ -319,11 +314,11 @@ const classNames = createClassNames({ unique: false });
319
314
 
320
315
  ## Module formats
321
316
 
322
- | Format | File |
323
- | ---------- | ------------------ |
324
- | ESM | `dist/index.js` |
325
- | CommonJS | `dist/index.cjs` |
326
- | TypeScript | `dist/index.d.ts` |
317
+ | Format | File |
318
+ | ---------- | ----------------- |
319
+ | ESM | `dist/index.js` |
320
+ | CommonJS | `dist/index.cjs` |
321
+ | TypeScript | `dist/index.d.ts` |
327
322
 
328
323
  ```ts
329
324
  // ESM
@@ -342,12 +337,18 @@ Requires Node.js ≥ 24.19 and pnpm 12.18.
342
337
 
343
338
  ```bash
344
339
  pnpm install
345
- pnpm test # tsc --noEmit + rstest
346
- pnpm build # rslib build → dist/
347
- pnpm check # Biome lint + fix
348
- pnpm format # Biome format + fix
340
+ pnpm test # tsc --noEmit + Node test suite
341
+ pnpm test:browser # same suite in real Chromium
342
+ pnpm test:all # Node + browser suites
343
+ pnpm build # rslib build → dist/
344
+ pnpm check # Biome lint + fix
345
+ pnpm format # Biome format + fix
349
346
  ```
350
347
 
348
+ Browser tests download Chromium once with
349
+ `pnpm exec playwright install chromium`; they are kept separate from
350
+ `pnpm test` so the default suite stays fast.
351
+
351
352
  Releases are managed with [changesets](https://github.com/changesets/changesets):
352
353
 
353
354
  ```bash
package/README.zh-CN.md CHANGED
@@ -35,13 +35,13 @@ yarn add @jsdevlab/classnames
35
35
  ```ts
36
36
  import { classNames, cx, createClassNames } from '@jsdevlab/classnames';
37
37
 
38
- classNames('btn', 'btn-primary'); // 'btn btn-primary'
38
+ classNames('btn', 'btn-primary'); // 'btn btn-primary'
39
39
  classNames('btn', { 'btn-primary': true, 'is-loading': false }); // 'btn btn-primary'
40
- classNames('btn', ['btn-lg', ['rounded']]); // 'btn btn-lg rounded'
41
- classNames('btn', new Set(['btn-lg', 'rounded'])); // 'btn btn-lg rounded'
42
- classNames('btn', 'btn'); // 'btn'
40
+ classNames('btn', ['btn-lg', ['rounded']]); // 'btn btn-lg rounded'
41
+ classNames('btn', new Set(['btn-lg', 'rounded'])); // 'btn btn-lg rounded'
42
+ classNames('btn', 'btn'); // 'btn'
43
43
 
44
- cx('btn', { disabled: true }); // 'btn disabled'
44
+ cx('btn', { disabled: true }); // 'btn disabled'
45
45
  ```
46
46
 
47
47
  本包**没有默认导出**,请使用具名导入:
@@ -86,8 +86,8 @@ classNames({ zero: 0, one: 1 }); // 'one'
86
86
  数组会被递归展平,同时也直接支持 `Set`:
87
87
 
88
88
  ```ts
89
- classNames(['a', ['b', ['c']]]); // 'a b c'
90
- classNames(new Set(['a', 'b'])); // 'a b'
89
+ classNames(['a', ['b', ['c']]]); // 'a b c'
90
+ classNames(new Set(['a', 'b'])); // 'a b'
91
91
  classNames([new Set(['a']), { b: true }]); // 'a b'
92
92
  ```
93
93
 
@@ -126,15 +126,15 @@ import { createClassNames } from '@jsdevlab/classnames';
126
126
 
127
127
  const join = createClassNames({ unique: false });
128
128
 
129
- join('a', 'a'); // 'a a'
130
- classNames('a', 'a'); // 'a'
129
+ join('a', 'a'); // 'a a'
130
+ classNames('a', 'a'); // 'a'
131
131
  ```
132
132
 
133
133
  选项在创建工厂时解析,返回的函数会绑定这些选项:
134
134
 
135
135
  ```ts
136
136
  const cls = createClassNames(); // unique 默认为 true
137
- cls('a', 'a'); // 'a'
137
+ cls('a', 'a'); // 'a'
138
138
  ```
139
139
 
140
140
  ### React
@@ -150,12 +150,7 @@ interface ButtonProps {
150
150
  children: ReactNode;
151
151
  }
152
152
 
153
- export function Button({
154
- primary,
155
- loading,
156
- className,
157
- children,
158
- }: ButtonProps) {
153
+ export function Button({ primary, loading, className, children }: ButtonProps) {
159
154
  return (
160
155
  <button
161
156
  className={cx(
@@ -200,7 +195,7 @@ defineProps<{ active?: boolean; disabled?: boolean }>();
200
195
  `''`:
201
196
 
202
197
  ```ts
203
- classNames(); // ''
198
+ classNames(); // ''
204
199
  classNames(null, false, undefined); // ''
205
200
  ```
206
201
 
@@ -218,12 +213,12 @@ cx('a', { b: true }); // 'a b'
218
213
 
219
214
  #### `ClassNamesOptions`
220
215
 
221
- | 选项 | 类型 | 默认值 | 说明 |
222
- | -------- | --------- | ------ | -------------------------------------- |
223
- | `unique` | `boolean` | `true` | 对类名去重,保留首次出现的顺序。 |
216
+ | 选项 | 类型 | 默认值 | 说明 |
217
+ | -------- | --------- | ------ | -------------------------------- |
218
+ | `unique` | `boolean` | `true` | 对类名去重,保留首次出现的顺序。 |
224
219
 
225
220
  ```ts
226
- const defaultJoin = createClassNames(); // unique: true
221
+ const defaultJoin = createClassNames(); // unique: true
227
222
  const keepAll = createClassNames({ unique: false }); // 保留重复项
228
223
  ```
229
224
 
@@ -253,18 +248,18 @@ export interface ClassNamesOptions {
253
248
 
254
249
  ## 行为参考
255
250
 
256
- | 输入 | 输出 |
257
- | -------------------------------------------------------------- | ---------- |
258
- | `classNames('a', 'b')` | `'a b'` |
259
- | `classNames('a', '', null, undefined, false, true)` | `'a'` |
260
- | `classNames(0, 1)` | `'0 1'` |
261
- | `classNames({ a: true, b: false, c: 1, d: 0 })` | `'a c'` |
262
- | `classNames(['a', [{ b: true }]])` | `'a b'` |
263
- | `classNames(new Set(['a', 'b']))` | `'a b'` |
264
- | `classNames({ active: () => true, hidden: () => false })` | `'active'` |
265
- | `classNames('a', 'b', 'a')` | `'a b'` |
266
- | `createClassNames({ unique: false })('a', 'a')` | `'a a'` |
267
- | `classNames()` | `''` |
251
+ | 输入 | 输出 |
252
+ | --------------------------------------------------------- | ---------- |
253
+ | `classNames('a', 'b')` | `'a b'` |
254
+ | `classNames('a', '', null, undefined, false, true)` | `'a'` |
255
+ | `classNames(0, 1)` | `'0 1'` |
256
+ | `classNames({ a: true, b: false, c: 1, d: 0 })` | `'a c'` |
257
+ | `classNames(['a', [{ b: true }]])` | `'a b'` |
258
+ | `classNames(new Set(['a', 'b']))` | `'a b'` |
259
+ | `classNames({ active: () => true, hidden: () => false })` | `'active'` |
260
+ | `classNames('a', 'b', 'a')` | `'a b'` |
261
+ | `createClassNames({ unique: false })('a', 'a')` | `'a a'` |
262
+ | `classNames()` | `''` |
268
263
 
269
264
  ## 注意事项与边界情况
270
265
 
@@ -289,18 +284,18 @@ export interface ClassNamesOptions {
289
284
  +import { classNames } from '@jsdevlab/classnames';
290
285
  ```
291
286
 
292
- | 能力 | `classnames` | `@jsdevlab/classnames` |
293
- | ----------------------------------- | ------------------------------------ | ----------------------------------------- |
294
- | 字符串 / 数字 | ✅ | ✅ |
295
- | 值为真值的对象 | ✅ | ✅ |
296
- | 嵌套数组 | ✅ | ✅ |
297
- | 跳过 `null` / `undefined` / `false` / `''` | ✅ | ✅ |
298
- | `Set` 输入 | — | ✅ |
299
- | 对象中的函数值 | 不求值(函数本身为真值) | 在调用时求值 |
300
- | 移除重复项 | 通过 `classnames/dedupe` | 默认行为 |
301
- | 保留重复项 | 默认行为 | `createClassNames({ unique: false })` |
302
- | 自定义分隔符 | — | — |
303
- | 默认导出 | ✅ | —(仅具名导出) |
287
+ | 能力 | `classnames` | `@jsdevlab/classnames` |
288
+ | ------------------------------------------ | ------------------------ | ------------------------------------- |
289
+ | 字符串 / 数字 | ✅ | ✅ |
290
+ | 值为真值的对象 | ✅ | ✅ |
291
+ | 嵌套数组 | ✅ | ✅ |
292
+ | 跳过 `null` / `undefined` / `false` / `''` | ✅ | ✅ |
293
+ | `Set` 输入 | — | ✅ |
294
+ | 对象中的函数值 | 不求值(函数本身为真值) | 在调用时求值 |
295
+ | 移除重复项 | 通过 `classnames/dedupe` | 默认行为 |
296
+ | 保留重复项 | 默认行为 | `createClassNames({ unique: false })` |
297
+ | 自定义分隔符 | — | — |
298
+ | 默认导出 | ✅ | —(仅具名导出) |
304
299
 
305
300
  如果你的代码依赖 `classnames` 默认保留重复项的行为,可以绑定自己的实例:
306
301
 
@@ -312,11 +307,11 @@ const classNames = createClassNames({ unique: false });
312
307
 
313
308
  ## 模块格式
314
309
 
315
- | 格式 | 文件 |
316
- | ---------- | ------------------ |
317
- | ESM | `dist/index.js` |
318
- | CommonJS | `dist/index.cjs` |
319
- | TypeScript | `dist/index.d.ts` |
310
+ | 格式 | 文件 |
311
+ | ---------- | ----------------- |
312
+ | ESM | `dist/index.js` |
313
+ | CommonJS | `dist/index.cjs` |
314
+ | TypeScript | `dist/index.d.ts` |
320
315
 
321
316
  ```ts
322
317
  // ESM
@@ -334,12 +329,18 @@ const { classNames } = require('@jsdevlab/classnames');
334
329
 
335
330
  ```bash
336
331
  pnpm install
337
- pnpm test # tsc --noEmit + rstest
338
- pnpm build # rslib 构建 → dist/
339
- pnpm check # Biome 检查并修复
340
- pnpm format # Biome 格式化并修复
332
+ pnpm test # tsc --noEmit + Node 测试套件
333
+ pnpm test:browser # 在真实 Chromium 中运行同一套测试
334
+ pnpm test:all # Node + 浏览器测试
335
+ pnpm build # rslib 构建 → dist/
336
+ pnpm check # Biome 检查并修复
337
+ pnpm format # Biome 格式化并修复
341
338
  ```
342
339
 
340
+ 浏览器测试首次运行前需执行
341
+ `pnpm exec playwright install chromium` 下载 Chromium;它与 `pnpm test`
342
+ 分开,以保持默认测试套件轻快。
343
+
343
344
  发布流程使用 [changesets](https://github.com/changesets/changesets):
344
345
 
345
346
  ```bash
package/dist/index.cjs CHANGED
@@ -30,9 +30,12 @@ __webpack_require__.r(__webpack_exports__);
30
30
  const DEFAULT_OPTIONS = {
31
31
  unique: true
32
32
  };
33
- const resolveOptions = (options)=>({
34
- unique: options?.unique ?? DEFAULT_OPTIONS.unique
35
- });
33
+ const resolveOptions = (options)=>{
34
+ var _ref;
35
+ return {
36
+ unique: null != (_ref = null == options ? void 0 : options.unique) ? _ref : DEFAULT_OPTIONS.unique
37
+ };
38
+ };
36
39
  const collect = (value, parts)=>{
37
40
  if (null == value || false === value || true === value) return;
38
41
  if ('string' == typeof value || 'number' == typeof value) {
@@ -72,10 +75,9 @@ function createClassNames(options) {
72
75
  const resolved = resolveOptions(options);
73
76
  return (...values)=>classNamesImpl(values, resolved);
74
77
  }
75
- __webpack_require__.d(__webpack_exports__, {
76
- classNames: ()=>classNames,
77
- createClassNames: ()=>createClassNames
78
- }, {
78
+ __webpack_require__.d(__webpack_exports__, {}, {
79
+ classNames: classNames,
80
+ createClassNames: createClassNames,
79
81
  cx: cx
80
82
  });
81
83
  exports.classNames = __webpack_exports__.classNames;
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
1
  const DEFAULT_OPTIONS = {
2
2
  unique: true
3
3
  };
4
- const resolveOptions = (options)=>({
5
- unique: options?.unique ?? DEFAULT_OPTIONS.unique
6
- });
4
+ const resolveOptions = (options)=>{
5
+ var _ref;
6
+ return {
7
+ unique: null != (_ref = null == options ? void 0 : options.unique) ? _ref : DEFAULT_OPTIONS.unique
8
+ };
9
+ };
7
10
  const collect = (value, parts)=>{
8
11
  if (null == value || false === value || true === value) return;
9
12
  if ('string' == typeof value || 'number' == typeof value) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@jsdevlab/classnames",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "private": false,
5
- "description": "Type-safe classnames utility — conditional classes with lazy evaluation, dedup, and separator factory. Framework-agnostic.",
5
+ "description": "Type-safe classnames utility — conditional classes with lazy evaluation and deduplication by default. Framework-agnostic.",
6
6
  "keywords": [],
7
7
  "repository": {
8
8
  "type": "git",
@@ -19,19 +19,11 @@
19
19
  },
20
20
  "main": "./dist/index.cjs",
21
21
  "types": "./dist/index.d.ts",
22
- "files": ["dist", "README.md", "README.zh-CN.md"],
23
- "scripts": {
24
- "build": "rslib",
25
- "changeset": "changeset",
26
- "check": "biome check --write",
27
- "dev": "rslib --watch",
28
- "format": "biome format --write",
29
- "prepare": "simple-git-hooks",
30
- "release": "changeset publish",
31
- "test": "tsc --noEmit && rstest",
32
- "test:watch": "rstest --watch",
33
- "version": "changeset version"
34
- },
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "README.zh-CN.md"
26
+ ],
35
27
  "simple-git-hooks": {
36
28
  "pre-commit": "pnpm check",
37
29
  "pre-push": "pnpm format"
@@ -40,15 +32,16 @@
40
32
  "@biomejs/biome": "^2.6.6",
41
33
  "@changesets/changelog-github": "^1.0.1",
42
34
  "@changesets/cli": "^3.0.1",
43
- "@rslib/core": "^0.23.2",
44
- "@rstest/adapter-rslib": "^0.11.9",
45
- "@rstest/core": "^0.11.9",
46
- "@rstest/coverage-v8": "^0.11.9",
35
+ "@rslib/core": "^1.0.6",
36
+ "@rstest/adapter-rslib": "^0.12.6",
37
+ "@rstest/browser": "^0.12.6",
38
+ "@rstest/core": "^0.12.6",
39
+ "@rstest/coverage-v8": "^0.12.6",
47
40
  "@types/node": "^24.13.3",
41
+ "playwright": "^1.65.0",
48
42
  "simple-git-hooks": "^2.14.0",
49
43
  "typescript": "^6.0.3"
50
44
  },
51
- "packageManager": "pnpm@12.18.0+sha512.9d7882d5dc82147ecfc4e062aa34834e0ad0296710a1837a1115ae012127d36b7109e321ac1598a1dd0a65597681b1e99917e12ed0d749eae91187943363beb3",
52
45
  "devEngines": {
53
46
  "runtime": {
54
47
  "name": "node",
@@ -59,5 +52,18 @@
59
52
  "publishConfig": {
60
53
  "access": "public",
61
54
  "registry": "https://registry.npmjs.org/"
55
+ },
56
+ "scripts": {
57
+ "build": "rslib",
58
+ "changeset": "changeset",
59
+ "check": "biome check --write",
60
+ "dev": "rslib --watch",
61
+ "format": "biome format --write",
62
+ "release": "changeset publish",
63
+ "test": "tsc --noEmit && rstest run",
64
+ "test:all": "pnpm test && pnpm test:browser",
65
+ "test:browser": "rstest run --browser.enabled",
66
+ "test:watch": "rstest watch",
67
+ "version": "changeset version"
62
68
  }
63
- }
69
+ }