@harperfast/harper 5.3.0-beta.3 → 5.3.0-beta.4

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.
Files changed (311) hide show
  1. package/bin/cliOperations.ts +25 -3
  2. package/bin/run.ts +18 -0
  3. package/components/Application.ts +52 -78
  4. package/components/DESIGN.md +76 -3
  5. package/components/Scope.ts +10 -4
  6. package/components/anthropic/index.ts +10 -1
  7. package/components/bedrock/index.ts +10 -1
  8. package/components/componentLoader.ts +23 -14
  9. package/components/mcp/tools/operations.ts +3 -1
  10. package/components/ollama/index.ts +10 -1
  11. package/components/openai/index.ts +265 -18
  12. package/components/operations.js +40 -1
  13. package/config/configUtils.ts +3 -19
  14. package/dataLayer/DESIGN.md +29 -5
  15. package/dataLayer/harperBridge/ResourceBridge.ts +39 -3
  16. package/dataLayer/restoreMarker.ts +250 -14
  17. package/dataLayer/schema.ts +2 -7
  18. package/dataLayer/schemaDescribe.ts +10 -0
  19. package/dist/bin/cliOperations.js +28 -3
  20. package/dist/bin/cliOperations.js.map +1 -1
  21. package/dist/bin/run.js +19 -0
  22. package/dist/bin/run.js.map +1 -1
  23. package/dist/components/Application.d.ts +8 -2
  24. package/dist/components/Application.js +43 -69
  25. package/dist/components/Application.js.map +1 -1
  26. package/dist/components/Scope.d.ts +1 -1
  27. package/dist/components/Scope.js +9 -4
  28. package/dist/components/Scope.js.map +1 -1
  29. package/dist/components/anthropic/index.d.ts +0 -10
  30. package/dist/components/anthropic/index.js +9 -1
  31. package/dist/components/anthropic/index.js.map +1 -1
  32. package/dist/components/bedrock/index.d.ts +0 -12
  33. package/dist/components/bedrock/index.js +9 -1
  34. package/dist/components/bedrock/index.js.map +1 -1
  35. package/dist/components/componentLoader.js +23 -14
  36. package/dist/components/componentLoader.js.map +1 -1
  37. package/dist/components/mcp/tools/operations.js +1 -1
  38. package/dist/components/mcp/tools/operations.js.map +1 -1
  39. package/dist/components/ollama/index.d.ts +0 -13
  40. package/dist/components/ollama/index.js +9 -1
  41. package/dist/components/ollama/index.js.map +1 -1
  42. package/dist/components/openai/index.d.ts +11 -15
  43. package/dist/components/openai/index.js +224 -12
  44. package/dist/components/openai/index.js.map +1 -1
  45. package/dist/components/operations.d.ts +9 -0
  46. package/dist/components/operations.js +32 -2
  47. package/dist/components/operations.js.map +1 -1
  48. package/dist/config/configUtils.d.ts +1 -2
  49. package/dist/config/configUtils.js +7 -22
  50. package/dist/config/configUtils.js.map +1 -1
  51. package/dist/dataLayer/harperBridge/ResourceBridge.js +29 -2
  52. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  53. package/dist/dataLayer/restoreMarker.d.ts +25 -3
  54. package/dist/dataLayer/restoreMarker.js +213 -13
  55. package/dist/dataLayer/restoreMarker.js.map +1 -1
  56. package/dist/dataLayer/schema.js +1 -4
  57. package/dist/dataLayer/schema.js.map +1 -1
  58. package/dist/dataLayer/schemaDescribe.js +10 -0
  59. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  60. package/dist/index.d.ts +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/json/systemSchema.json +28 -0
  63. package/dist/resources/DatabaseTransaction.d.ts +21 -1
  64. package/dist/resources/DatabaseTransaction.js +147 -8
  65. package/dist/resources/DatabaseTransaction.js.map +1 -1
  66. package/dist/resources/PrimaryRocksDatabase.js +1 -1
  67. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  68. package/dist/resources/Table.d.ts +31 -3
  69. package/dist/resources/Table.js +397 -79
  70. package/dist/resources/Table.js.map +1 -1
  71. package/dist/resources/auditStore.js +16 -10
  72. package/dist/resources/auditStore.js.map +1 -1
  73. package/dist/resources/blob.d.ts +1 -0
  74. package/dist/resources/blob.js +14 -5
  75. package/dist/resources/blob.js.map +1 -1
  76. package/dist/resources/branchDatabase.js +3 -3
  77. package/dist/resources/branchDatabase.js.map +1 -1
  78. package/dist/resources/databaseDropPreparation.d.ts +20 -0
  79. package/dist/resources/databaseDropPreparation.js +106 -0
  80. package/dist/resources/databaseDropPreparation.js.map +1 -0
  81. package/dist/resources/databases.d.ts +26 -21
  82. package/dist/resources/databases.js +1040 -204
  83. package/dist/resources/databases.js.map +1 -1
  84. package/dist/resources/derivedIndexRegistry.d.ts +23 -0
  85. package/dist/resources/derivedIndexRegistry.js +92 -0
  86. package/dist/resources/derivedIndexRegistry.js.map +1 -1
  87. package/dist/resources/derivedIndexRuntime.d.ts +10 -0
  88. package/dist/resources/derivedIndexRuntime.js +136 -25
  89. package/dist/resources/derivedIndexRuntime.js.map +1 -1
  90. package/dist/resources/derivedIndexes.d.ts +39 -0
  91. package/dist/resources/derivedIndexes.js +733 -0
  92. package/dist/resources/derivedIndexes.js.map +1 -0
  93. package/dist/resources/fullTextSchema.d.ts +8 -0
  94. package/dist/resources/fullTextSchema.js +42 -0
  95. package/dist/resources/fullTextSchema.js.map +1 -1
  96. package/dist/resources/fullTextSchemaLifecycle.d.ts +0 -5
  97. package/dist/resources/fullTextSchemaLifecycle.js +0 -9
  98. package/dist/resources/fullTextSchemaLifecycle.js.map +1 -1
  99. package/dist/resources/graphql.js +101 -9
  100. package/dist/resources/graphql.js.map +1 -1
  101. package/dist/resources/indexes/hnswDerivedIndex.d.ts +0 -10
  102. package/dist/resources/indexes/hnswDerivedIndex.js +0 -230
  103. package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -1
  104. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.d.ts +3 -0
  105. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js +57 -8
  106. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js.map +1 -1
  107. package/dist/resources/models/Models.d.ts +26 -3
  108. package/dist/resources/models/Models.js +256 -13
  109. package/dist/resources/models/Models.js.map +1 -1
  110. package/dist/resources/models/TestBackend.d.ts +3 -1
  111. package/dist/resources/models/TestBackend.js +35 -1
  112. package/dist/resources/models/TestBackend.js.map +1 -1
  113. package/dist/resources/models/analyticsTable.d.ts +2 -2
  114. package/dist/resources/models/analyticsTable.js +4 -2
  115. package/dist/resources/models/analyticsTable.js.map +1 -1
  116. package/dist/resources/models/backendHelpers.d.ts +24 -0
  117. package/dist/resources/models/backendHelpers.js +18 -1
  118. package/dist/resources/models/backendHelpers.js.map +1 -1
  119. package/dist/resources/models/backendRegistry.d.ts +10 -21
  120. package/dist/resources/models/backendRegistry.js +74 -18
  121. package/dist/resources/models/backendRegistry.js.map +1 -1
  122. package/dist/resources/models/bootstrap.d.ts +7 -0
  123. package/dist/resources/models/bootstrap.js +36 -4
  124. package/dist/resources/models/bootstrap.js.map +1 -1
  125. package/dist/resources/models/decideHook.d.ts +33 -0
  126. package/dist/resources/models/decideHook.js +105 -0
  127. package/dist/resources/models/decideHook.js.map +1 -0
  128. package/dist/resources/models/decision.d.ts +64 -0
  129. package/dist/resources/models/decision.js +507 -0
  130. package/dist/resources/models/decision.js.map +1 -0
  131. package/dist/resources/models/decisionStore.d.ts +134 -0
  132. package/dist/resources/models/decisionStore.js +350 -0
  133. package/dist/resources/models/decisionStore.js.map +1 -0
  134. package/dist/resources/models/embedHook.d.ts +66 -8
  135. package/dist/resources/models/embedHook.js +228 -61
  136. package/dist/resources/models/embedHook.js.map +1 -1
  137. package/dist/resources/models/generativeDecision.d.ts +58 -0
  138. package/dist/resources/models/generativeDecision.js +315 -0
  139. package/dist/resources/models/generativeDecision.js.map +1 -0
  140. package/dist/resources/models/types.d.ts +232 -4
  141. package/dist/security/authn/oidc/tokenExchange.js +3 -33
  142. package/dist/security/authn/oidc/tokenExchange.js.map +1 -1
  143. package/dist/security/authn/oidc/tokenUseTable.d.ts +9 -0
  144. package/dist/security/authn/oidc/tokenUseTable.js +28 -0
  145. package/dist/security/authn/oidc/tokenUseTable.js.map +1 -0
  146. package/dist/security/certificateVerification/certificateVerificationSource.d.ts +0 -1
  147. package/dist/security/certificateVerification/certificateVerificationSource.js +3 -3
  148. package/dist/security/certificateVerification/certificateVerificationSource.js.map +1 -1
  149. package/dist/security/certificateVerification/crlVerification.js +77 -165
  150. package/dist/security/certificateVerification/crlVerification.js.map +1 -1
  151. package/dist/security/certificateVerification/types.d.ts +0 -3
  152. package/dist/security/certificateVerification/verificationTables.d.ts +19 -0
  153. package/dist/security/certificateVerification/verificationTables.js +125 -0
  154. package/dist/security/certificateVerification/verificationTables.js.map +1 -0
  155. package/dist/security/certificateVerification/verificationUtils.d.ts +1 -1
  156. package/dist/security/certificateVerification/verificationUtils.js +6 -31
  157. package/dist/security/certificateVerification/verificationUtils.js.map +1 -1
  158. package/dist/security/jsLoader.d.ts +5 -0
  159. package/dist/security/jsLoader.js +8 -0
  160. package/dist/security/jsLoader.js.map +1 -1
  161. package/dist/server/Server.d.ts +1 -0
  162. package/dist/server/Server.js.map +1 -1
  163. package/dist/server/http.js +2 -2
  164. package/dist/server/http.js.map +1 -1
  165. package/dist/server/itc/serverHandlers.js +21 -2
  166. package/dist/server/itc/serverHandlers.js.map +1 -1
  167. package/dist/server/jobs/jobOwnership.d.ts +25 -0
  168. package/dist/server/jobs/jobOwnership.js +127 -0
  169. package/dist/server/jobs/jobOwnership.js.map +1 -0
  170. package/dist/server/jobs/jobProcess.js +9 -2
  171. package/dist/server/jobs/jobProcess.js.map +1 -1
  172. package/dist/server/jobs/jobs.js +18 -5
  173. package/dist/server/jobs/jobs.js.map +1 -1
  174. package/dist/server/loadRootComponents.js +10 -0
  175. package/dist/server/loadRootComponents.js.map +1 -1
  176. package/dist/server/serverHelpers/contentTypes.js +11 -1
  177. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  178. package/dist/server/serverHelpers/serverHandlers.js +12 -2
  179. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  180. package/dist/server/threads/itc.d.ts +4 -1
  181. package/dist/server/threads/itc.js +29 -6
  182. package/dist/server/threads/itc.js.map +1 -1
  183. package/dist/server/threads/manageThreads.d.ts +12 -4
  184. package/dist/server/threads/manageThreads.js +241 -119
  185. package/dist/server/threads/manageThreads.js.map +1 -1
  186. package/dist/server/threads/threadServer.d.ts +1 -0
  187. package/dist/server/threads/threadServer.js +15 -1
  188. package/dist/server/threads/threadServer.js.map +1 -1
  189. package/dist/server/threads/windowsProcessTree.d.ts +91 -0
  190. package/dist/server/threads/windowsProcessTree.js +361 -0
  191. package/dist/server/threads/windowsProcessTree.js.map +1 -0
  192. package/dist/server/throttle.d.ts +1 -1
  193. package/dist/server/throttle.js +8 -1
  194. package/dist/server/throttle.js.map +1 -1
  195. package/dist/upgrade/directives/5-3-0.js +53 -46
  196. package/dist/upgrade/directives/5-3-0.js.map +1 -1
  197. package/dist/utility/errors/hdbError.d.ts +10 -1
  198. package/dist/utility/errors/hdbError.js +55 -11
  199. package/dist/utility/errors/hdbError.js.map +1 -1
  200. package/dist/utility/fsync.d.ts +2 -0
  201. package/dist/utility/fsync.js +20 -0
  202. package/dist/utility/fsync.js.map +1 -0
  203. package/dist/utility/globalSchema.d.ts +18 -0
  204. package/dist/utility/hdbTerms.d.ts +3 -0
  205. package/dist/utility/hdbTerms.js +3 -0
  206. package/dist/utility/hdbTerms.js.map +1 -1
  207. package/dist/utility/signalling.d.ts +7 -1
  208. package/dist/utility/signalling.js +27 -3
  209. package/dist/utility/signalling.js.map +1 -1
  210. package/dist/utility/when.d.ts +1 -0
  211. package/dist/utility/when.js +21 -0
  212. package/dist/utility/when.js.map +1 -1
  213. package/dist/validation/configValidator.js +30 -3
  214. package/dist/validation/configValidator.js.map +1 -1
  215. package/index.ts +13 -0
  216. package/json/systemSchema.json +28 -0
  217. package/npm-shrinkwrap.json +151 -55
  218. package/package.json +14 -13
  219. package/resources/DESIGN.md +80 -100
  220. package/resources/DatabaseTransaction.ts +157 -10
  221. package/resources/PrimaryRocksDatabase.ts +2 -2
  222. package/resources/Table.ts +494 -101
  223. package/resources/auditStore.ts +18 -10
  224. package/resources/blob.ts +13 -6
  225. package/resources/branchDatabase.ts +3 -3
  226. package/resources/databaseDropPreparation.ts +120 -0
  227. package/resources/databases.ts +1155 -205
  228. package/resources/derivedIndexRegistry.ts +122 -0
  229. package/resources/derivedIndexRuntime.ts +157 -30
  230. package/resources/derivedIndexes.ts +856 -0
  231. package/resources/fullTextSchema.ts +55 -0
  232. package/resources/fullTextSchemaLifecycle.ts +0 -15
  233. package/resources/graphql.ts +107 -12
  234. package/resources/indexes/DESIGN.md +7 -0
  235. package/resources/indexes/hnswDerivedIndex.ts +0 -260
  236. package/resources/indexes/nativeFullTextDerivedIndexLifecycle.ts +72 -9
  237. package/resources/models/DESIGN.md +39 -0
  238. package/resources/models/Models.ts +361 -18
  239. package/resources/models/TestBackend.ts +56 -1
  240. package/resources/models/analyticsTable.ts +6 -4
  241. package/resources/models/backendHelpers.ts +17 -0
  242. package/resources/models/backendRegistry.ts +76 -21
  243. package/resources/models/bootstrap.ts +57 -7
  244. package/resources/models/decideHook.ts +135 -0
  245. package/resources/models/decision.ts +505 -0
  246. package/resources/models/decisionStore.ts +419 -0
  247. package/resources/models/embedHook.ts +272 -55
  248. package/resources/models/generativeDecision.ts +459 -0
  249. package/resources/models/types.ts +231 -4
  250. package/security/DESIGN.md +22 -2
  251. package/security/authn/oidc/tokenExchange.ts +6 -34
  252. package/security/authn/oidc/tokenUseTable.ts +27 -0
  253. package/security/certificateVerification/certificateVerificationSource.ts +2 -3
  254. package/security/certificateVerification/crlVerification.ts +96 -174
  255. package/security/certificateVerification/types.ts +0 -3
  256. package/security/certificateVerification/verificationTables.ts +124 -0
  257. package/security/certificateVerification/verificationUtils.ts +8 -32
  258. package/security/jsLoader.ts +9 -1
  259. package/server/DESIGN.md +27 -1
  260. package/server/Server.ts +2 -1
  261. package/server/http.ts +4 -2
  262. package/server/itc/serverHandlers.js +29 -1
  263. package/server/jobs/jobOwnership.ts +89 -0
  264. package/server/jobs/jobProcess.ts +8 -2
  265. package/server/jobs/jobs.ts +15 -4
  266. package/server/loadRootComponents.js +11 -0
  267. package/server/serverHelpers/contentTypes.ts +13 -1
  268. package/server/serverHelpers/serverHandlers.js +11 -2
  269. package/server/threads/itc.js +32 -6
  270. package/server/threads/manageThreads.js +268 -122
  271. package/server/threads/threadServer.js +13 -1
  272. package/server/threads/windowsProcessTree.ts +409 -0
  273. package/server/throttle.ts +11 -1
  274. package/studio/web/assets/{Chat-CveGbxe6.js → Chat-Bq60AO-g.js} +1 -1
  275. package/studio/web/assets/{FloatingChat-IpCFgYWL.js → FloatingChat-D4560T0p.js} +3 -3
  276. package/studio/web/assets/{apiToken-CS8fFTgL.js → apiToken-BEvbFPMc.js} +1 -1
  277. package/studio/web/assets/{applications-D7F4Jopl.js → applications-CSUVTH4E.js} +1 -1
  278. package/studio/web/assets/{cssMode-Daw_oLPq.js → cssMode-DJyc9mHj.js} +1 -1
  279. package/studio/web/assets/{editor-B3Bs1zWX.js → editor-DDIsQfj6.js} +1 -1
  280. package/studio/web/assets/{html-CDaQwWiE.js → html-g1BJHxLy.js} +1 -1
  281. package/studio/web/assets/{htmlMode-Cb6emO4U.js → htmlMode-Vh5IglCQ.js} +1 -1
  282. package/studio/web/assets/{index-B4g2Fu_2.js → index-DGRAzvO4.js} +5 -5
  283. package/studio/web/assets/{index.lazy-NwhvF1q1.js → index.lazy-vgSic7et.js} +1 -1
  284. package/studio/web/assets/{javascript-2_86gB9Q.js → javascript-5VIolqf7.js} +1 -1
  285. package/studio/web/assets/{jsonMode-DX-i86uQ.js → jsonMode-DG4zQraI.js} +1 -1
  286. package/studio/web/assets/{languageServices-B85WN-Ej.js → languageServices-t5FBpX-i.js} +1 -1
  287. package/studio/web/assets/{lspLanguageFeatures-JCWHIsKg.js → lspLanguageFeatures-DgVnNPh-.js} +1 -1
  288. package/studio/web/assets/{notifications-D9ejzt52.js → notifications-BeWcX04m.js} +1 -1
  289. package/studio/web/assets/{notifications-B7hjKhai.js → notifications-DUGWrWoO.js} +1 -1
  290. package/studio/web/assets/{profile-D8B6No3F.js → profile-BvUEDBzW.js} +1 -1
  291. package/studio/web/assets/{regions-DFazIfTK.js → regions-CB-_2m7M.js} +1 -1
  292. package/studio/web/assets/{register-CwFLviLF.js → register-1w1Zr3b2.js} +2 -2
  293. package/studio/web/assets/{setComponentFile-VnJ80SSJ.js → setComponentFile-z4-qJCbA.js} +1 -1
  294. package/studio/web/assets/{setup-BYQxFy-C.js → setup-CS50uJ4x.js} +2 -2
  295. package/studio/web/assets/{status-Cn5XjmsL.js → status-CI0wOdOE.js} +1 -1
  296. package/studio/web/assets/{toggleHighContrast-g9xIh6TX.js → toggleHighContrast-BsAE4jPe.js} +1 -1
  297. package/studio/web/assets/{tsMode-EC-n0Wqc.js → tsMode-D83Gg3cq.js} +1 -1
  298. package/studio/web/assets/{typescript-DHmM9JCO.js → typescript-Dfp-GrNq.js} +1 -1
  299. package/studio/web/assets/{useEntityRestURL-BUdnVSVv.js → useEntityRestURL-BKetlINf.js} +1 -1
  300. package/studio/web/assets/{workers-BVl9bBB-.js → workers-CCvmDLH3.js} +1 -1
  301. package/studio/web/assets/{xml-C4_sqOkX.js → xml-06pZp00U.js} +1 -1
  302. package/studio/web/assets/{yaml-CVkbDqtW.js → yaml-iSnWMVlV.js} +1 -1
  303. package/studio/web/index.html +1 -1
  304. package/upgrade/directives/5-3-0.ts +61 -54
  305. package/utility/DESIGN.md +5 -1
  306. package/utility/errors/hdbError.ts +56 -8
  307. package/utility/fsync.ts +16 -0
  308. package/utility/hdbTerms.ts +3 -0
  309. package/utility/signalling.ts +33 -4
  310. package/utility/when.ts +22 -0
  311. package/validation/configValidator.ts +36 -7
