@aiao/rxdb-plugin-search-react 0.0.20 → 0.0.21

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/REVIEW.md ADDED
@@ -0,0 +1,23 @@
1
+ # `@aiao/rxdb-plugin-search-react` 代码评审
2
+
3
+ ## 结论
4
+
5
+ 🔴 不通过。`useSearch()` 宣称 source 变化时重建 handle,但实际把首次 source 永久锁进 ref;组件切换数据库/collection 后仍订阅和查询旧 source。
6
+
7
+ ## 评审基线
8
+
9
+ - 基线提交:`03a46a5d5992a958c19ae33d5fed15c9c3322021`
10
+ - 评审日期:2026-07-14
11
+ - 范围:React 搜索 hook、测试、公开入口;10 个文件,约 311 行 TS
12
+ - 自动校验:`lint`、`test`、`typecheck`、`build` 全部通过
13
+
14
+ ## 问题
15
+
16
+ | ID | 级别 | 位置 | 问题与影响 | 建议 |
17
+ | --- | --- | --- | --- | --- |
18
+ | SEARCH-REACT-001 | P1 | `src/use-search.ts:67` | `handleRef` 只在 null 时用 source 创建,订阅 effect 的依赖数组为空;rerender 传入新 source/options 时,hook 仍对旧 handle 调用 setQuery/loadMore,并显示旧数据库结果。源码注释“仅在 source 变化时重建”与实现相反。 | 用 source/稳定 options key 作为 handle 生命周期依赖,切换时先取消旧订阅并 destroy 旧 handle;增加 rerender source A→B 后只能调用 B 的测试。 |
19
+
20
+ ## 三端对称性
21
+
22
+ - 共享类型透传与 Vue/Angular 一致;运行时入口 `useSearch` 符合 React 约定。
23
+ - source 切换语义目前不可靠,是此三端组唯一 P1。
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
+ export type { SearchExecutionError, SearchHandle, SearchOptions, SearchResult, SearchState } from '@aiao/rxdb-plugin-search';
8
9
  export { useSearch } from './use-search.js';
9
10
  export type { SearchSourceLike, UseSearchReturn } from './use-search.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -2,24 +2,35 @@
2
2
  import { useCallback as e, useEffect as t, useMemo as n, useRef as r, useState as i } from "react";
3
3
  import { Subscription as a } from "rxjs";
4
4
  //#region src/use-search.ts
5
- function o(o, s) {
6
- let c = s?.initialQuery ?? "", l = r(null), u = r(null);
7
- l.current === null && (l.current = o.search(c, s));
8
- let d = l.current, [f, p] = i(c), [m, h] = i([]), [g, _] = i("idle"), [v, y] = i(void 0), [b, x] = i(!1);
5
+ function o(e, t) {
6
+ return e === t ? !0 : e === void 0 || t === void 0 || e.length !== t.length ? !1 : e.every((e, n) => e === t[n]);
7
+ }
8
+ function s(e, t) {
9
+ return e === t ? !0 : e === void 0 || t === void 0 ? !1 : e.debounce === t.debounce && e.pageSize === t.pageSize && e.snippetLength === t.snippetLength && e.initialQuery === t.initialQuery && o(e.collections, t.collections);
10
+ }
11
+ function c(e) {
12
+ let t = r(e);
13
+ return s(t.current, e) || (t.current = e), t.current;
14
+ }
15
+ function l(o, s) {
16
+ let l = c(s), u = l?.initialQuery ?? "", d = r(null), [f, p] = i(u), [m, h] = i([]), [g, _] = i("idle"), [v, y] = i(void 0), [b, x] = i(!1);
9
17
  t(() => {
10
- u.current !== null && (clearTimeout(u.current), u.current = null);
11
- let e = new a();
12
- return e.add(d.results$.subscribe((e) => h(e))), e.add(d.state$.subscribe((e) => _(e))), e.add(d.error$.subscribe((e) => y(e))), e.add(d.hasMore$.subscribe((e) => x(e))), () => {
13
- e.unsubscribe(), u.current = setTimeout(() => {
14
- d.destroy(), l.current = null, u.current = null;
15
- }, 0);
18
+ let e = o.search(u, l);
19
+ d.current = e, p(u);
20
+ let t = new a();
21
+ return t.add(e.results$.subscribe((e) => h(e))), t.add(e.state$.subscribe((e) => _(e))), t.add(e.error$.subscribe((e) => y(e))), t.add(e.hasMore$.subscribe((e) => x(e))), () => {
22
+ t.unsubscribe(), e.destroy(), d.current === e && (d.current = null);
16
23
  };
17
- }, []);
24
+ }, [
25
+ o,
26
+ l,
27
+ u
28
+ ]);
18
29
  let S = e((e) => {
19
- p(e), d.setQuery(e);
20
- }, [d]), C = e(() => {
21
- p(""), d.clear();
22
- }, [d]), w = e(() => d.retry(), [d]), T = e(() => d.loadMore(), [d]);
30
+ p(e), d.current?.setQuery(e);
31
+ }, []), C = e(() => {
32
+ p(""), d.current?.clear();
33
+ }, []), w = e(() => d.current?.retry(), []), T = e(() => d.current?.loadMore() ?? Promise.resolve(), []);
23
34
  return n(() => ({
24
35
  query: f,
25
36
  setQuery: S,
@@ -43,4 +54,4 @@ function o(o, s) {
43
54
  ]);
44
55
  }
45
56
  //#endregion
46
- export { o as useSearch };
57
+ export { l as useSearch };
@@ -1,4 +1,4 @@
1
- import { SearchExecutionError, SearchOptions, SearchResult, SearchSourceLike, SearchState } from '../packages/rxdb-plugin-search/src/index.ts';
1
+ import { SearchExecutionError, SearchOptions, SearchResult, SearchSourceLike, SearchState } from '@aiao/rxdb-plugin-search';
2
2
  /**
3
3
  * React 集成 - rxdb-plugin-search
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"use-search.d.ts","sourceRoot":"","sources":["../src/use-search.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,oBAAoB,EAEpB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAElC;;;;;;;GAOG;AAEH,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW;IACX,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,WAAW;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,eAAe;IACf,KAAK,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACxC,cAAc;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sBAAsB;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,oBAAoB;IACpB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,eAAe,CA0D5F"}
1
+ {"version":3,"file":"use-search.d.ts","sourceRoot":"","sources":["../src/use-search.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,oBAAoB,EAEpB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAElC;;;;;;;GAOG;AAEH,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW;IACX,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,WAAW;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,eAAe;IACf,KAAK,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACxC,cAAc;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,sBAAsB;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,oBAAoB;IACpB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AA0BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,eAAe,CAgD5F"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=use-search.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-search.spec.d.ts","sourceRoot":"","sources":["../../../src/use-search.spec.ts"],"names":[],"mappings":""}