@harperfast/harper 5.3.0-alpha.1 → 5.3.0-beta.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.
Files changed (291) hide show
  1. package/bin/cliOperations.ts +12 -0
  2. package/bin/restart.ts +66 -6
  3. package/components/Application.ts +1134 -112
  4. package/components/OptionsWatcher.ts +368 -102
  5. package/components/Scope.ts +20 -1
  6. package/components/componentLoader.ts +43 -4
  7. package/components/deploymentOperations.ts +4 -1
  8. package/components/deploymentRecorder.ts +9 -2
  9. package/components/operations.js +284 -52
  10. package/components/operationsValidation.js +49 -2
  11. package/components/packageComponent.ts +25 -1
  12. package/components/requestRestart.ts +11 -0
  13. package/config/RootConfigWatcher.ts +191 -37
  14. package/config/configReadRetry.ts +62 -0
  15. package/config/configUtils.ts +78 -26
  16. package/config/parseConfigFile.ts +34 -0
  17. package/config/readConfigFileSync.ts +44 -0
  18. package/config/watcherArming.ts +59 -0
  19. package/config-root.schema.json +4 -0
  20. package/dataLayer/harperBridge/ResourceBridge.ts +28 -2
  21. package/dist/bin/cliOperations.js +13 -0
  22. package/dist/bin/cliOperations.js.map +1 -1
  23. package/dist/bin/restart.js +42 -6
  24. package/dist/bin/restart.js.map +1 -1
  25. package/dist/components/Application.d.ts +104 -9
  26. package/dist/components/Application.js +954 -102
  27. package/dist/components/Application.js.map +1 -1
  28. package/dist/components/OptionsWatcher.d.ts +4 -1
  29. package/dist/components/OptionsWatcher.js +378 -104
  30. package/dist/components/OptionsWatcher.js.map +1 -1
  31. package/dist/components/Scope.js +15 -1
  32. package/dist/components/Scope.js.map +1 -1
  33. package/dist/components/componentLoader.js +35 -3
  34. package/dist/components/componentLoader.js.map +1 -1
  35. package/dist/components/deploymentOperations.js +4 -1
  36. package/dist/components/deploymentOperations.js.map +1 -1
  37. package/dist/components/deploymentRecorder.d.ts +4 -2
  38. package/dist/components/deploymentRecorder.js +1 -0
  39. package/dist/components/deploymentRecorder.js.map +1 -1
  40. package/dist/components/operations.d.ts +28 -0
  41. package/dist/components/operations.js +263 -54
  42. package/dist/components/operations.js.map +1 -1
  43. package/dist/components/operationsValidation.js +48 -2
  44. package/dist/components/operationsValidation.js.map +1 -1
  45. package/dist/components/packageComponent.js +24 -0
  46. package/dist/components/packageComponent.js.map +1 -1
  47. package/dist/components/requestRestart.d.ts +1 -0
  48. package/dist/components/requestRestart.js +7 -0
  49. package/dist/components/requestRestart.js.map +1 -1
  50. package/dist/config/RootConfigWatcher.d.ts +2 -0
  51. package/dist/config/RootConfigWatcher.js +189 -35
  52. package/dist/config/RootConfigWatcher.js.map +1 -1
  53. package/dist/config/configReadRetry.d.ts +8 -0
  54. package/dist/config/configReadRetry.js +62 -0
  55. package/dist/config/configReadRetry.js.map +1 -0
  56. package/dist/config/configUtils.d.ts +10 -9
  57. package/dist/config/configUtils.js +63 -27
  58. package/dist/config/configUtils.js.map +1 -1
  59. package/dist/config/parseConfigFile.d.ts +4 -0
  60. package/dist/config/parseConfigFile.js +35 -0
  61. package/dist/config/parseConfigFile.js.map +1 -0
  62. package/dist/config/readConfigFileSync.d.ts +1 -0
  63. package/dist/config/readConfigFileSync.js +47 -0
  64. package/dist/config/readConfigFileSync.js.map +1 -0
  65. package/dist/config/watcherArming.d.ts +15 -0
  66. package/dist/config/watcherArming.js +59 -0
  67. package/dist/config/watcherArming.js.map +1 -0
  68. package/dist/dataLayer/harperBridge/ResourceBridge.js +21 -2
  69. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  70. package/dist/index.d.ts +1 -0
  71. package/dist/index.js +4 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/json/systemSchema.json +3 -0
  74. package/dist/resources/DatabaseTransaction.d.ts +25 -0
  75. package/dist/resources/DatabaseTransaction.js +224 -18
  76. package/dist/resources/DatabaseTransaction.js.map +1 -1
  77. package/dist/resources/LMDBTransaction.d.ts +2 -1
  78. package/dist/resources/LMDBTransaction.js +22 -3
  79. package/dist/resources/LMDBTransaction.js.map +1 -1
  80. package/dist/resources/PrimaryRocksDatabase.js +22 -6
  81. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  82. package/dist/resources/RecordEncoder.d.ts +1 -1
  83. package/dist/resources/RecordEncoder.js +21 -5
  84. package/dist/resources/RecordEncoder.js.map +1 -1
  85. package/dist/resources/Resource.js +97 -13
  86. package/dist/resources/Resource.js.map +1 -1
  87. package/dist/resources/ResourceInterface.d.ts +8 -0
  88. package/dist/resources/RocksIndexStore.js +2 -1
  89. package/dist/resources/RocksIndexStore.js.map +1 -1
  90. package/dist/resources/RocksTransactionLogStore.d.ts +10 -0
  91. package/dist/resources/RocksTransactionLogStore.js +104 -33
  92. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  93. package/dist/resources/Table.d.ts +58 -7
  94. package/dist/resources/Table.js +1095 -346
  95. package/dist/resources/Table.js.map +1 -1
  96. package/dist/resources/analytics/write.js +10 -3
  97. package/dist/resources/analytics/write.js.map +1 -1
  98. package/dist/resources/auditStore.d.ts +170 -0
  99. package/dist/resources/auditStore.js +457 -11
  100. package/dist/resources/auditStore.js.map +1 -1
  101. package/dist/resources/dataLoader.js +3 -4
  102. package/dist/resources/dataLoader.js.map +1 -1
  103. package/dist/resources/databases.d.ts +16 -13
  104. package/dist/resources/databases.js +624 -176
  105. package/dist/resources/databases.js.map +1 -1
  106. package/dist/resources/derivedIndexRegistry.d.ts +5 -0
  107. package/dist/resources/derivedIndexRegistry.js +68 -0
  108. package/dist/resources/derivedIndexRegistry.js.map +1 -0
  109. package/dist/resources/derivedIndexRuntime.d.ts +215 -0
  110. package/dist/resources/derivedIndexRuntime.js +2027 -0
  111. package/dist/resources/derivedIndexRuntime.js.map +1 -0
  112. package/dist/resources/graphql.js +3 -2
  113. package/dist/resources/graphql.js.map +1 -1
  114. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +102 -9
  115. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +848 -39
  116. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  117. package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
  118. package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
  119. package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
  120. package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
  121. package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
  122. package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
  123. package/dist/resources/nodeIdMapping.d.ts +5 -0
  124. package/dist/resources/nodeIdMapping.js +49 -0
  125. package/dist/resources/nodeIdMapping.js.map +1 -1
  126. package/dist/resources/recordLock.d.ts +47 -4
  127. package/dist/resources/recordLock.js +138 -7
  128. package/dist/resources/recordLock.js.map +1 -1
  129. package/dist/resources/recordLockCoordinator.d.ts +557 -0
  130. package/dist/resources/recordLockCoordinator.js +2565 -0
  131. package/dist/resources/recordLockCoordinator.js.map +1 -0
  132. package/dist/resources/replayLogs.js +5 -0
  133. package/dist/resources/replayLogs.js.map +1 -1
  134. package/dist/resources/replicatedApplyFailure.d.ts +16 -0
  135. package/dist/resources/replicatedApplyFailure.js +63 -0
  136. package/dist/resources/replicatedApplyFailure.js.map +1 -0
  137. package/dist/resources/scheduler/scheduler.js +3 -3
  138. package/dist/resources/scheduler/scheduler.js.map +1 -1
  139. package/dist/resources/search.d.ts +10 -4
  140. package/dist/resources/search.js +160 -40
  141. package/dist/resources/search.js.map +1 -1
  142. package/dist/resources/tracked.d.ts +5 -1
  143. package/dist/resources/tracked.js +74 -23
  144. package/dist/resources/tracked.js.map +1 -1
  145. package/dist/security/jsLoader.js +6 -4
  146. package/dist/security/jsLoader.js.map +1 -1
  147. package/dist/server/REST.js +33 -2
  148. package/dist/server/REST.js.map +1 -1
  149. package/dist/server/http.d.ts +5 -1
  150. package/dist/server/http.js +34 -2
  151. package/dist/server/http.js.map +1 -1
  152. package/dist/server/serverHelpers/Headers.d.ts +2 -0
  153. package/dist/server/serverHelpers/Headers.js +6 -0
  154. package/dist/server/serverHelpers/Headers.js.map +1 -1
  155. package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
  156. package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
  157. package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
  158. package/dist/server/serverHelpers/Request.d.ts +5 -10
  159. package/dist/server/serverHelpers/Request.js +38 -136
  160. package/dist/server/serverHelpers/Request.js.map +1 -1
  161. package/dist/server/serverHelpers/contentTypes.d.ts +2 -0
  162. package/dist/server/serverHelpers/contentTypes.js +189 -15
  163. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  164. package/dist/server/serverHelpers/serverUtilities.js +96 -17
  165. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  166. package/dist/server/storageReclamation.js +1 -1
  167. package/dist/server/storageReclamation.js.map +1 -1
  168. package/dist/server/threads/isolatedApplications.d.ts +47 -0
  169. package/dist/server/threads/isolatedApplications.js +171 -0
  170. package/dist/server/threads/isolatedApplications.js.map +1 -0
  171. package/dist/server/threads/logRotationTransport.d.ts +1 -0
  172. package/dist/server/threads/logRotationTransport.js +33 -0
  173. package/dist/server/threads/logRotationTransport.js.map +1 -0
  174. package/dist/server/threads/manageThreads.d.ts +64 -6
  175. package/dist/server/threads/manageThreads.js +261 -12
  176. package/dist/server/threads/manageThreads.js.map +1 -1
  177. package/dist/server/threads/socketRouter.d.ts +1 -0
  178. package/dist/server/threads/socketRouter.js +196 -13
  179. package/dist/server/threads/socketRouter.js.map +1 -1
  180. package/dist/server/threads/threadServer.js +30 -7
  181. package/dist/server/threads/threadServer.js.map +1 -1
  182. package/dist/utility/errors/hdbError.d.ts +24 -0
  183. package/dist/utility/errors/hdbError.js +58 -1
  184. package/dist/utility/errors/hdbError.js.map +1 -1
  185. package/dist/utility/hdbTerms.d.ts +2 -0
  186. package/dist/utility/hdbTerms.js +2 -0
  187. package/dist/utility/hdbTerms.js.map +1 -1
  188. package/dist/utility/logging/harper_logger.js +217 -38
  189. package/dist/utility/logging/harper_logger.js.map +1 -1
  190. package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
  191. package/dist/utility/logging/logGenerationCoordinator.js +184 -0
  192. package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
  193. package/dist/utility/logging/logRotation.d.ts +46 -0
  194. package/dist/utility/logging/logRotation.js +365 -0
  195. package/dist/utility/logging/logRotation.js.map +1 -0
  196. package/dist/utility/logging/logRotator.d.ts +1 -1
  197. package/dist/utility/logging/logRotator.js +172 -92
  198. package/dist/utility/logging/logRotator.js.map +1 -1
  199. package/dist/utility/npmUtilities.js +6 -4
  200. package/dist/utility/npmUtilities.js.map +1 -1
  201. package/dist/utility/watcherFallback.d.ts +0 -45
  202. package/dist/utility/watcherFallback.js +1 -125
  203. package/dist/utility/watcherFallback.js.map +1 -1
  204. package/dist/validation/configValidator.js +6 -3
  205. package/dist/validation/configValidator.js.map +1 -1
  206. package/index.ts +6 -0
  207. package/json/systemSchema.json +3 -0
  208. package/npm-shrinkwrap.json +131 -41
  209. package/package.json +10 -3
  210. package/resources/DESIGN.md +124 -19
  211. package/resources/DatabaseTransaction.ts +230 -17
  212. package/resources/LMDBTransaction.ts +21 -3
  213. package/resources/PrimaryRocksDatabase.ts +20 -7
  214. package/resources/RecordEncoder.ts +25 -5
  215. package/resources/Resource.ts +97 -13
  216. package/resources/ResourceInterface.ts +8 -0
  217. package/resources/RocksIndexStore.ts +2 -1
  218. package/resources/RocksTransactionLogStore.ts +111 -31
  219. package/resources/Table.ts +1224 -393
  220. package/resources/analytics/write.ts +10 -3
  221. package/resources/auditStore.ts +460 -11
  222. package/resources/dataLoader.ts +3 -4
  223. package/resources/databases.ts +610 -146
  224. package/resources/derivedIndexRegistry.ts +56 -0
  225. package/resources/derivedIndexRuntime.ts +2292 -0
  226. package/resources/graphql.ts +3 -2
  227. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +905 -46
  228. package/resources/indexes/hnswDerivedIndex.ts +531 -0
  229. package/resources/indexes/hnswPlaneBinding.ts +174 -0
  230. package/resources/nodeIdMapping.ts +50 -0
  231. package/resources/recordLock.ts +173 -7
  232. package/resources/recordLockCoordinator.ts +3043 -0
  233. package/resources/replayLogs.ts +5 -0
  234. package/resources/replicatedApplyFailure.ts +77 -0
  235. package/resources/scheduler/scheduler.ts +4 -4
  236. package/resources/search.ts +169 -49
  237. package/resources/tracked.ts +73 -22
  238. package/security/jsLoader.ts +6 -4
  239. package/server/DESIGN.md +11 -0
  240. package/server/REST.ts +36 -3
  241. package/server/http.ts +34 -2
  242. package/server/serverHelpers/Headers.ts +5 -1
  243. package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
  244. package/server/serverHelpers/Request.ts +33 -131
  245. package/server/serverHelpers/contentTypes.ts +188 -15
  246. package/server/serverHelpers/serverUtilities.ts +143 -24
  247. package/server/storageReclamation.ts +2 -2
  248. package/server/threads/isolatedApplications.ts +157 -0
  249. package/server/threads/logRotationTransport.ts +40 -0
  250. package/server/threads/manageThreads.js +254 -12
  251. package/server/threads/socketRouter.ts +217 -11
  252. package/server/threads/threadServer.js +30 -7
  253. package/studio/web/assets/{Chat-BnCBegQz.js → Chat-D3j-1yY1.js} +1 -1
  254. package/studio/web/assets/{FloatingChat-CoDW1ySS.js → FloatingChat-BxJGYcfB.js} +3 -3
  255. package/studio/web/assets/{apiToken-Bwk5BLXW.js → apiToken-CT55oWOe.js} +1 -1
  256. package/studio/web/assets/{applications-DHxGi7JH.js → applications-D9Ct9_vm.js} +1 -1
  257. package/studio/web/assets/{cssMode-s0cWI-_M.js → cssMode-DV8H7VwA.js} +1 -1
  258. package/studio/web/assets/{editor-DNcRHK54.js → editor-uatc0unt.js} +1 -1
  259. package/studio/web/assets/{html-Bdssedlg.js → html-Bm6D6paN.js} +1 -1
  260. package/studio/web/assets/{htmlMode-CoDlJ3fw.js → htmlMode-CEn7tpLG.js} +1 -1
  261. package/studio/web/assets/{index-D6sxmFLR.js → index-BIXW6Pu4.js} +5 -5
  262. package/studio/web/assets/{index.lazy-tmU5BS8s.js → index.lazy-UI7L-Vrk.js} +1 -1
  263. package/studio/web/assets/{javascript-B8meVSTH.js → javascript-CJ0G3AFZ.js} +1 -1
  264. package/studio/web/assets/{jsonMode-DpIPd35T.js → jsonMode-DQADAYEa.js} +1 -1
  265. package/studio/web/assets/{languageServices-C_5FMJzQ.js → languageServices-CAQJXWcI.js} +1 -1
  266. package/studio/web/assets/{lspLanguageFeatures-BIzNBzPK.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
  267. package/studio/web/assets/{notifications-CQf18QKb.js → notifications-BbxTU6Aw.js} +1 -1
  268. package/studio/web/assets/{notifications-CvZivSbh.js → notifications-Cvb3P1lB.js} +1 -1
  269. package/studio/web/assets/{profile-DdOwtntb.js → profile-Yyb7gsvL.js} +1 -1
  270. package/studio/web/assets/{regions-n69fwagr.js → regions-OgjGHlU5.js} +1 -1
  271. package/studio/web/assets/{register-PfWTCXWB.js → register-6qwNEOY3.js} +2 -2
  272. package/studio/web/assets/{setComponentFile-Bg6O7X0S.js → setComponentFile-BilDMtgB.js} +1 -1
  273. package/studio/web/assets/{setup-CUx_aUDl.js → setup-J6qJ7OIU.js} +2 -2
  274. package/studio/web/assets/{status-D7BVKqX9.js → status-0RWGcfyD.js} +1 -1
  275. package/studio/web/assets/{toggleHighContrast-DBSyXzMr.js → toggleHighContrast-BIn-vErT.js} +1 -1
  276. package/studio/web/assets/{tsMode-BByKCjBS.js → tsMode-DgUXku4d.js} +1 -1
  277. package/studio/web/assets/{typescript-DDLnLpw9.js → typescript-C9orXcsM.js} +1 -1
  278. package/studio/web/assets/{useEntityRestURL-31CHGaHk.js → useEntityRestURL-BEoXXbUB.js} +1 -1
  279. package/studio/web/assets/{workers-pR3jRY9D.js → workers-JVzSDmgx.js} +1 -1
  280. package/studio/web/assets/{xml-2iRnMhQO.js → xml-Cq-S8S4X.js} +1 -1
  281. package/studio/web/assets/{yaml-Bf92gJpd.js → yaml-sfoRdh1M.js} +1 -1
  282. package/studio/web/index.html +1 -1
  283. package/utility/errors/hdbError.ts +54 -0
  284. package/utility/hdbTerms.ts +2 -0
  285. package/utility/logging/harper_logger.ts +209 -30
  286. package/utility/logging/logGenerationCoordinator.ts +196 -0
  287. package/utility/logging/logRotation.ts +367 -0
  288. package/utility/logging/logRotator.ts +196 -91
  289. package/utility/npmUtilities.ts +6 -4
  290. package/utility/watcherFallback.ts +0 -122
  291. package/validation/configValidator.ts +6 -3
@@ -0,0 +1,464 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HnswDerivedIndexBackend = exports.MAX_WAIT_FOR_INDEX_MILLISECONDS = exports.DEFAULT_MAX_INDEX_LAG_MILLISECONDS = exports.DERIVED_INDEX_CURSOR_KEY = void 0;
4
+ exports.attachDerivedIndexes = attachDerivedIndexes;
5
+ exports.derivedIndexReadiness = derivedIndexReadiness;
6
+ const hdbError_ts_1 = require("../../utility/errors/hdbError.js");
7
+ const logger_ts_1 = require("../../utility/logging/logger.js");
8
+ const derivedIndexRuntime_ts_1 = require("../derivedIndexRuntime.js");
9
+ const logger = (0, logger_ts_1.loggerWithTag)('HNSW');
10
+ /** The one durable cursor vector of a file-primary HNSW index, stored beside its node mappings. */
11
+ exports.DERIVED_INDEX_CURSOR_KEY = Symbol.for('derived-index-cursor');
12
+ exports.DEFAULT_MAX_INDEX_LAG_MILLISECONDS = 3000;
13
+ exports.MAX_WAIT_FOR_INDEX_MILLISECONDS = 30_000;
14
+ // Bounds on the queue between the runtime's delivery and the native applier. The runtime already
15
+ // chunks a delivery by records and estimated bytes; this caps how many chunks may wait.
16
+ const QUEUE_CAPACITY_BYTES = 64 * 1024 * 1024;
17
+ const APPLY_SLICE_MILLIS = 5;
18
+ const BARRIER_IDLE_MULTIPLE = 3;
19
+ const BARRIER_IDLE_CEILING_MILLISECONDS = 7_500;
20
+ // Writes to an index this far behind fail with a retryable 503 (see the runtime's lag policy).
21
+ const DEFAULT_MAX_LAG_MILLISECONDS = 30_000;
22
+ /**
23
+ * `DerivedIndexBackend` over a file-primary HNSW index. `deliver()` only enqueues; an applier drains
24
+ * the queue in bounded time slices so a 4096-record chunk at ~0.35 ms per native insert does not
25
+ * hold the event loop for a second and a half. The barrier is the plane's `msync`, after which the
26
+ * pending mappings and then the cursor vector are published — in that order, so a crash between
27
+ * any two steps leaves a cursor that replays (idempotently) over a mapping that was never published,
28
+ * never a published cursor over native state the barrier did not cover.
29
+ */
30
+ class HnswDerivedIndexBackend {
31
+ id;
32
+ #index;
33
+ #host;
34
+ #wake;
35
+ #queue = [];
36
+ #queuedBytes = 0;
37
+ #position = 0;
38
+ #scheduled = false;
39
+ #appliedCursor;
40
+ #appliedEpoch;
41
+ #flushRequested = false;
42
+ #flushing;
43
+ #interruptBarrierAfter = 0;
44
+ #resetting;
45
+ #unindexable = 0;
46
+ constructor(id, index) {
47
+ this.id = id;
48
+ this.#index = index;
49
+ }
50
+ attach(host) {
51
+ this.#host = host;
52
+ }
53
+ onStateChange(wake) {
54
+ this.#wake = wake;
55
+ return () => {
56
+ if (this.#wake === wake)
57
+ this.#wake = undefined;
58
+ };
59
+ }
60
+ getDurableCursor() {
61
+ const cursor = this.#index.indexStore.getSync(exports.DERIVED_INDEX_CURSOR_KEY);
62
+ return cursor === undefined ? undefined : cursor;
63
+ }
64
+ publishCoverage(positions, ownerEpoch) {
65
+ if (!this.#host?.isOwnerEpoch(ownerEpoch))
66
+ return;
67
+ const cursor = this.getDurableCursor();
68
+ if (!cursor)
69
+ throw new Error('Cannot publish native index coverage without a durable cursor');
70
+ if (cursor.coverage && (0, derivedIndexRuntime_ts_1.sameDerivedIndexPositions)(cursor.coverage, positions))
71
+ return;
72
+ this.#index.indexStore.putSync(exports.DERIVED_INDEX_CURSOR_KEY, { ...cursor, coverage: positions });
73
+ }
74
+ deliver(batch) {
75
+ if (this.#queuedBytes >= QUEUE_CAPACITY_BYTES)
76
+ return derivedIndexRuntime_ts_1.DERIVED_INDEX_DEFERRED;
77
+ this.#queue.push(batch);
78
+ this.#queuedBytes += batch.bytes;
79
+ this.#schedule();
80
+ return derivedIndexRuntime_ts_1.DERIVED_INDEX_ACCEPTED;
81
+ }
82
+ flush(_reason) {
83
+ this.#flushRequested = true;
84
+ if (this.#queue.length === 0 && !this.#scheduled)
85
+ this.#runFlush();
86
+ }
87
+ /**
88
+ * Drop what is queued and resolve once no barrier is in flight. The runtime quiesces an epoch
89
+ * before it mints the next, so nothing of a newer epoch can be queued here yet.
90
+ */
91
+ async shutdown(_epoch) {
92
+ this.#dropQueue();
93
+ await Promise.allSettled([this.#flushing, this.#resetting]);
94
+ }
95
+ /**
96
+ * The cursor goes first: a crash anywhere after this line reopens cursorless and rebuilds, never
97
+ * on a format-valid cursor over a destroyed graph.
98
+ */
99
+ reset(_epoch) {
100
+ this.#dropQueue();
101
+ this.#appliedCursor = undefined;
102
+ this.#resetting = (async () => {
103
+ await this.#flushing;
104
+ this.#index.indexStore.removeSync(exports.DERIVED_INDEX_CURSOR_KEY);
105
+ this.#index.resetDerivedStorage();
106
+ await this.#index.indexStore.clear();
107
+ })();
108
+ return this.#resetting.finally(() => (this.#resetting = undefined));
109
+ }
110
+ #dropQueue() {
111
+ this.#queue.length = 0;
112
+ this.#queuedBytes = 0;
113
+ this.#position = 0;
114
+ }
115
+ #schedule() {
116
+ if (this.#scheduled)
117
+ return;
118
+ this.#scheduled = true;
119
+ setImmediate(() => {
120
+ this.#scheduled = false;
121
+ this.#applySlice();
122
+ });
123
+ }
124
+ #applySlice() {
125
+ // Application pauses while a barrier is in flight so the barrier publishes exactly the
126
+ // mappings it covers; the flush reschedules application when it settles.
127
+ if (this.#flushing)
128
+ return;
129
+ const host = this.#host;
130
+ const until = performance.now() + APPLY_SLICE_MILLIS;
131
+ const wasFull = this.#queuedBytes >= QUEUE_CAPACITY_BYTES;
132
+ let advancedCursor = false;
133
+ while (this.#queue.length > 0 && performance.now() < until) {
134
+ const batch = this.#queue[0];
135
+ if (!host.isOwnerEpoch(batch.ownerEpoch)) {
136
+ this.#queue.shift();
137
+ this.#queuedBytes -= batch.bytes;
138
+ this.#position = 0;
139
+ continue;
140
+ }
141
+ const records = batch.records;
142
+ while (this.#position < records.length && performance.now() < until) {
143
+ try {
144
+ this.#apply(records[this.#position++]);
145
+ }
146
+ catch (error) {
147
+ this.#queue.length = 0;
148
+ this.#queuedBytes = 0;
149
+ this.#position = 0;
150
+ logger.error(`Derived index '${this.id}' could not apply a record; requesting a rebuild`, error);
151
+ this.#wake?.('failed');
152
+ return;
153
+ }
154
+ }
155
+ if (this.#position < records.length)
156
+ break;
157
+ this.#queue.shift();
158
+ this.#queuedBytes -= batch.bytes;
159
+ this.#position = 0;
160
+ this.#appliedEpoch = batch.ownerEpoch;
161
+ if (batch.through) {
162
+ this.#appliedCursor = batch.through;
163
+ advancedCursor = true;
164
+ if (this.#mayInterruptForBarrier())
165
+ break;
166
+ }
167
+ }
168
+ if (this.#queue.length > 0) {
169
+ if (wasFull && this.#queuedBytes < QUEUE_CAPACITY_BYTES)
170
+ this.#wake?.('changed');
171
+ if (this.#position === 0 && advancedCursor && this.#mayInterruptForBarrier())
172
+ this.#runFlush(true);
173
+ else
174
+ this.#schedule();
175
+ return;
176
+ }
177
+ if (wasFull)
178
+ this.#wake?.('changed');
179
+ if (this.#flushRequested)
180
+ this.#runFlush();
181
+ }
182
+ #apply(mutation) {
183
+ const { recordId, logVersion, state } = mutation;
184
+ if (state.kind !== 'record' || state.projection == null) {
185
+ this.#index.applyDerivedValue(recordId, undefined, logVersion);
186
+ return;
187
+ }
188
+ try {
189
+ this.#index.applyDerivedValue(recordId, state.projection, state.version);
190
+ }
191
+ catch (error) {
192
+ // The projection validated the vector, but the plane's dimensionality is only known to the
193
+ // worker holding it: a mismatch is this record's fault, not the index's. Same rule as the
194
+ // runtime's own 4xx handling — remove any entry and count it, never rebuild.
195
+ if (!(error instanceof hdbError_ts_1.ClientError))
196
+ throw error;
197
+ if (this.#unindexable++ === 0)
198
+ logger.warn?.(`Derived index '${this.id}' skipped a record its plane cannot hold: ${error.message}`);
199
+ this.#index.applyDerivedValue(recordId, undefined, state.version);
200
+ }
201
+ }
202
+ #mayInterruptForBarrier() {
203
+ return this.#flushRequested && performance.now() >= this.#interruptBarrierAfter;
204
+ }
205
+ #runFlush(interrupting = false) {
206
+ if (this.#flushing)
207
+ return;
208
+ this.#flushRequested = false;
209
+ const started = performance.now();
210
+ const cursor = this.#appliedCursor;
211
+ const epoch = this.#appliedEpoch;
212
+ const host = this.#host;
213
+ this.#flushing = (async () => {
214
+ await this.#index.flushDerived();
215
+ if (epoch !== undefined && !host.isOwnerEpoch(epoch))
216
+ return;
217
+ if (cursor) {
218
+ const coverage = this.getDurableCursor()?.coverage;
219
+ this.#index.indexStore.putSync(exports.DERIVED_INDEX_CURSOR_KEY, coverage ? { ...cursor, coverage } : cursor);
220
+ }
221
+ })();
222
+ this.#flushing.then(() => {
223
+ this.#flushing = undefined;
224
+ if (interrupting) {
225
+ const idle = Math.min(BARRIER_IDLE_MULTIPLE * (performance.now() - started), BARRIER_IDLE_CEILING_MILLISECONDS);
226
+ this.#interruptBarrierAfter = performance.now() + idle;
227
+ }
228
+ this.#wake?.('changed');
229
+ if (this.#queue.length > 0)
230
+ this.#schedule();
231
+ else if (this.#flushRequested)
232
+ this.#runFlush();
233
+ }, (error) => {
234
+ this.#flushing = undefined;
235
+ logger.error(`Derived index '${this.id}' durability barrier failed`, error);
236
+ this.#wake?.('failed');
237
+ });
238
+ }
239
+ }
240
+ exports.HnswDerivedIndexBackend = HnswDerivedIndexBackend;
241
+ const runtimes = new WeakMap();
242
+ const retryUnavailableByStore = new Set();
243
+ function retryUnavailableKey(auditStore, backendId) {
244
+ return `${auditStore.rootStore.path}\0${backendId}`;
245
+ }
246
+ function markUnavailableRetry(registered, auditStore, backendId) {
247
+ registered.retryUnavailable.add(backendId);
248
+ retryUnavailableByStore.add(retryUnavailableKey(auditStore, backendId));
249
+ }
250
+ function consumeUnavailableRetry(registered, auditStore, backendId) {
251
+ const local = registered.retryUnavailable.delete(backendId);
252
+ const storeScoped = retryUnavailableByStore.delete(retryUnavailableKey(auditStore, backendId));
253
+ return local || storeScoped;
254
+ }
255
+ function runtimeFor(auditStore) {
256
+ let registered = runtimes.get(auditStore);
257
+ if (registered)
258
+ return registered;
259
+ const tables = new Map();
260
+ const runtime = new derivedIndexRuntime_ts_1.DerivedIndexRuntime(auditStore, (tableId, recordId) => {
261
+ const entry = tables.get(tableId)?.current.Table.primaryStore.getEntry(recordId);
262
+ return entry?.value == null ? undefined : { version: entry.version, value: entry.value };
263
+ }, {
264
+ scanRecords: (tableId) => tables
265
+ .get(tableId)
266
+ .current.Table.primaryStore.getRange({ versions: true, snapshot: false })
267
+ .map(({ key, value, version }) => ({ recordId: key, version, value })),
268
+ });
269
+ registered = {
270
+ runtime,
271
+ tables,
272
+ backends: new Map(),
273
+ tableBackends: new Map(),
274
+ droppingTables: new Set(),
275
+ retryUnavailable: new Set(),
276
+ };
277
+ runtimes.set(auditStore, registered);
278
+ return registered;
279
+ }
280
+ const warnedAuditIndexes = new Set();
281
+ /**
282
+ * Register every post-commit custom index of a table with the shared derived-index runtime of its
283
+ * database. Returns the release for the table's registrations, or undefined when it has none. Runs
284
+ * on every worker; the runtime elects one owner per index.
285
+ */
286
+ function attachDerivedIndexes(Table) {
287
+ const hnswAttributes = Table.attributes.filter((attribute) => attribute.indexed?.type === 'HNSW' && Table.indices[attribute.name]?.customIndex);
288
+ const attributes = hnswAttributes.filter((attribute) => Table.indices[attribute.name]?.customIndex?.postCommit);
289
+ if (Table.audit !== true && attributes.length > 0) {
290
+ throw new hdbError_ts_1.ClientError(`Table '${Table.databaseName}.${Table.tableName}' must enable audit logging before using a post-commit derived index`);
291
+ }
292
+ if (!Table.auditStore)
293
+ return;
294
+ const auditStore = Table.auditStore;
295
+ const registered = runtimeFor(auditStore);
296
+ if (registered.droppingTables.has(Table.tableId))
297
+ return;
298
+ for (const attribute of hnswAttributes) {
299
+ const indexStore = Table.indices[attribute.name];
300
+ const id = `hnsw:${indexStore.name}`;
301
+ // A transient JS-backed declaration can precede the first native registration while a
302
+ // schema is being installed. Only an explicit transition away from an already-registered
303
+ // native backend should make a later native registration eligible to rearm an exhausted
304
+ // rebuild budget.
305
+ if (attribute.indexed.nativePlane === false && !indexStore.customIndex.postCommit && registered.backends.has(id))
306
+ markUnavailableRetry(registered, auditStore, id);
307
+ }
308
+ if (attributes.length === 0)
309
+ return;
310
+ const installed = { Table };
311
+ let registeredTable = registered.tables.get(Table.tableId);
312
+ if (registeredTable) {
313
+ registeredTable.owners.add(installed);
314
+ registeredTable.current = installed;
315
+ }
316
+ else {
317
+ registeredTable = { current: installed, owners: new Set([installed]) };
318
+ registered.tables.set(Table.tableId, registeredTable);
319
+ }
320
+ const releases = [];
321
+ const backendIds = [];
322
+ const registeredBackends = new Map();
323
+ for (const attribute of attributes) {
324
+ const indexStore = Table.indices[attribute.name];
325
+ const index = indexStore.customIndex;
326
+ const id = `hnsw:${indexStore.name}`;
327
+ const warningKey = `${Table.databaseName}.${Table.tableName}.${indexStore.name}`;
328
+ if (!warnedAuditIndexes.has(warningKey)) {
329
+ warnedAuditIndexes.add(warningKey);
330
+ logger.warn?.(`Derived index ${indexStore.name} requires auditing; the audit API retains full record history for the configured retention window`);
331
+ }
332
+ const resolver = Table.propertyResolvers?.[attribute.name];
333
+ const label = `Vector for attribute "${attribute.name}"`;
334
+ index.attachDerivedHost({
335
+ readiness: () => registered.runtime.getReadiness(id),
336
+ coverage: (maxLagMilliseconds) => (0, derivedIndexRuntime_ts_1.readDerivedIndexCoverage)(auditStore, id, () => indexStore.getSync(exports.DERIVED_INDEX_CURSOR_KEY), maxLagMilliseconds),
337
+ requestRebuild: () => registered.runtime.requestRebuild(id),
338
+ waitForCoverage: (since, timeout, signal) => registered.runtime.waitForCoverage(id, since, timeout, signal),
339
+ });
340
+ let predecessor = registered.backends.get(id);
341
+ const inherited = predecessor;
342
+ const settlePredecessor = () => {
343
+ const current = predecessor;
344
+ if (!current)
345
+ return Promise.resolve();
346
+ const settled = current.settle();
347
+ settled.then(() => {
348
+ if (predecessor === current)
349
+ predecessor = undefined;
350
+ }, () => { });
351
+ return settled;
352
+ };
353
+ const predecessorSettled = settlePredecessor();
354
+ predecessorSettled.catch(() => { });
355
+ if (registered.backends.get(id) === inherited)
356
+ registered.backends.delete(id);
357
+ const release = registered.runtime.register({
358
+ backend: new HnswDerivedIndexBackend(id, index),
359
+ projections: new Map([
360
+ [
361
+ Table.tableId,
362
+ (record) => {
363
+ const vector = resolver ? resolver(record) : record[attribute.name];
364
+ if (vector == null)
365
+ return undefined;
366
+ index.assertDerivedValue(vector, label);
367
+ return vector;
368
+ },
369
+ ],
370
+ ]),
371
+ options: { maxLagMilliseconds: attribute.indexed?.maxLagMilliseconds ?? DEFAULT_MAX_LAG_MILLISECONDS },
372
+ });
373
+ let settling;
374
+ const registeredBackend = {
375
+ tableId: Table.tableId,
376
+ settle: () => {
377
+ if (settling)
378
+ return settling;
379
+ const attempt = Promise.allSettled([settlePredecessor(), release()]).then((results) => {
380
+ if (results[1].status === 'fulfilled') {
381
+ if (registered.backends.get(id) === registeredBackend)
382
+ registered.backends.delete(id);
383
+ const tableBackends = registered.tableBackends.get(Table.tableId);
384
+ tableBackends?.delete(registeredBackend);
385
+ if (tableBackends?.size === 0)
386
+ registered.tableBackends.delete(Table.tableId);
387
+ }
388
+ const failures = results
389
+ .filter((result) => result.status === 'rejected')
390
+ .map((result) => result.reason);
391
+ if (failures.length === 1)
392
+ throw failures[0];
393
+ if (failures.length)
394
+ throw new AggregateError(failures, `Could not settle HNSW backend '${id}'`);
395
+ });
396
+ settling = attempt;
397
+ attempt.catch(() => {
398
+ if (settling === attempt)
399
+ settling = undefined;
400
+ });
401
+ return attempt;
402
+ },
403
+ };
404
+ let tableBackends = registered.tableBackends.get(Table.tableId);
405
+ if (!tableBackends)
406
+ registered.tableBackends.set(Table.tableId, (tableBackends = new Set()));
407
+ tableBackends.add(registeredBackend);
408
+ registered.backends.set(id, registeredBackend);
409
+ registeredBackends.set(id, registeredBackend);
410
+ const retryUnavailable = consumeUnavailableRetry(registered, auditStore, id);
411
+ if (retryUnavailable && registered.runtime.getReadiness(id).state === 'unavailable')
412
+ registered.runtime.requestRebuild(id);
413
+ backendIds.push(id);
414
+ releases.push(() => registeredBackend.settle());
415
+ }
416
+ return {
417
+ async close(dropping = false) {
418
+ if (dropping)
419
+ registered.droppingTables.add(Table.tableId);
420
+ const settlements = dropping
421
+ ? [...(registered.tableBackends.get(Table.tableId) ?? [])].map((backend) => backend.settle())
422
+ : releases.map((release) => release());
423
+ const tableRegistration = registered.tables.get(Table.tableId);
424
+ if (tableRegistration) {
425
+ tableRegistration.owners.delete(installed);
426
+ if (tableRegistration.owners.size === 0) {
427
+ registered.tables.delete(Table.tableId);
428
+ }
429
+ else if (tableRegistration.current === installed) {
430
+ tableRegistration.current = tableRegistration.owners.values().next().value;
431
+ }
432
+ }
433
+ if (dropping) {
434
+ await Promise.all(settlements);
435
+ }
436
+ else {
437
+ for (const result of await Promise.allSettled(settlements)) {
438
+ if (result.status === 'rejected')
439
+ logger.error(`Could not settle a superseded HNSW backend for table ${Table.tableId}`, result.reason);
440
+ }
441
+ }
442
+ },
443
+ restoreAfterFailedDrop() {
444
+ registered.droppingTables.delete(Table.tableId);
445
+ for (const [id, registeredBackend] of registeredBackends) {
446
+ const current = registered.backends.get(id);
447
+ if (current && current !== registeredBackend)
448
+ return;
449
+ }
450
+ return attachDerivedIndexes(Table);
451
+ },
452
+ completeDrop(dropped = true) {
453
+ registered.droppingTables.delete(Table.tableId);
454
+ if (dropped)
455
+ for (const id of backendIds)
456
+ markUnavailableRetry(registered, auditStore, id);
457
+ },
458
+ };
459
+ }
460
+ /** Shared readiness of an index on any worker, registered or not. */
461
+ function derivedIndexReadiness(auditStore, indexStoreName) {
462
+ return (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(auditStore, `hnsw:${indexStoreName}`);
463
+ }
464
+ //# sourceMappingURL=hnswDerivedIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hnswDerivedIndex.js","sourceRoot":"","sources":["../../../resources/indexes/hnswDerivedIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Parallel arrays, ascending by distance: hit i is (ids[i], distances[i]) with its host key at
3
+ * keys.subarray(keyEnds[i - 1] ?? 0, keyEnds[i]); an empty key means the node vanished mid-query.
4
+ */
5
+ export interface PlaneSearchHits {
6
+ ids: Uint32Array;
7
+ distances: Float32Array;
8
+ keys: Buffer;
9
+ keyEnds: Uint32Array;
10
+ }
11
+ /** A predicate batch: candidate ids and their host keys, laid out as in PlaneSearchHits. */
12
+ export type PlanePredicate = (ids: number[], keys: Buffer, keyEnds: Uint32Array) => Uint8Array;
13
+ /** NAPI surface of the native file-primary HNSW index (`@harperfast/hnsw`). */
14
+ export interface HnswPlane {
15
+ readonly dims: number;
16
+ readonly layer0Cap: number;
17
+ readonly keyCap: number;
18
+ insert(vector: Float32Array, key?: Buffer): number;
19
+ remove(id: number): void;
20
+ writeNodeRaw(id: number, level: number, vector: Buffer, scale: number, invMag: number, neighbors: Uint32Array, upper: Uint32Array[] | null): void;
21
+ clearNode(id: number): void;
22
+ setEntryPoint(id: number, level: number): void;
23
+ getEntryPoint(): number[];
24
+ search(vector: Float32Array, k: number, ef: number, filter?: Uint8Array | null, filterExpansion?: number | null): Promise<PlaneSearchHits>;
25
+ searchWithPredicate(vector: Float32Array, k: number, ef: number, predicate: PlanePredicate, filterExpansion?: number | null, visitBudget?: number | null): Promise<PlaneSearchHits>;
26
+ searchSync(vector: Float32Array, k: number, ef: number): PlaneSearchHits;
27
+ writeNodeRawIfAbsent(id: number, level: number, vector: Buffer, scale: number, invMag: number, neighbors: Uint32Array, upper: Uint32Array[] | null): boolean;
28
+ openedClean(): boolean;
29
+ idHighWater(): number;
30
+ getWatermark(): number;
31
+ setWatermark(txn: number): void;
32
+ flush(watermark?: number): void;
33
+ flushAsync(watermark?: number): Promise<void>;
34
+ invalidateFile(): PlaneInvalidationOutcome;
35
+ invalidated(): boolean;
36
+ }
37
+ export interface HnswPlaneConstructor {
38
+ readonly prototype: HnswPlane;
39
+ create(path: string, dims: number, layer0Cap: number, maxNodes: number, keyCap?: number): HnswPlane;
40
+ open(path: string): HnswPlane;
41
+ }
42
+ export interface PlaneInvalidationOutcome {
43
+ inBand: boolean;
44
+ sidecar: boolean;
45
+ inBandError?: string;
46
+ sidecarError?: string;
47
+ }
48
+ /** Entry-point id meaning "none" (u32::MAX in the plane header). */
49
+ export declare const PLANE_NO_ID = 4294967295;
50
+ /**
51
+ * Where an index's plane file lives: next to its store, named by the dbiKey
52
+ * (`table/attribute`, flattened to a single file name). Exposed separately from the index
53
+ * instance so crash-recovery drop paths can remove the file without opening the index.
54
+ */
55
+ export declare function planeFilePathFor(storePath: string, storeName: string): string;
56
+ /**
57
+ * Tombstone marking a plane file that could not be deleted (e.g. Windows EBUSY while still
58
+ * mapped). Its presence means the plane file is STALE: never open it — delete both when
59
+ * possible and rebuild.
60
+ */
61
+ export declare function planeStalePathFor(planePath: string): string;
62
+ /** The native plane constructor, or null when the compiled artifact is unavailable (warns once by default). */
63
+ export declare function getPlaneBinding(warn?: boolean): HnswPlaneConstructor | null;
64
+ /** Make a derived plane unadoptable before it is replaced or removed. */
65
+ export declare function invalidatePlaneFile(filePath: string, attached?: HnswPlane | null): PlaneInvalidationOutcome;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PLANE_NO_ID = void 0;
4
+ exports.planeFilePathFor = planeFilePathFor;
5
+ exports.planeStalePathFor = planeStalePathFor;
6
+ exports.getPlaneBinding = getPlaneBinding;
7
+ exports.invalidatePlaneFile = invalidatePlaneFile;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
10
+ const logger_ts_1 = require("../../utility/logging/logger.js");
11
+ const logger = (0, logger_ts_1.loggerWithTag)('HNSW');
12
+ /** Entry-point id meaning "none" (u32::MAX in the plane header). */
13
+ exports.PLANE_NO_ID = 0xffffffff;
14
+ /**
15
+ * Where an index's plane file lives: next to its store, named by the dbiKey
16
+ * (`table/attribute`, flattened to a single file name). Exposed separately from the index
17
+ * instance so crash-recovery drop paths can remove the file without opening the index.
18
+ */
19
+ function planeFilePathFor(storePath, storeName) {
20
+ // encodeURIComponent is injective and never emits a path separator: table `a` attribute
21
+ // `b.c` and table `a.b` attribute `c` must not share a plane file (dot-flattening let two
22
+ // indexes serve each other's node ids as their own primary keys)
23
+ return (0, node_path_1.join)(storePath, `${encodeURIComponent(storeName)}.hnsw`);
24
+ }
25
+ /**
26
+ * Tombstone marking a plane file that could not be deleted (e.g. Windows EBUSY while still
27
+ * mapped). Its presence means the plane file is STALE: never open it — delete both when
28
+ * possible and rebuild.
29
+ */
30
+ function planeStalePathFor(planePath) {
31
+ // the package owns the convention; the literal covers the calls that precede its load
32
+ return binding?.stalePathFor(planePath) ?? `${planePath}.stale`;
33
+ }
34
+ let binding;
35
+ let bindingLoadError;
36
+ let bindingWarningLogged = false;
37
+ function getHnswPackage(warn = true) {
38
+ if (binding === undefined) {
39
+ try {
40
+ binding = require('@harperfast/hnsw');
41
+ }
42
+ catch (error) {
43
+ binding = null;
44
+ bindingLoadError = error;
45
+ }
46
+ }
47
+ if (binding === null && warn && !bindingWarningLogged) {
48
+ bindingWarningLogged = true;
49
+ logger.warn?.(`The @harperfast/hnsw native module is not available (${bindingLoadError?.message}); ` +
50
+ 'indexes with nativePlane enabled will remain unavailable until the module can load');
51
+ }
52
+ return binding;
53
+ }
54
+ /** The native plane constructor, or null when the compiled artifact is unavailable (warns once by default). */
55
+ function getPlaneBinding(warn = true) {
56
+ return getHnswPackage(warn)?.Plane ?? null;
57
+ }
58
+ /** Make a derived plane unadoptable before it is replaced or removed. */
59
+ function invalidatePlaneFile(filePath, attached) {
60
+ if (attached)
61
+ return attached.invalidateFile();
62
+ const hnswPackage = getHnswPackage();
63
+ if (hnswPackage)
64
+ return hnswPackage.invalidatePlane(filePath);
65
+ // A plane can outlive the package that made it (uninstall, or a prebuild that stopped
66
+ // loading), and a reinstall would then adopt it. Only the sidecar is reachable without the
67
+ // package, and it has to survive a power loss to be worth writing, so fsync it and the
68
+ // directory entry that names it — the same durability the package's own sidecar has.
69
+ const fd = (0, node_fs_1.openSync)(planeStalePathFor(filePath), 'w');
70
+ try {
71
+ (0, node_fs_1.fsyncSync)(fd);
72
+ }
73
+ finally {
74
+ (0, node_fs_1.closeSync)(fd);
75
+ }
76
+ try {
77
+ const dirFd = (0, node_fs_1.openSync)((0, node_path_1.dirname)(filePath), 'r');
78
+ try {
79
+ (0, node_fs_1.fsyncSync)(dirFd);
80
+ }
81
+ finally {
82
+ (0, node_fs_1.closeSync)(dirFd);
83
+ }
84
+ }
85
+ catch {
86
+ // Windows cannot open a directory as a file; it also does not need this — the metadata
87
+ // journal already orders the create ahead of anything that could read the sidecar
88
+ }
89
+ return { inBand: false, sidecar: true };
90
+ }
91
+ //# sourceMappingURL=hnswPlaneBinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hnswPlaneBinding.js","sourceRoot":"","sources":["../../../resources/indexes/hnswPlaneBinding.ts"],"names":[],"mappings":";;;AAqGA,4CAKC;AAOD,8CAGC;AA0BD,0CAEC;AAGD,kDA0BC;AA7KD,qCAAyD;AACzD,yCAA0C;AAC1C,+DAAgE;AAEhE,MAAM,MAAM,GAAG,IAAA,yBAAa,EAAC,MAAM,CAAC,CAAC;AAyFrC,oEAAoE;AACvD,QAAA,WAAW,GAAG,UAAU,CAAC;AAEtC;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,SAAiB,EAAE,SAAiB;IACpE,wFAAwF;IACxF,0FAA0F;IAC1F,iEAAiE;IACjE,OAAO,IAAA,gBAAI,EAAC,SAAS,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,SAAiB;IAClD,sFAAsF;IACtF,OAAO,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI,GAAG,SAAS,QAAQ,CAAC;AACjE,CAAC;AAED,IAAI,OAA4C,CAAC;AACjD,IAAI,gBAAmC,CAAC;AACxC,IAAI,oBAAoB,GAAG,KAAK,CAAC;AAEjC,SAAS,cAAc,CAAC,IAAI,GAAG,IAAI;IAClC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACJ,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAqB,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,gBAAgB,GAAG,KAAc,CAAC;QACnC,CAAC;IACF,CAAC;IACD,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACvD,oBAAoB,GAAG,IAAI,CAAC;QAC5B,MAAM,CAAC,IAAI,EAAE,CACZ,wDAAwD,gBAAgB,EAAE,OAAO,KAAK;YACrF,oFAAoF,CACrF,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,+GAA+G;AAC/G,SAAgB,eAAe,CAAC,IAAI,GAAG,IAAI;IAC1C,OAAO,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,SAAgB,mBAAmB,CAAC,QAAgB,EAAE,QAA2B;IAChF,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC/C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC9D,sFAAsF;IACtF,2FAA2F;IAC3F,uFAAuF;IACvF,qFAAqF;IACrF,MAAM,EAAE,GAAG,IAAA,kBAAQ,EAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC;QACJ,IAAA,mBAAS,EAAC,EAAE,CAAC,CAAC;IACf,CAAC;YAAS,CAAC;QACV,IAAA,mBAAS,EAAC,EAAE,CAAC,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,IAAA,mBAAO,EAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC;YACJ,IAAA,mBAAS,EAAC,KAAK,CAAC,CAAC;QAClB,CAAC;gBAAS,CAAC;YACV,IAAA,mBAAS,EAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,uFAAuF;QACvF,kFAAkF;IACnF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -11,3 +11,8 @@ export declare function getIdOfRemoteNode(remoteNodeName: any, auditStore: any):
11
11
  */
12
12
  export declare function lastTimeInAuditStore(auditStore: Database): import("lmdb").Key;
13
13
  export declare function getThisNodeId(auditStore: any): any;
14
+ /**
15
+ * The node name a local short id refers to. Callers that must attribute a replicated entry to its
16
+ * origin node need the globally stable name, not the id, which is assigned per node.
17
+ */
18
+ export declare function getNodeNameForId(auditStore: any, nodeId: number | undefined, rebuildOnMiss?: boolean): string | undefined;