@@ -1,5 +1,28 @@
1
+ type LockStore = {
2
+ status?: string;
3
+ tryLock(key: string): boolean;
4
+ unlock(key: string): void;
5
+ };
6
+ type FenceWaitOptions = {
7
+ shouldContinue?: () => boolean;
8
+ timeoutMilliseconds?: number;
9
+ };
10
+ /** Hold this node-wide fence for the full duration of an asynchronous table clear. */
11
+ export declare function acquireFullTextClearFence(rootStore: LockStore, tableId: number): (() => void) | undefined;
12
+ /** Probe without waiting; callers hold the schema lock so a clear cannot start between this and persistence. */
13
+ export declare function fullTextClearInProgress(rootStore: LockStore, tableId: number): boolean;
14
+ /** Wait until the current clear releases its fence; callers retry admission afterwards. */
15
+ export declare function waitForFullTextClear(rootStore: LockStore, tableId: number, options?: FenceWaitOptions): Promise<boolean>;
16
+ /** Fence same-name recreation while a dropped table's native directories are being retired. */
17
+ export declare function acquireFullTextRetirementFence(rootStore: LockStore, tableName: string): (() => void) | undefined;
18
+ /** Probe under the schema lock so recreation cannot pass between the probe and catalog persistence. */
19
+ export declare function fullTextRetirementInProgress(rootStore: LockStore, tableName: string): boolean;
20
+ /** Wait until the current retirement releases its fence; the caller must recheck its generation afterwards. */
21
+ export declare function waitForFullTextRetirement(rootStore: LockStore, tableName: string, options?: FenceWaitOptions): Promise<boolean>;
22
+ export declare function waitForFullTextRetirementLease(rootStore: LockStore, tableName: string, options?: FenceWaitOptions): Promise<(() => void) | undefined>;
1
23
  /** `admission` returns a reason while writes to these tables must be rejected. */
