Skip to content

fix(search): accept unknown future SearchIndexStatus values (MZ-17) - #15

Merged
rockyshi1993 merged 2 commits into
mainfrom
fix/mz17-search-index-status
Nov 12, 2026
Merged

rockyshi1993 merged 2 commits into
mainfrom
fix/mz17-search-index-status

Conversation

@rockyshi1993

@rockyshi1993 rockyshi1993 commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

MZ-17: the public SearchIndexStatus type was a closed seven-literal union, while normalizeSearchIndexInfo already passes unknown future server statuses through unchanged (only missing/empty/non-string values become PENDING). This made legal runtime values unrepresentable in TypeScript.

Design decision (candidate A): introduce KnownSearchIndexStatus for the documented literals and define SearchIndexStatus = KnownSearchIndexStatus | (string & {}). Autocomplete is preserved; unknown strings such as PAUSED_BY_SERVER are assignable. Unknown values are never rewritten to PENDING. waitForSearchIndex defaults and READY / queryable semantics are unchanged.

Rejected candidate B (status: SearchIndexStatus | (string & {}) only on SearchIndexInfo, leaving SearchIndexStatus closed) because standalone uses of the public status type would still reject future values. Rejected candidate C (status: string) because it drops literal autocomplete.

isKnownSearchIndexStatus is now a type predicate and is re-exported from the internal search-indexes barrel for unit tests only. It is not a new public runtime API (confirmed absent from dist/cjs/index.cjs / package exports). A public runtime guard can be considered later if reviewers want it.

No version bump, no npm publish, no GitHub Actions changes.

SHAs

  • Base (current main): 80da4d733be421a6ea8e68daca6c101e62268a28
  • Head: 81a7d2195e9e973de9e1dae0df4265ece03a909a

File changes

  • types/search-index.d.ts — KnownSearchIndexStatus + open SearchIndexStatus
  • src/adapters/mongodb/search-indexes/types.ts — re-export the new type
  • src/adapters/mongodb/search-indexes/normalize.ts — drop the as SearchIndexStatus assertion; type-guard predicate
  • src/adapters/mongodb/search-indexes/index.ts — internal export of the helper (tests only)
  • test/types/search-index-usage.test-d.ts — future status assignable; known union still rejects it
  • test/unit/search-indexes/search-indexes.test.ts — passthrough, known literals, empty/missing → PENDING, wait behavior for unknown status
  • docs/en/search-indexes.md, docs/zh/search-indexes.md
  • changelogs/unreleased.md — candidate note only; package remains 3.5.3

Tests actually run (this machine)

Environment: Linux, Node v24.22.1, npm 11.21.1, local mongodb driver 6.21.0 (from this checkout’s package). Commands run after the commit contents were in the working tree; dist was produced by npm run build on this branch.

npm run lint                 # 0 errors (206 pre-existing warnings)
npm run build
npm run build:tests
node --test .generated/test-dist/test/unit/search-indexes/search-indexes.test.js
  # 47 tests, 47 pass, 0 fail  (includes 5 new MZ-17 cases)
npx tsc -p tsconfig.json --noEmit
npx tsd --files test/types/root-import.test-d.ts --files test/types/cache-usage.test-d.ts \
  --files test/types/model-usage.test-d.ts --files test/types/pool-usage.test-d.ts \
  --files test/types/sync-usage.test-d.ts --files test/types/slow-query-log-usage.test-d.ts \
  --files test/types/saga-usage.test-d.ts --files test/types/data-tasks-usage.test-d.ts \
  --files test/types/search-index-usage.test-d.ts --files test/types/gridfs-usage.test-d.ts
npm run check:package-budgets
  # dist/cjs/index.cjs: 887250/890000
  # dist/esm/index.mjs: 884533/887000
  # dist/cjs/cli/data-task.cjs: 20319/50000
npm run check:docs-examples  # 112/112
npm run check:doc-claims
npm run check:test-language
npm run check:error-contract
npm run check:current-version