2
24
  export declare function registerDerivedIndexTables(auditStore: object, tableIds: Iterable<number>, admission?: () => string | undefined): () => void;
3
25
  export declare function hasDerivedIndexRegistration(auditStore: object, tableId: number): boolean;
4
26
  /** The reason a write to this table must currently be rejected, or undefined when writes are admitted. */
5
27
  export declare function derivedIndexWriteRejection(auditStore: object, tableId: number): string | undefined;
28
+ export {};
@@ -1,10 +1,102 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.acquireFullTextClearFence = acquireFullTextClearFence;
4
+ exports.fullTextClearInProgress = fullTextClearInProgress;
5
+ exports.waitForFullTextClear = waitForFullTextClear;
6
+ exports.acquireFullTextRetirementFence = acquireFullTextRetirementFence;
7
+ exports.fullTextRetirementInProgress = fullTextRetirementInProgress;
8
+ exports.waitForFullTextRetirement = waitForFullTextRetirement;
9
+ exports.waitForFullTextRetirementLease = waitForFullTextRetirementLease;
3
10
  exports.registerDerivedIndexTables = registerDerivedIndexTables;
4
11
  exports.hasDerivedIndexRegistration = hasDerivedIndexRegistration;
5
12
  exports.derivedIndexWriteRejection = derivedIndexWriteRejection;
13
+ const hdbError_ts_1 = require("../utility/errors/hdbError.js");
6
14
  const registrations = new WeakMap();
7
15
  const admissions = new WeakMap();
16
+ const DEFAULT_FENCE_WAIT_MILLISECONDS = 70_000;
17
+ function fullTextClearLockKey(tableId) {
18
+ return `derived-index:fulltext:${tableId}:table-clear`;
19
+ }
20
+ function fullTextRetirementLockKey(tableName) {
21
+ return `derived-index:fulltext:${tableName}:retirement`;
22
+ }
23
+ /** Hold this node-wide fence for the full duration of an asynchronous table clear. */
24
+ function acquireFullTextClearFence(rootStore, tableId) {
25
+ const key = fullTextClearLockKey(tableId);
26
+ if (!rootStore.tryLock(key))
27
+ return;
28
+ let held = true;
29
+ return () => {
30
+ if (!held)
31
+ return;
32
+ held = false;
33
+ rootStore.unlock(key);
34
+ };
35
+ }
36
+ /** Probe without waiting; callers hold the schema lock so a clear cannot start between this and persistence. */
37
+ function fullTextClearInProgress(rootStore, tableId) {
38
+ const release = acquireFullTextClearFence(rootStore, tableId);
39
+ if (!release)
40
+ return true;
41
+ release();
42
+ return false;
43
+ }
44
+ /** Wait until the current clear releases its fence; callers retry admission afterwards. */
45
+ function waitForFullTextClear(rootStore, tableId, options) {
46
+ return waitForFence(rootStore, () => acquireFullTextClearFence(rootStore, tableId), 'table clear', options);
47
+ }
48
+ /** Fence same-name recreation while a dropped table's native directories are being retired. */
49
+ function acquireFullTextRetirementFence(rootStore, tableName) {
50
+ const key = fullTextRetirementLockKey(tableName);
51
+ if (!rootStore.tryLock(key))
52
+ return;
53
+ let held = true;
54
+ return () => {
55
+ if (!held)
56
+ return;
57
+ held = false;
58
+ rootStore.unlock(key);
59
+ };
60
+ }
61
+ /** Probe under the schema lock so recreation cannot pass between the probe and catalog persistence. */
62
+ function fullTextRetirementInProgress(rootStore, tableName) {
63
+ const release = acquireFullTextRetirementFence(rootStore, tableName);
64
+ if (!release)
65
+ return true;
66
+ release();
67
+ return false;
68
+ }
69
+ /** Wait until the current retirement releases its fence; the caller must recheck its generation afterwards. */
70
+ function waitForFullTextRetirement(rootStore, tableName, options) {
71
+ return waitForFence(rootStore, () => acquireFullTextRetirementFence(rootStore, tableName), `retirement of full-text storage for '${tableName}'`, options);
72
+ }
73
+ function waitForFullTextRetirementLease(rootStore, tableName, options) {
74
+ return waitForFenceLease(rootStore, () => acquireFullTextRetirementFence(rootStore, tableName), `retirement of full-text storage for '${tableName}'`, options);
75
+ }
76
+ async function waitForFence(rootStore, acquire, description, options = {}) {
77
+ const release = await waitForFenceLease(rootStore, acquire, description, options);
78
+ if (!release)
79
+ return false;
80
+ release();
81
+ return true;
82
+ }
83
+ async function waitForFenceLease(rootStore, acquire, description, options = {}) {
84
+ const deadline = Date.now() + (options.timeoutMilliseconds ?? DEFAULT_FENCE_WAIT_MILLISECONDS);
85
+ let retryDelayMilliseconds = 1;
86
+ for (;;) {
87
+ if (options.shouldContinue && !options.shouldContinue())
88
+ return;
89
+ if (rootStore.status !== undefined && rootStore.status !== 'open')
90
+ throw new Error(`Cannot wait for ${description} on a ${rootStore.status} store`);
91
+ const release = acquire();
92
+ if (release)
93
+ return release;
94
+ if (Date.now() >= deadline)
95
+ throw new hdbError_ts_1.DerivedIndexLagError(`Timed out waiting for ${description}; retry the operation`);
96
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMilliseconds));
97
+ retryDelayMilliseconds = Math.min(retryDelayMilliseconds * 2, 50);
98
+ }
99
+ }
8
100
  /** `admission` returns a reason while writes to these tables must be rejected. */
9
101
  function registerDerivedIndexTables(auditStore, tableIds, admission) {
10
102
  const registeredTableIds = new Set(tableIds);
@@ -1 +1 @@
1
- {"version":3,"file":"derivedIndexRegistry.js","sourceRoot":"","sources":["../../resources/derivedIndexRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"derivedIndexRegistry.js","sourceRoot":"","sources":["../../resources/derivedIndexRegistry.ts"],"names":[],"mappings":"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"}
@@ -144,6 +144,10 @@ export type DerivedIndexRegistration = {
144
144
  backend: DerivedIndexBackend;
145
145
  projections: ReadonlyMap<number, (record: unknown) => unknown>;
146
146
  options?: DerivedIndexRunnerOptions;
147
+ /** Shared readiness identity when it must be narrower than the stable backend/lock identity. */
148
+ readinessId?: string;
149
+ /** False once this table generation has been superseded. Must be synchronous and allocation-free. */
150
+ isCurrent?: () => boolean;
147
151
  };
148
152
  /**
149
153
  * `size` is the stored byte size of the record when known; it bounds the projection's size without
@@ -211,5 +215,11 @@ export declare class DerivedIndexRuntime {
211
215
  }
212
216
  /** Read an index's shared readiness on any worker, without a registered runtime. */
213
217
  export declare function readDerivedIndexReadiness(logStore: RocksTransactionLogStore, backendId: string): DerivedIndexReadiness;
218
+ /** Publish setup-time state before a backend runner exists. */
219
+ export declare function publishDerivedIndexReadiness(logStore: RocksTransactionLogStore, backendId: string, state: DerivedIndexReadinessState, reason?: DerivedIndexReadinessReason): void;
220
+ /** Publish a setup failure only while no elected runner has published a stronger state. */
221
+ export declare function publishDerivedIndexUnavailableIfUnknown(logStore: RocksTransactionLogStore, backendId: string): boolean;
222
+ /** Rearm setup only while no peer has replaced the unavailable state. */
223
+ export declare function retryDerivedIndexUnavailable(logStore: RocksTransactionLogStore, backendId: string): boolean;
214
224
  export declare function sameDerivedIndexPositions(left: DerivedIndexPositions, right: DerivedIndexPositions): boolean;
215
225
  export declare function readDerivedIndexCoverage(logStore: RocksTransactionLogStore, backendId: string, loadCursor: () => DerivedIndexCursor | undefined, maxLagMilliseconds: number): DerivedIndexCoverage;
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DerivedIndexRuntime = exports.READINESS_BYTES = exports.DERIVED_INDEX_FAILED = exports.DERIVED_INDEX_DEFERRED = exports.DERIVED_INDEX_ACCEPTED = void 0;
4
4
  exports.derivedIndexTime = derivedIndexTime;
5
5
  exports.readDerivedIndexReadiness = readDerivedIndexReadiness;
6
+ exports.publishDerivedIndexReadiness = publishDerivedIndexReadiness;
7
+ exports.publishDerivedIndexUnavailableIfUnknown = publishDerivedIndexUnavailableIfUnknown;
8
+ exports.retryDerivedIndexUnavailable = retryDerivedIndexUnavailable;
6
9
  exports.sameDerivedIndexPositions = sameDerivedIndexPositions;
7
10
  exports.readDerivedIndexCoverage = readDerivedIndexCoverage;
8
11
  const DatabaseTransaction_ts_1 = require("./DatabaseTransaction.js");
@@ -33,6 +36,8 @@ const READINESS_STATES = [
33
36
  'needs-rebuild',
34
37
  'unavailable',
35
38
  ];
39
+ const READINESS_BACKEND_FAILED = READINESS_STATES.length;
40
+ const READINESS_RETRYING = READINESS_BACKEND_FAILED + 1;
36
41
  const READINESS_REASONS = [
37
42
  'none',
38
43
  'cursor-missing',
@@ -114,6 +119,7 @@ class DerivedIndexRuntime {
114
119
  this.#listening = true;
115
120
  }
116
121
  runner.wake(true);
122
+ let releaseStarted = false;
117
123
  return () => {
118
124
  if (this.#runners.get(registration.backend.id) === runner) {
119
125
  this.#runners.delete(registration.backend.id);
@@ -124,6 +130,9 @@ class DerivedIndexRuntime {
124
130
  }
125
131
  this.#stopListeningIfIdle();
126
132
  }
133
+ if (releaseStarted)
134
+ return this.#retryRunnerRelease(registration.backend.id, runner);
135
+ releaseStarted = true;
127
136
  return this.#track(runner, runner.stop());
128
137
  };
129
138
  }
@@ -197,7 +206,7 @@ class DerivedIndexRuntime {
197
206
  }
198
207
  #pollCoverage(backendId, group) {
199
208
  try {
200
- const views = getReadinessViews(this.#logStore, backendId);
209
+ const views = getReadinessViews(this.#logStore, this.#runners.get(backendId)?.readinessId ?? backendId);
201
210
  const before = readReadiness(views);
202
211
  const time = Atomics.load(views.coverage, 0);
203
212
  const after = readReadiness(views);
@@ -224,21 +233,32 @@ class DerivedIndexRuntime {
224
233
  /** Force a rebuild (or retry one that became `unavailable`). Returns false when the backend cannot be rebuilt by the runtime. */
225
234
  requestRebuild(backendId) {
226
235
  const held = this.#heldRunners.get(backendId);
227
- if (held) {
228
- const released = held.runner.retryRelease();
229
- this.#pendingStops.add(released);
230
- released.then(() => {
231
- this.#pendingStops.delete(released);
232
- this.#pendingStops.delete(held.stopped);
233
- if (this.#heldRunners.get(backendId) === held)
234
- this.#heldRunners.delete(backendId);
235
- }, () => { });
236
- }
236
+ if (held)
237
+ void this.#retryRunnerRelease(backendId, held.runner);
237
238
  const runner = this.#runners.get(backendId);
238
239
  if (runner)
239
240
  return runner.requestRebuild();
240
241
  return held !== undefined;
241
242
  }
243
+ #retryRunnerRelease(backendId, runner) {
244
+ const held = this.#heldRunners.get(backendId);
245
+ const released = runner.retryRelease();
246
+ this.#pendingStops.add(released);
247
+ released.then(() => {
248
+ this.#pendingStops.delete(released);
249
+ if (held?.runner === runner)
250
+ this.#pendingStops.delete(held.stopped);
251
+ if (this.#heldRunners.get(backendId)?.runner === runner)
252
+ this.#heldRunners.delete(backendId);
253
+ }, () => {
254
+ if (held?.runner === runner && held.stopped !== released)
255
+ this.#pendingStops.delete(held.stopped);
256
+ const current = this.#heldRunners.get(backendId);
257
+ if (!current || current.runner === runner)
258
+ this.#heldRunners.set(backendId, { runner, stopped: released });
259
+ });
260
+ return released;
261
+ }
242
262
  /** Resolves once every runner has released ownership and its backend shutdown has settled. */
243
263
  stop() {
244
264
  if (this.#stopping)
@@ -269,8 +289,18 @@ class DerivedIndexRuntime {
269
289
  #stopListening() {
270
290
  if (!this.#listening)
271
291
  return;
272
- this.#logStore.rootStore.off?.('committed', this.#onCommit);
273
- this.#listening = false;
292
+ try {
293
+ this.#logStore.rootStore.off?.('committed', this.#onCommit);
294
+ }
295
+ catch (error) {
296
+ // An already-closed store cannot emit again and some native stores reject listener access
297
+ // after close. Preserve errors from a live store, where losing the listener would be unsafe.
298
+ if (this.#logStore.rootStore.status === 'open')
299
+ throw error;
300
+ }
301
+ finally {
302
+ this.#listening = false;
303
+ }
274
304
  }
275
305
  }
276
306
  exports.DerivedIndexRuntime = DerivedIndexRuntime;
@@ -379,12 +409,16 @@ class DerivedIndexRunner {
379
409
  #unregisterTables;
380
410
  #ownerEpoch;
381
411
  #readinessBuffer;
412
+ #wakeBuffer;
382
413
  #sharedViews;
383
414
  #resetting;
384
415
  status = { state: 'idle' };
385
416
  get id() {
386
417
  return this.#registration.backend.id;
387
418
  }
419
+ get readinessId() {
420
+ return this.#registration.readinessId ?? this.id;
421
+ }
388
422
  retryRelease() {
389
423
  if (!this.#heldLock)
390
424
  return this.#stopResult ?? Promise.resolve();
@@ -414,7 +448,9 @@ class DerivedIndexRunner {
414
448
  typeof root?.getSync === 'function' &&
415
449
  typeof root?.removeSync === 'function';
416
450
  this.#lagBudget = effectiveLagBudget(options);
417
- this.#readinessBuffer = readinessBuffer(logStore, registration.backend.id, () => this.#notified());
451
+ const notified = () => this.#notified();
452
+ this.#readinessBuffer = readinessBuffer(logStore, this.readinessId, this.readinessId === this.id ? notified : undefined);
453
+ this.#wakeBuffer = this.readinessId === this.id ? this.#readinessBuffer : wakeBuffer(logStore, this.id, notified);
418
454
  this.#sharedViews = sharedViewsOf(this.#readinessBuffer);
419
455
  try {
420
456
  registration.backend.attach({
@@ -425,6 +461,8 @@ class DerivedIndexRunner {
425
461
  }
426
462
  catch (error) {
427
463
  this.#readinessBuffer.cancel?.();
464
+ if (this.#wakeBuffer !== this.#readinessBuffer)
465
+ this.#wakeBuffer.cancel?.();
428
466
  throw error;
429
467
  }
430
468
  this.#unregisterTables = (0, derivedIndexRegistry_ts_1.registerDerivedIndexTables)(logStore, registration.projections.keys(), this.#lagBudget > 0 ? () => this.#writeRejection() : undefined);
@@ -443,8 +481,7 @@ class DerivedIndexRunner {
443
481
  if (!fromBackend && !forCoverage && this.#lagBudget > 0)
444
482
  this.#unreadSince ??= this.#options.now();
445
483
  if (this.status.state === 'unavailable') {
446
- if (this.#heldLock ||
447
- Atomics.load(this.#shared().words, READINESS_STATE) === READINESS_STATES.indexOf('unavailable'))
484
+ if (this.#heldLock || isUnavailableReadinessState(Atomics.load(this.#shared().words, READINESS_STATE)))
448
485
  return;
449
486
  this.status = { state: 'idle' };
450
487
  }
@@ -492,6 +529,8 @@ class DerivedIndexRunner {
492
529
  try {
493
530
  this.#unsubscribeBackend?.();
494
531
  this.#readinessBuffer.cancel?.();
532
+ if (this.#wakeBuffer !== this.#readinessBuffer)
533
+ this.#wakeBuffer.cancel?.();
495
534
  }
496
535
  catch (error) {
497
536
  logger.warn?.(`Derived index '${this.id}' cleanup hook threw`, error);
@@ -630,9 +669,9 @@ class DerivedIndexRunner {
630
669
  return true;
631
670
  }
632
671
  // The owner may be another worker that never idles: leave the request where every runner looks,
633
- // and notify whoever holds the buffer's callback.
672
+ // and notify every generation sharing the stable runner lock.
634
673
  Atomics.store(this.#shared().words, READINESS_REBUILD_REQUEST, 1);
635
- this.#readinessBuffer.notify?.();
674
+ this.#wakeBuffer.notify?.();
636
675
  this.wake(true);
637
676
  return true;
638
677
  }
@@ -672,13 +711,16 @@ class DerivedIndexRunner {
672
711
  * The lock is taken without an unlock callback. rocksdb-js queues such a callback as a
673
712
  * thread-safe function of the caller's env, and on Node 22 a callback left behind by a worker that
674
713
  * was terminated aborts the process when another thread unlocks (HarperFast/rocksdb-js, pending).
675
- * A successor is woken by the releasing owner's `notify()` on the readiness buffer — which
676
- * tolerates a dead listener's env — and by the retry timer below.
714
+ * A successor is woken by the releasing owner's `notify()` on the stable-id wake buffer — which
715
+ * tolerates a dead listener's env — and by the retry timer below. Registrations without a
716
+ * generation-specific readiness id keep using the readiness buffer itself.
677
717
  */
678
718
  #acquire() {
679
719
  // Commit wakes are frequent; neither a parked nor a backing-off runner may re-probe on each one.
680
720
  if (this.#waitingForLock || this.#lockBackoff)
681
721
  return;
722
+ if (this.#registration.isCurrent && !this.#registration.isCurrent())
723
+ return;
682
724
  if (this.#releasing) {
683
725
  this.#releasing.then(() => this.wake(true));
684
726
  return;
@@ -729,6 +771,10 @@ class DerivedIndexRunner {
729
771
  try {
730
772
  if (!reviving)
731
773
  this.#ownerEpoch = this.#mintEpoch();
774
+ // A worker that could not construct this generation may have published a setup-only
775
+ // failure before this healthy backend acquired the stable runner lock. Ownership is
776
+ // stronger evidence: clear only that sentinel, never a runner-published unavailable state.
777
+ Atomics.compareExchange(this.#shared().words, READINESS_STATE, READINESS_BACKEND_FAILED, READINESS_STATES.indexOf('unknown'));
732
778
  this.status = { state: 'running', ownerEpoch: this.#ownerEpoch };
733
779
  const condemned = this.#readCondemnation();
734
780
  const shared = this.getReadiness();
@@ -849,6 +895,10 @@ class DerivedIndexRunner {
849
895
  #drain() {
850
896
  if (!this.#owned || this.#stopped || this.#rebuilding)
851
897
  return;
898
+ if (this.#registration.isCurrent && !this.#registration.isCurrent()) {
899
+ this.#release();
900
+ return;
901
+ }
852
902
  if (this.#canRebuild() && this.#takeSharedRebuildRequest()) {
853
903
  if (this.#rebuildTimer) {
854
904
  clearTimeout(this.#rebuildTimer);
@@ -1844,10 +1894,10 @@ class DerivedIndexRunner {
1844
1894
  logger.error(`Failed to release derived index runner '${backend.id}'`, error);
1845
1895
  }
1846
1896
  // A skip left standing by an absent or throwing `notify` swallows a peer's release instead.
1847
- if (this.#readinessBuffer.notify) {
1897
+ if (this.#wakeBuffer.notify) {
1848
1898
  this.#skipNextNotify = !this.#stopped;
1849
1899
  try {
1850
- this.#readinessBuffer.notify();
1900
+ this.#wakeBuffer.notify();
1851
1901
  }
1852
1902
  catch (error) {
1853
1903
  this.#skipNextNotify = false;
@@ -1884,6 +1934,11 @@ function lastOpen(collected) {
1884
1934
  function readinessBuffer(logStore, backendId, callback) {
1885
1935
  return logStore.getUserSharedBuffer(`derived-index:${backendId}:readiness`, new ArrayBuffer(exports.READINESS_BYTES), callback ? { callback } : undefined);
1886
1936
  }
1937
+ function wakeBuffer(logStore, backendId, callback) {
1938
+ return logStore.getUserSharedBuffer(`derived-index:${backendId}:wake`, new ArrayBuffer(1), {
1939
+ callback,
1940
+ });
1941
+ }
1887
1942
  function sharedViewsOf(buffer) {
1888
1943
  return {
1889
1944
  words: new Int32Array(buffer, 0, READINESS_WORDS),
@@ -1893,12 +1948,19 @@ function sharedViewsOf(buffer) {
1893
1948
  }
1894
1949
  const readinessViews = new WeakMap();
1895
1950
  function readReadiness({ words, epoch }) {
1896
- const state = READINESS_STATES[Atomics.load(words, READINESS_STATE)] ?? 'unknown';
1897
- const reason = READINESS_REASONS[Atomics.load(words, READINESS_REASON)] ?? 'none';
1951
+ const stateIndex = Atomics.load(words, READINESS_STATE);
1952
+ const setupFailed = stateIndex === READINESS_BACKEND_FAILED;
1953
+ const retrying = stateIndex === READINESS_RETRYING;
1954
+ const state = setupFailed ? 'unavailable' : retrying ? 'unknown' : (READINESS_STATES[stateIndex] ?? 'unknown');
1955
+ const reason = setupFailed
1956
+ ? 'backend-failed'
1957
+ : retrying
1958
+ ? 'none'
1959
+ : (READINESS_REASONS[Atomics.load(words, READINESS_REASON)] ?? 'none');
1898
1960
  const readiness = {
1899
1961
  state,
1900
1962
  ownerEpoch: Atomics.load(epoch, 0),
1901
- rebuildAttempts: Atomics.load(words, READINESS_ATTEMPTS),
1963
+ rebuildAttempts: retrying || setupFailed ? 0 : Atomics.load(words, READINESS_ATTEMPTS),
1902
1964
  };
1903
1965
  if (reason !== 'none')
1904
1966
  readiness.reason = reason;
@@ -1908,6 +1970,55 @@ function readReadiness({ words, epoch }) {
1908
1970
  function readDerivedIndexReadiness(logStore, backendId) {
1909
1971
  return readReadiness(getReadinessViews(logStore, backendId));
1910
1972
  }
1973
+ /** Publish setup-time state before a backend runner exists. */
1974
+ function publishDerivedIndexReadiness(logStore, backendId, state, reason = 'none') {
1975
+ const views = getReadinessViews(logStore, backendId);
1976
+ if (state === 'unknown')
1977
+ Atomics.store(views.words, READINESS_ATTEMPTS, 0);
1978
+ Atomics.store(views.words, READINESS_REASON, READINESS_REASONS.indexOf(reason));
1979
+ Atomics.store(views.words, READINESS_STATE, READINESS_STATES.indexOf(state));
1980
+ }
1981
+ /** Publish a setup failure only while no elected runner has published a stronger state. */
1982
+ function publishDerivedIndexUnavailableIfUnknown(logStore, backendId) {
1983
+ const { words, epoch } = getReadinessViews(logStore, backendId);
1984
+ // RETRYING is an explicit setup retry. Epochs are monotonic, so a prior
1985
+ // owner must not prevent that retry from returning to an observable failure.
1986
+ const retryEpoch = Atomics.load(epoch, 0);
1987
+ if (Atomics.compareExchange(words, READINESS_STATE, READINESS_RETRYING, READINESS_BACKEND_FAILED) === READINESS_RETRYING) {
1988
+ // Close the same owner-election race as the unknown-state path below. A
1989
+ // runner that acquired this epoch owns readiness, even if its worker has
1990
+ // not published ready yet.
1991
+ if (Atomics.load(epoch, 0) !== retryEpoch) {
1992
+ Atomics.compareExchange(words, READINESS_STATE, READINESS_BACKEND_FAILED, READINESS_STATES.indexOf('unknown'));
1993
+ return false;
1994
+ }
1995
+ return true;
1996
+ }
1997
+ if (Atomics.load(epoch, 0) !== 0n)
1998
+ return false;
1999
+ const published = Atomics.compareExchange(words, READINESS_STATE, READINESS_STATES.indexOf('unknown'), READINESS_BACKEND_FAILED) ===
2000
+ READINESS_STATES.indexOf('unknown');
2001
+ if (!published)
2002
+ return false;
2003
+ // Close the race with an owner acquiring between the epoch probe and the state CAS.
2004
+ if (Atomics.load(epoch, 0) !== 0n) {
2005
+ Atomics.compareExchange(words, READINESS_STATE, READINESS_BACKEND_FAILED, READINESS_STATES.indexOf('unknown'));
2006
+ return false;
2007
+ }
2008
+ return true;
2009
+ }
2010
+ /** Rearm setup only while no peer has replaced the unavailable state. */
2011
+ function retryDerivedIndexUnavailable(logStore, backendId) {
2012
+ const { words } = getReadinessViews(logStore, backendId);
2013
+ const unavailable = READINESS_STATES.indexOf('unavailable');
2014
+ if (Atomics.compareExchange(words, READINESS_STATE, unavailable, READINESS_RETRYING) === unavailable)
2015
+ return true;
2016
+ return (Atomics.compareExchange(words, READINESS_STATE, READINESS_BACKEND_FAILED, READINESS_RETRYING) ===
2017
+ READINESS_BACKEND_FAILED);
2018
+ }
2019
+ function isUnavailableReadinessState(stateIndex) {
2020
+ return stateIndex === READINESS_STATES.indexOf('unavailable') || stateIndex === READINESS_BACKEND_FAILED;
2021
+ }
1911
2022
  function getReadinessViews(logStore, backendId) {
1912
2023
  let byBackend = readinessViews.get(logStore);
1913
2024
  if (!byBackend)