All of the commands above exited 0. GitHub Actions CI for this PR is not claimed here; it will run after open.

Not run on this PR (out of scope / no environment): Search/Vector Search real deployments (Atlas, atlas-local, Community+mongot, Enterprise+mongot); Node 18/20/22 × Driver 6/7 × MongoDB 7/8 matrix. Those remain on main evidence for SHA 80da4d7 as documented in the handoff, and should be judged from this PR’s CI jobs once they finish.

Risks

  • Additive public type KnownSearchIndexStatus (compatible). Existing SearchIndexStatus remains assignable from the seven literals.
  • Exhaustive switch on SearchIndexStatus in downstream TypeScript may now require a default branch. That is the intended correction.
  • No runtime wait-policy change: unknown statuses are not treated as FAILED or READY; until: 'queryable' still succeeds when queryable === true.
  • Internal barrel export does not change the published CJS/ESM public surface.

Please do not merge yet

This PR is ready for independent review (ChatGPT / R1). Do not merge until that review passes and the existing merge authorization is applied by the reviewer.


Note

Low Risk
Additive typing and documentation; runtime wait/queryable semantics are unchanged aside from clearer tests and docs. Downstream exhaustive switches on SearchIndexStatus may need a default branch.

Overview
MZ-17 aligns the public TypeScript model with runtime behavior: server-reported search index statuses are no longer limited to a closed seven-literal union.

A new exported type KnownSearchIndexStatus holds the documented literals, while SearchIndexStatus becomes KnownSearchIndexStatus | (string & {}) so values like PAUSED_BY_SERVER are typable without losing autocomplete on known statuses. Normalization still maps only empty, missing, or non-string statuses to PENDING; unknown strings pass through unchanged. isKnownSearchIndexStatus is now a type predicate and is exposed only on the internal adapter barrel for tests.

Type tests, unit coverage for passthrough and waitForSearchIndex with unknown statuses, bilingual Search docs, and an unreleased changelog note accompany the type/export tweaks.

Reviewed by Cursor Bugbot for commit 8eec9f1. Bugbot is set up for automated code reviews on this repo. Configure here.

Align the public SearchIndexStatus type with the runtime passthrough of
unknown server statuses. Export KnownSearchIndexStatus for documented
literals, keep wait defaults and READY/queryable semantics unchanged,
and cover the contract with tsd, unit, and bilingual docs.

Copy link
Copy Markdown
Contributor Author

独立复审 R1 — MZ-17 (PR #15)

结论:REQUEST_CHANGES(1 项 P2 文档契约不一致;未发现核心类型实现阻断)
基线:base 80da4d733be421a6ea8e68daca6c101e62268a28,head 81a7d2195e9e973de9e1dae0df4265ece03a909a。

已核验且认可

  • types/search-index.d.ts:17-30,43-45:公开 KnownSearchIndexStatus 保留 7 种状态,SearchIndexStatus = KnownSearchIndexStatus | (string & {}) 接受服务端未知状态,和运行时一致。
  • normalize.ts:13-20,35-37:去掉错误的强制断言;未知字符串原样透传,缺失/空/非字符串 fallback PENDING;类型守卫限定已知集。
  • src/adapters/mongodb/search-indexes/index.ts 是内部 barrel;src/entry/index.ts / index.mts 未将 helper 公开导出;types/index.d.ts 有 export * from './search-index',新类型可从 package root 获取。
  • tsd、5 项补充运行时用例及原 wait 测试覆盖合理。当前 PR HEAD 的 CI Node 18/20/22 均 success;GridFS 7.0.37/8.0.26 均 success;Release Gate 此次检查时仍 running,不计 PASS。
  • 公共类型由封闭 union 变宽会让依赖穷尽 switch 的下游代码需要 default;PR 已说明这一合理的纠偏影响。

P2 / 需要修复:英文/中文新加说明与实际 wait 策略矛盾

  • docs/en/search-indexes.md:113 与 docs/zh/search-indexes.md:113 新增描述认为 waitForSearchIndex 在 ready / queryable 中只把 READY 和 FAILED 视为终态。这对 until:'queryable' 不准确。
  • 真实源码 src/adapters/mongodb/search-indexes/operations.ts:258-275:
    • until:'queryable' 以 info.queryable === true 为成功条件,与 status 字面量无关(即使是 FAILED、PAUSED_BY_SERVER 也可以成功)。
    • queryable === false && status === 'FAILED' 才拒绝;status === 'READY' && queryable === false 不会立即成功。
    • until:'ready' 是 status === 'READY' 成功,FAILED 失败。
    • until:'dropped' 是 DOES_NOT_EXIST 成功,FAILED 继续等待。
  • 同一文档紧接着 :123-131 的原有表格其实正确,与这次新句直接矛盾。建议删除“只把 READY 和 FAILED 当作 ready/queryable 终态”的合并表述,改为分别说明 queryable、ready 和 dropped 三种条件;中英文同步。
  • 建议顺便补一句 SearchIndexStatus TS 类型本身允许 '',但 normalizeSearchIndexInfo 会把空输入规范化为 PENDING,以免将类型宽化误写成类型层面保证“非空”。

R2 通过条件

  1. 只修订上述两处文档(若需同步示例则解释);保持本 PR 的 runtime 等待逻辑不变。
  2. 运行 npm run check:docs-examples + npm run check:doc-claims,提供 PR 最新 HEAD SHA 的结果;若本轮改动导致 CI 重新触发,核对相关 Job。
  3. 提交更新后的 commit,回复此审查意见并请求 R2。本轮暂不建议合并 main。

其他 MZ-02/03/06/07/09/13 问题属于独立工作,本 PR 不要求顺带实现。

注:本条为独立复审 R1 记录,需按上述项修复后再考虑合并。

Split the queryable, ready, and dropped wait conditions so they match
operations.ts. Note that SearchIndexStatus can type an empty string while
normalizeSearchIndexInfo still maps empty, missing, or non-string input
to PENDING. Runtime wait logic is unchanged.

Copy link
Copy Markdown
Contributor Author

独立复审 R2 — PASS(MZ-17)

复审基线:base 80da4d733be421a6ea8e68daca6c101e62268a28,head 8eec9f1374ef89c977d1c909b22f1e627f019a64。

R1 返工核对

  • 对比 81a7d2195e9e973de9e1dae0df4265ece03a909a...8eec9f1374ef89c977d1c909b22f1e627f019a64:仅改 docs/en/search-indexes.md 与 docs/zh/search-indexes.md,没有源码/公开类型/测试变更。
  • 新增中英文文档分别描述 until:'queryable'(queryable=true 成功,即使 status 为 FAILED 或未知)、until:'ready'(READY 成功、FAILED 拒绝)、until:'dropped'(DOES_NOT_EXIST 成功)及其失败分支,与 operations.ts:258-275 一致。
  • 说明 TS 开放字符串类型可表示 ''、运行时规范化将空/缺失/非字符串输入映射 PENDING,已消除 R1 提出的不准确表述。
  • 公共 KnownSearchIndexStatus / SearchIndexStatus 声明、CJS/ESM 导出边界与 tsd / Search 单元测试沿用 R1 已审正确实现。

证据

  • 精确 head 8eec9f1374ef89c977d1c909b22f1e627f019a64 Node 18/20/22 CI jobs 均 success;GridFS MongoDB 7.0.37 和 8.0.26 safety jobs success。
  • Full release-gate 当前仍运行中;不计作通过。它是发布级门禁,本轮为纯文档返工,本次以用户既有授权的静态复审与已通过分项测试作为合并依据。

R2 判定:PASS,无 P0/P1/P2 阻断。建议 squash merge main。 不发布 npm、不打 Tag、不改变版本。

@rockyshi1993
rockyshi1993 merged commit 693f214 into main Nov 12, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant