@bsv/overlay 2.3.0 → 2.6.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 (207) hide show
  1. package/LICENSES/Open-BSV-License-4-standard-pre-2026.txt +28 -0
  2. package/README.md +171 -1
  3. package/THIRD_PARTY_NOTICES.md +49 -0
  4. package/dist/cjs/mod.d.ts +4 -1
  5. package/dist/cjs/mod.d.ts.map +1 -1
  6. package/dist/cjs/mod.js +8 -1
  7. package/dist/cjs/mod.js.map +1 -1
  8. package/dist/cjs/package.json +13 -5
  9. package/dist/cjs/src/BASM.d.ts +6 -0
  10. package/dist/cjs/src/BASM.d.ts.map +1 -1
  11. package/dist/cjs/src/BASM.js +21 -8
  12. package/dist/cjs/src/BASM.js.map +1 -1
  13. package/dist/cjs/src/BASMRemote.d.ts +8 -1
  14. package/dist/cjs/src/BASMRemote.d.ts.map +1 -1
  15. package/dist/cjs/src/BASMRemote.js +179 -13
  16. package/dist/cjs/src/BASMRemote.js.map +1 -1
  17. package/dist/cjs/src/BASMValidation.d.ts +27 -0
  18. package/dist/cjs/src/BASMValidation.d.ts.map +1 -0
  19. package/dist/cjs/src/BASMValidation.js +108 -0
  20. package/dist/cjs/src/BASMValidation.js.map +1 -0
  21. package/dist/cjs/src/DiscoveryAdvertisementValidation.d.ts +11 -0
  22. package/dist/cjs/src/DiscoveryAdvertisementValidation.d.ts.map +1 -0
  23. package/dist/cjs/src/DiscoveryAdvertisementValidation.js +60 -0
  24. package/dist/cjs/src/DiscoveryAdvertisementValidation.js.map +1 -0
  25. package/dist/cjs/src/Engine.d.ts +38 -13
  26. package/dist/cjs/src/Engine.d.ts.map +1 -1
  27. package/dist/cjs/src/Engine.js +1735 -336
  28. package/dist/cjs/src/Engine.js.map +1 -1
  29. package/dist/cjs/src/EngineAdmission.d.ts +70 -0
  30. package/dist/cjs/src/EngineAdmission.d.ts.map +1 -0
  31. package/dist/cjs/src/EngineAdmission.js +297 -0
  32. package/dist/cjs/src/EngineAdmission.js.map +1 -0
  33. package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts +4 -3
  34. package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts.map +1 -1
  35. package/dist/cjs/src/GASP/OverlayGASPRemote.js +27 -43
  36. package/dist/cjs/src/GASP/OverlayGASPRemote.js.map +1 -1
  37. package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts +22 -16
  38. package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts.map +1 -1
  39. package/dist/cjs/src/GASP/OverlayGASPStorage.js +206 -57
  40. package/dist/cjs/src/GASP/OverlayGASPStorage.js.map +1 -1
  41. package/dist/cjs/src/RemoteSecurity.d.ts +50 -0
  42. package/dist/cjs/src/RemoteSecurity.d.ts.map +1 -0
  43. package/dist/cjs/src/RemoteSecurity.js +301 -0
  44. package/dist/cjs/src/RemoteSecurity.js.map +1 -0
  45. package/dist/cjs/src/TopicManager.d.ts +13 -3
  46. package/dist/cjs/src/TopicManager.d.ts.map +1 -1
  47. package/dist/cjs/src/storage/AdmissionStorage.d.ts +185 -0
  48. package/dist/cjs/src/storage/AdmissionStorage.d.ts.map +1 -0
  49. package/dist/cjs/src/storage/AdmissionStorage.js +93 -0
  50. package/dist/cjs/src/storage/AdmissionStorage.js.map +1 -0
  51. package/dist/cjs/src/storage/RecoveryContract.d.ts +50 -0
  52. package/dist/cjs/src/storage/RecoveryContract.d.ts.map +1 -0
  53. package/dist/cjs/src/storage/RecoveryContract.js +35 -0
  54. package/dist/cjs/src/storage/RecoveryContract.js.map +1 -0
  55. package/dist/cjs/src/storage/Storage.d.ts +32 -19
  56. package/dist/cjs/src/storage/Storage.d.ts.map +1 -1
  57. package/dist/cjs/src/storage/Storage.js +5 -0
  58. package/dist/cjs/src/storage/Storage.js.map +1 -1
  59. package/dist/cjs/src/storage/knex/KnexStorage.d.ts +8 -8
  60. package/dist/cjs/src/storage/knex/KnexStorage.d.ts.map +1 -1
  61. package/dist/cjs/src/storage/knex/KnexStorage.js +98 -61
  62. package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -1
  63. package/dist/cjs/src/storage/knex/all-migrations.d.ts.map +1 -1
  64. package/dist/cjs/src/storage/knex/all-migrations.js +5 -1
  65. package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -1
  66. package/dist/cjs/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.d.ts +4 -0
  67. package/dist/cjs/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.d.ts.map +1 -0
  68. package/dist/cjs/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.js +36 -0
  69. package/dist/cjs/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.js.map +1 -0
  70. package/dist/cjs/src/storage/knex/migrations/2026-09-20-001-spent-by.d.ts +5 -0
  71. package/dist/cjs/src/storage/knex/migrations/2026-09-20-001-spent-by.d.ts.map +1 -0
  72. package/dist/cjs/src/storage/knex/migrations/2026-09-20-001-spent-by.js +16 -0
  73. package/dist/cjs/src/storage/knex/migrations/2026-09-20-001-spent-by.js.map +1 -0
  74. package/dist/cjs/src/storage/mongo/MongoAdmissionPlan.d.ts +18 -0
  75. package/dist/cjs/src/storage/mongo/MongoAdmissionPlan.d.ts.map +1 -0
  76. package/dist/cjs/src/storage/mongo/MongoAdmissionPlan.js +229 -0
  77. package/dist/cjs/src/storage/mongo/MongoAdmissionPlan.js.map +1 -0
  78. package/dist/cjs/src/storage/mongo/MongoAdmissionStorage.d.ts +112 -0
  79. package/dist/cjs/src/storage/mongo/MongoAdmissionStorage.d.ts.map +1 -0
  80. package/dist/cjs/src/storage/mongo/MongoAdmissionStorage.js +675 -0
  81. package/dist/cjs/src/storage/mongo/MongoAdmissionStorage.js.map +1 -0
  82. package/dist/cjs/src/storage/mongo/MongoOverlayStorage.d.ts +71 -0
  83. package/dist/cjs/src/storage/mongo/MongoOverlayStorage.d.ts.map +1 -0
  84. package/dist/cjs/src/storage/mongo/MongoOverlayStorage.js +453 -0
  85. package/dist/cjs/src/storage/mongo/MongoOverlayStorage.js.map +1 -0
  86. package/dist/cjs/src/storage/mongo/MongoPayloadStore.d.ts +134 -0
  87. package/dist/cjs/src/storage/mongo/MongoPayloadStore.d.ts.map +1 -0
  88. package/dist/cjs/src/storage/mongo/MongoPayloadStore.js +756 -0
  89. package/dist/cjs/src/storage/mongo/MongoPayloadStore.js.map +1 -0
  90. package/dist/cjs/src/storage/mongo/MongoReadGuards.d.ts +44 -0
  91. package/dist/cjs/src/storage/mongo/MongoReadGuards.d.ts.map +1 -0
  92. package/dist/cjs/src/storage/mongo/MongoReadGuards.js +135 -0
  93. package/dist/cjs/src/storage/mongo/MongoReadGuards.js.map +1 -0
  94. package/dist/cjs/src/storage/mongo/MongoSchema.d.ts +67 -0
  95. package/dist/cjs/src/storage/mongo/MongoSchema.d.ts.map +1 -0
  96. package/dist/cjs/src/storage/mongo/MongoSchema.js +743 -0
  97. package/dist/cjs/src/storage/mongo/MongoSchema.js.map +1 -0
  98. package/dist/cjs/src/storage/mongo/MongoTransactionRunner.d.ts +69 -0
  99. package/dist/cjs/src/storage/mongo/MongoTransactionRunner.d.ts.map +1 -0
  100. package/dist/cjs/src/storage/mongo/MongoTransactionRunner.js +368 -0
  101. package/dist/cjs/src/storage/mongo/MongoTransactionRunner.js.map +1 -0
  102. package/dist/cjs/src/storage/mongo.d.ts +9 -0
  103. package/dist/cjs/src/storage/mongo.d.ts.map +1 -0
  104. package/dist/cjs/src/storage/mongo.js +25 -0
  105. package/dist/cjs/src/storage/mongo.js.map +1 -0
  106. package/dist/esm/mod.js +3 -0
  107. package/dist/esm/mod.js.map +1 -1
  108. package/dist/esm/src/BASM.js +21 -8
  109. package/dist/esm/src/BASM.js.map +1 -1
  110. package/dist/esm/src/BASMRemote.js +176 -12
  111. package/dist/esm/src/BASMRemote.js.map +1 -1
  112. package/dist/esm/src/BASMValidation.js +95 -0
  113. package/dist/esm/src/BASMValidation.js.map +1 -0
  114. package/dist/esm/src/DiscoveryAdvertisementValidation.js +57 -0
  115. package/dist/esm/src/DiscoveryAdvertisementValidation.js.map +1 -0
  116. package/dist/esm/src/Engine.js +1720 -326
  117. package/dist/esm/src/Engine.js.map +1 -1
  118. package/dist/esm/src/EngineAdmission.js +280 -0
  119. package/dist/esm/src/EngineAdmission.js.map +1 -0
  120. package/dist/esm/src/GASP/OverlayGASPRemote.js +27 -43
  121. package/dist/esm/src/GASP/OverlayGASPRemote.js.map +1 -1
  122. package/dist/esm/src/GASP/OverlayGASPStorage.js +200 -56
  123. package/dist/esm/src/GASP/OverlayGASPStorage.js.map +1 -1
  124. package/dist/esm/src/RemoteSecurity.js +279 -0
  125. package/dist/esm/src/RemoteSecurity.js.map +1 -0
  126. package/dist/esm/src/storage/AdmissionStorage.js +85 -0
  127. package/dist/esm/src/storage/AdmissionStorage.js.map +1 -0
  128. package/dist/esm/src/storage/RecoveryContract.js +31 -0
  129. package/dist/esm/src/storage/RecoveryContract.js.map +1 -0
  130. package/dist/esm/src/storage/Storage.js +4 -1
  131. package/dist/esm/src/storage/Storage.js.map +1 -1
  132. package/dist/esm/src/storage/knex/KnexStorage.js +98 -61
  133. package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -1
  134. package/dist/esm/src/storage/knex/all-migrations.js +5 -1
  135. package/dist/esm/src/storage/knex/all-migrations.js.map +1 -1
  136. package/dist/esm/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.js +32 -0
  137. package/dist/esm/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.js.map +1 -0
  138. package/dist/esm/src/storage/knex/migrations/2026-09-20-001-spent-by.js +12 -0
  139. package/dist/esm/src/storage/knex/migrations/2026-09-20-001-spent-by.js.map +1 -0
  140. package/dist/esm/src/storage/mongo/MongoAdmissionPlan.js +217 -0
  141. package/dist/esm/src/storage/mongo/MongoAdmissionPlan.js.map +1 -0
  142. package/dist/esm/src/storage/mongo/MongoAdmissionStorage.js +673 -0
  143. package/dist/esm/src/storage/mongo/MongoAdmissionStorage.js.map +1 -0
  144. package/dist/esm/src/storage/mongo/MongoOverlayStorage.js +451 -0
  145. package/dist/esm/src/storage/mongo/MongoOverlayStorage.js.map +1 -0
  146. package/dist/esm/src/storage/mongo/MongoPayloadStore.js +747 -0
  147. package/dist/esm/src/storage/mongo/MongoPayloadStore.js.map +1 -0
  148. package/dist/esm/src/storage/mongo/MongoReadGuards.js +129 -0
  149. package/dist/esm/src/storage/mongo/MongoReadGuards.js.map +1 -0
  150. package/dist/esm/src/storage/mongo/MongoSchema.js +730 -0
  151. package/dist/esm/src/storage/mongo/MongoSchema.js.map +1 -0
  152. package/dist/esm/src/storage/mongo/MongoTransactionRunner.js +371 -0
  153. package/dist/esm/src/storage/mongo/MongoTransactionRunner.js.map +1 -0
  154. package/dist/esm/src/storage/mongo.js +9 -0
  155. package/dist/esm/src/storage/mongo.js.map +1 -0
  156. package/dist/types/mod.d.ts +4 -1
  157. package/dist/types/mod.d.ts.map +1 -1
  158. package/dist/types/src/BASM.d.ts +6 -0
  159. package/dist/types/src/BASM.d.ts.map +1 -1
  160. package/dist/types/src/BASMRemote.d.ts +8 -1
  161. package/dist/types/src/BASMRemote.d.ts.map +1 -1
  162. package/dist/types/src/BASMValidation.d.ts +27 -0
  163. package/dist/types/src/BASMValidation.d.ts.map +1 -0
  164. package/dist/types/src/DiscoveryAdvertisementValidation.d.ts +11 -0
  165. package/dist/types/src/DiscoveryAdvertisementValidation.d.ts.map +1 -0
  166. package/dist/types/src/Engine.d.ts +38 -13
  167. package/dist/types/src/Engine.d.ts.map +1 -1
  168. package/dist/types/src/EngineAdmission.d.ts +70 -0
  169. package/dist/types/src/EngineAdmission.d.ts.map +1 -0
  170. package/dist/types/src/GASP/OverlayGASPRemote.d.ts +4 -3
  171. package/dist/types/src/GASP/OverlayGASPRemote.d.ts.map +1 -1
  172. package/dist/types/src/GASP/OverlayGASPStorage.d.ts +22 -16
  173. package/dist/types/src/GASP/OverlayGASPStorage.d.ts.map +1 -1
  174. package/dist/types/src/RemoteSecurity.d.ts +50 -0
  175. package/dist/types/src/RemoteSecurity.d.ts.map +1 -0
  176. package/dist/types/src/TopicManager.d.ts +13 -3
  177. package/dist/types/src/TopicManager.d.ts.map +1 -1
  178. package/dist/types/src/storage/AdmissionStorage.d.ts +185 -0
  179. package/dist/types/src/storage/AdmissionStorage.d.ts.map +1 -0
  180. package/dist/types/src/storage/RecoveryContract.d.ts +50 -0
  181. package/dist/types/src/storage/RecoveryContract.d.ts.map +1 -0
  182. package/dist/types/src/storage/Storage.d.ts +32 -19
  183. package/dist/types/src/storage/Storage.d.ts.map +1 -1
  184. package/dist/types/src/storage/knex/KnexStorage.d.ts +8 -8
  185. package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -1
  186. package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -1
  187. package/dist/types/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.d.ts +4 -0
  188. package/dist/types/src/storage/knex/migrations/2026-09-17-001-topical-uniqueness.d.ts.map +1 -0
  189. package/dist/types/src/storage/knex/migrations/2026-09-20-001-spent-by.d.ts +5 -0
  190. package/dist/types/src/storage/knex/migrations/2026-09-20-001-spent-by.d.ts.map +1 -0
  191. package/dist/types/src/storage/mongo/MongoAdmissionPlan.d.ts +18 -0
  192. package/dist/types/src/storage/mongo/MongoAdmissionPlan.d.ts.map +1 -0
  193. package/dist/types/src/storage/mongo/MongoAdmissionStorage.d.ts +112 -0
  194. package/dist/types/src/storage/mongo/MongoAdmissionStorage.d.ts.map +1 -0
  195. package/dist/types/src/storage/mongo/MongoOverlayStorage.d.ts +71 -0
  196. package/dist/types/src/storage/mongo/MongoOverlayStorage.d.ts.map +1 -0
  197. package/dist/types/src/storage/mongo/MongoPayloadStore.d.ts +134 -0
  198. package/dist/types/src/storage/mongo/MongoPayloadStore.d.ts.map +1 -0
  199. package/dist/types/src/storage/mongo/MongoReadGuards.d.ts +44 -0
  200. package/dist/types/src/storage/mongo/MongoReadGuards.d.ts.map +1 -0
  201. package/dist/types/src/storage/mongo/MongoSchema.d.ts +67 -0
  202. package/dist/types/src/storage/mongo/MongoSchema.d.ts.map +1 -0
  203. package/dist/types/src/storage/mongo/MongoTransactionRunner.d.ts +69 -0
  204. package/dist/types/src/storage/mongo/MongoTransactionRunner.d.ts.map +1 -0
  205. package/dist/types/src/storage/mongo.d.ts +9 -0
  206. package/dist/types/src/storage/mongo.d.ts.map +1 -0
  207. package/package.json +14 -6
@@ -0,0 +1,675 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoAdmissionStorage = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const promises_1 = require("node:timers/promises");
6
+ const AdmissionStorage_js_1 = require("../AdmissionStorage.js");
7
+ const MongoAdmissionPlan_js_1 = require("./MongoAdmissionPlan.js");
8
+ const MongoPayloadStore_js_1 = require("./MongoPayloadStore.js");
9
+ const MongoReadGuards_js_1 = require("./MongoReadGuards.js");
10
+ const MongoSchema_js_1 = require("./MongoSchema.js");
11
+ const MongoTransactionRunner_js_1 = require("./MongoTransactionRunner.js");
12
+ function isMongoWriteConflict(error) {
13
+ if (typeof error !== 'object' || error === null)
14
+ return false;
15
+ const code = 'code' in error ? error.code : undefined;
16
+ if (code === 112 || code === '112')
17
+ return true;
18
+ if ('codeName' in error && error.codeName === 'WriteConflict')
19
+ return true;
20
+ const text = [
21
+ error instanceof Error ? error.message : '',
22
+ 'errmsg' in error ? String(error.errmsg) : ''
23
+ ].join(' ');
24
+ return text.includes('Write conflict');
25
+ }
26
+ const majority = { w: 'majority', j: true };
27
+ const schemaVersion = 1;
28
+ const duplicateKey = (error) => typeof error === 'object' && error !== null && 'code' in error && error.code === 11000;
29
+ const isPayloadKind = (value) => value === 'raw-transaction' ||
30
+ value === 'merkle-path' ||
31
+ value === 'beef-manifest' ||
32
+ value === 'locking-script' ||
33
+ value === 'outbox-data';
34
+ /**
35
+ * Opt-in Mongo AdmissionStorage. Engine submit uses this only when
36
+ * getAdmissionStorage(storage) observes overlay-admission-v1.
37
+ */
38
+ class MongoAdmissionStorage {
39
+ constructor(db, scope, options = {}) {
40
+ var _a, _b, _c, _d;
41
+ this.db = db;
42
+ this.protocol = 'overlay-admission-v1';
43
+ this.peers = new Map();
44
+ this.scope = { ...scope };
45
+ this.runner = (_a = options.runner) !== null && _a !== void 0 ? _a : new MongoTransactionRunner_js_1.MongoTransactionRunner(db, this.scope);
46
+ this.payloads = (_b = options.payloads) !== null && _b !== void 0 ? _b : new MongoPayloadStore_js_1.MongoPayloadStore(db, this.scope);
47
+ this.guards = (_c = options.readGuards) !== null && _c !== void 0 ? _c : new MongoReadGuards_js_1.MongoReadGuards(db);
48
+ this.enlisted = [...((_d = options.enlistedIndexes) !== null && _d !== void 0 ? _d : [])];
49
+ this.projector = options.projector;
50
+ if (this.enlisted.some(index => index.protocol !== 'overlay-mongo-index-v1' || index.target.length === 0)) {
51
+ throw new Error('Invalid enlisted Mongo lookup index');
52
+ }
53
+ if (new Set(this.enlisted.map(index => index.target)).size !== this.enlisted.length) {
54
+ throw new Error('Duplicate enlisted Mongo lookup index target');
55
+ }
56
+ }
57
+ enlistedTargets() {
58
+ return this.enlisted.map(index => index.target);
59
+ }
60
+ async commitAdmission(plan) {
61
+ if (!(0, MongoAdmissionPlan_js_1.sameScope)(plan.key.scope, this.scope) || !(0, MongoAdmissionPlan_js_1.sameScope)(plan.identity.scope, this.scope)) {
62
+ return await this.peerFor(plan.key.scope).commitAdmission(plan);
63
+ }
64
+ let semanticDigest;
65
+ try {
66
+ semanticDigest = (0, AdmissionStorage_js_1.admissionSemanticDigest)(plan.identity);
67
+ }
68
+ catch {
69
+ return { state: 'rejected', code: 'digest-mismatch' };
70
+ }
71
+ if (plan.key.semanticDigest !== semanticDigest ||
72
+ !(0, MongoAdmissionPlan_js_1.sameScope)(plan.key.scope, plan.identity.scope)) {
73
+ return { state: 'rejected', code: 'digest-mismatch' };
74
+ }
75
+ if (this.projector !== undefined && !(0, AdmissionStorage_js_1.isReplaySafeProjection)(this.projector)) {
76
+ return { state: 'rejected', code: 'unsupported-projection' };
77
+ }
78
+ const existing = await this.runner.reconcile(plan.key);
79
+ if (existing.state === 'committed' || existing.state === 'rejected')
80
+ return existing;
81
+ if (existing.state === 'pending' && existing.attemptId !== 'unlocated') {
82
+ const waited = await this.waitForPending(plan.key, existing.attemptId);
83
+ if (waited.state === 'committed' || waited.state === 'rejected')
84
+ return waited;
85
+ }
86
+ const rejected = (0, MongoAdmissionPlan_js_1.validateAdmissionPlan)(plan);
87
+ if (rejected !== undefined)
88
+ return { state: 'rejected', code: rejected };
89
+ let receipt;
90
+ try {
91
+ receipt = (0, MongoAdmissionPlan_js_1.admissionReceiptFor)(plan, this.enlistedTargets());
92
+ }
93
+ catch (error) {
94
+ return this.asResult(error);
95
+ }
96
+ await this.prepareReadGuards(plan);
97
+ await this.publishHistoryUpdatePayloads(plan);
98
+ return await this.runAdmissionWithWriteConflictRetry(plan, receipt);
99
+ }
100
+ async runAdmissionWithWriteConflictRetry(plan, receipt) {
101
+ for (let attempt = 0; attempt < 8; attempt += 1) {
102
+ try {
103
+ const result = await this.runner.run({ key: plan.key, identity: plan.identity, receipt }, async (context) => {
104
+ await this.applyPlan(context, plan);
105
+ });
106
+ if (result.state !== 'pending')
107
+ return result;
108
+ return await this.waitForPending(plan.key, result.attemptId);
109
+ }
110
+ catch (error) {
111
+ if (isMongoWriteConflict(error) && attempt < 7)
112
+ continue;
113
+ return this.asResult(error);
114
+ }
115
+ }
116
+ return { state: 'rejected', code: 'spend-conflict' };
117
+ }
118
+ async waitForPending(key, attemptId) {
119
+ let current = { state: 'pending', attemptId };
120
+ for (let index = 0; index < 50 && current.state === 'pending'; index += 1) {
121
+ await (0, promises_1.setTimeout)(20);
122
+ const reconciled = await this.runner.reconcile(key, current.state === 'pending' ? current.attemptId : attemptId);
123
+ if (reconciled.state === 'committed' || reconciled.state === 'rejected')
124
+ return reconciled;
125
+ if (reconciled.state === 'aborted') {
126
+ return { state: 'pending', attemptId };
127
+ }
128
+ current = reconciled;
129
+ }
130
+ return current;
131
+ }
132
+ async reconcileAdmission(key, attemptId, options = {}) {
133
+ if (!(0, MongoAdmissionPlan_js_1.sameScope)(key.scope, this.scope))
134
+ return await this.peerFor(key.scope).reconcileAdmission(key, attemptId, options);
135
+ return await this.runner.reconcile(key, attemptId, options);
136
+ }
137
+ async close() {
138
+ await Promise.all([
139
+ this.runner.close(),
140
+ ...[...this.peers.values()].map(async (peer) => await peer.close())
141
+ ]);
142
+ }
143
+ peerFor(scope) {
144
+ const id = (0, MongoSchema_js_1.mongoNodeKey)(scope);
145
+ const existing = this.peers.get(id);
146
+ if (existing !== undefined)
147
+ return existing;
148
+ const peer = new MongoAdmissionStorage(this.db, scope, {
149
+ enlistedIndexes: this.enlisted,
150
+ projector: this.projector
151
+ });
152
+ this.peers.set(id, peer);
153
+ return peer;
154
+ }
155
+ async claimOutbox(kind, leaseMS = 15000) {
156
+ if (!Number.isSafeInteger(leaseMS) || leaseMS < 1 || leaseMS > 60000) {
157
+ throw new Error('Invalid Mongo outbox lease');
158
+ }
159
+ const claimed = await this.outbox(kind).findOneAndUpdate({
160
+ network: this.scope.network,
161
+ genesisHash: this.scope.genesisHash,
162
+ nodeId: this.scope.nodeId,
163
+ $or: [{ state: 'pending' }, { state: 'leased', $expr: { $lte: ['$leaseUntil', '$$NOW'] } }]
164
+ }, [
165
+ {
166
+ $set: {
167
+ state: 'leased',
168
+ leaseUntil: { $dateAdd: { startDate: '$$NOW', unit: 'millisecond', amount: leaseMS } },
169
+ nextAttemptAt: {
170
+ $dateAdd: { startDate: '$$NOW', unit: 'millisecond', amount: leaseMS }
171
+ },
172
+ updatedAt: '$$NOW'
173
+ }
174
+ }
175
+ ], { returnDocument: 'after', writeConcern: majority });
176
+ if (claimed === null)
177
+ return null;
178
+ return {
179
+ eventId: claimed.eventId,
180
+ kind,
181
+ target: claimed.target,
182
+ payloads: await this.outboxPayloads(kind, claimed.eventId)
183
+ };
184
+ }
185
+ async acknowledgeOutbox(kind, eventId) {
186
+ const result = await this.outbox(kind).updateOne({
187
+ _id: this.outboxId(kind, eventId),
188
+ eventId,
189
+ state: { $in: ['leased', 'delivered'] }
190
+ }, { $set: { state: 'delivered', updatedAt: new Date() } }, { writeConcern: majority });
191
+ if (result.matchedCount !== 1)
192
+ throw new Error('Mongo outbox event is not leased');
193
+ }
194
+ asResult(error) {
195
+ if (error instanceof MongoAdmissionPlan_js_1.AdmissionRejectedError)
196
+ return { state: 'rejected', code: error.code };
197
+ if (error instanceof MongoReadGuards_js_1.MongoReadGuardConflictError)
198
+ return { state: 'rejected', code: 'read-conflict' };
199
+ if (error instanceof Error && error.message === 'Mongo payload is not ready for reference') {
200
+ return { state: 'rejected', code: 'payload-not-ready' };
201
+ }
202
+ throw error;
203
+ }
204
+ async prepareReadGuards(plan) {
205
+ for (const decision of plan.decisions) {
206
+ for (const read of decision.reads)
207
+ await this.guards.initialize(this.scope, read.key);
208
+ }
209
+ }
210
+ async publishHistoryUpdatePayloads(plan) {
211
+ for (const decision of plan.decisions) {
212
+ if (decision.historyUpdate === undefined)
213
+ continue;
214
+ const bytes = Buffer.from(JSON.stringify(this.historyUpdateRecord(decision)), 'utf8');
215
+ const digest = (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
216
+ await this.payloads.publish({
217
+ kind: 'outbox-data',
218
+ digest,
219
+ byteLength: String(bytes.byteLength),
220
+ bytes: (async function* () {
221
+ yield bytes;
222
+ })()
223
+ });
224
+ }
225
+ }
226
+ historyUpdateRecord(decision) {
227
+ if (decision.historyUpdate === undefined)
228
+ return { affectedFromHeight: '0' };
229
+ return {
230
+ affectedFromHeight: decision.historyUpdate.affectedFromHeight,
231
+ ...(decision.historyUpdate.handoff === undefined
232
+ ? {}
233
+ : { checkpoint: decision.historyUpdate.handoff.checkpoint })
234
+ };
235
+ }
236
+ async applyPlan(context, plan) {
237
+ var _a;
238
+ var _b;
239
+ await this.assertReadyPayloads(context, plan);
240
+ for (const decision of plan.decisions) {
241
+ await this.checkReads(context, decision);
242
+ await this.checkHistory(context, decision);
243
+ await this.assertAppliedAvailable(context, plan, decision);
244
+ }
245
+ for (const intent of plan.outbox)
246
+ await this.assertOutboxAvailable(context, intent);
247
+ for (const decision of plan.decisions) {
248
+ for (const spend of decision.spends)
249
+ await this.applySpend(context, decision.topic, spend);
250
+ for (const eviction of decision.evictions)
251
+ await this.applyEviction(context, decision.topic, eviction);
252
+ for (const output of decision.outputs)
253
+ await this.insertOutput(context, decision, output);
254
+ for (const edge of decision.edges)
255
+ await this.insertEdge(context, decision.topic, edge);
256
+ await this.insertApplied(context, plan, decision);
257
+ await this.applyHistoryUpdate(context, decision, (_b = (_a = plan.identity.topics.find(item => item.topic === decision.topic)) === null || _a === void 0 ? void 0 : _a.policyId) !== null && _b !== void 0 ? _b : 'default');
258
+ }
259
+ await this.upsertTransaction(context, plan);
260
+ for (const ref of (0, MongoAdmissionPlan_js_1.admissionPlanPayloads)(plan)) {
261
+ await this.pin(context, ref, 'transaction', plan.identity.txid, `${ref.kind}:${ref.digest}`);
262
+ }
263
+ for (const intent of (0, MongoAdmissionPlan_js_1.lookupOutboxIntents)(plan))
264
+ await this.insertOutbox(context, 'lookup', intent);
265
+ for (const intent of (0, MongoAdmissionPlan_js_1.propagationOutboxIntents)(plan)) {
266
+ await this.insertOutbox(context, 'propagation', intent);
267
+ }
268
+ for (const index of this.enlisted)
269
+ await index.apply(context, plan);
270
+ }
271
+ async assertReadyPayloads(context, plan) {
272
+ const seen = new Set();
273
+ for (const ref of (0, MongoAdmissionPlan_js_1.admissionPlanPayloads)(plan)) {
274
+ const id = this.payloadId(ref);
275
+ if (seen.has(id))
276
+ continue;
277
+ seen.add(id);
278
+ const found = await this.db
279
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloads)
280
+ .findOne({ _id: id, state: 'ready', digest: ref.digest, kind: ref.kind }, context.options());
281
+ if (found === null || (0, MongoSchema_js_1.decodeMongoUint64)(String(found.byteLength)) !== ref.byteLength) {
282
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('payload-not-ready');
283
+ }
284
+ }
285
+ }
286
+ async checkReads(context, decision) {
287
+ for (const read of decision.reads) {
288
+ const options = context.options();
289
+ await this.guards.check(options.session, { scope: this.scope, key: read.key, expectedVersion: read.expectedVersion }, { timeoutMS: options.timeoutMS, signal: context.signal });
290
+ }
291
+ }
292
+ async checkHistory(context, decision) {
293
+ const document = await this.generations().findOne({ _id: this.generationId(decision.topic) }, context.options());
294
+ const epoch = document === null ? '0' : (0, MongoSchema_js_1.decodeMongoUint64)(document.chainEpoch);
295
+ const generation = document === null ? '0' : (0, MongoSchema_js_1.decodeMongoUint64)(document.topicHistoryGeneration);
296
+ if (epoch !== decision.expectedHistory.chainEpoch ||
297
+ generation !== decision.expectedHistory.topicHistoryGeneration) {
298
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('read-conflict');
299
+ }
300
+ }
301
+ async assertAppliedAvailable(context, plan, decision) {
302
+ const existing = await this.applied().findOne({ _id: this.appliedId(decision.topic, decision.applied.txid) }, context.options());
303
+ if (existing !== null && existing.admissionId !== plan.key.operationId) {
304
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
305
+ }
306
+ }
307
+ async assertOutboxAvailable(context, intent) {
308
+ const existing = await this.outbox(intent.kind).findOne({ _id: this.outboxId(intent.kind, intent.eventId) }, context.options());
309
+ if (existing !== null)
310
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
311
+ }
312
+ async applySpend(context, topic, spend) {
313
+ const id = this.outputId(topic, spend.outpoint);
314
+ const result = await this.outputs().findOneAndUpdate({
315
+ _id: id,
316
+ version: spend.expectedVersion,
317
+ state: 'unspent'
318
+ }, {
319
+ $set: {
320
+ state: 'spent',
321
+ spender: spend.spender,
322
+ updatedAt: new Date()
323
+ }
324
+ }, { ...context.options(), returnDocument: 'after' });
325
+ if (result === null) {
326
+ const current = await this.outputs().findOne({ _id: id }, context.options());
327
+ if ((current === null || current === void 0 ? void 0 : current.spender) === spend.spender && current.state === 'spent')
328
+ return;
329
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('spend-conflict');
330
+ }
331
+ }
332
+ async applyEviction(context, topic, eviction) {
333
+ const id = this.outputId(topic, eviction);
334
+ const result = await this.outputs().updateOne({ _id: id }, { $set: { state: 'evicted', updatedAt: new Date() } }, context.options());
335
+ if (result.matchedCount !== 1)
336
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
337
+ }
338
+ async insertOutput(context, decision, output) {
339
+ const now = new Date();
340
+ const payloadId = this.payloadId(output.script.payload);
341
+ try {
342
+ await this.outputs().insertOne({
343
+ _id: this.outputId(decision.topic, output),
344
+ schemaVersion,
345
+ network: this.scope.network,
346
+ genesisHash: this.scope.genesisHash,
347
+ nodeId: this.scope.nodeId,
348
+ topic: decision.topic,
349
+ txid: output.txid,
350
+ outputIndex: (0, MongoSchema_js_1.encodeMongoOutputIndex)(output.outputIndex),
351
+ satoshis: (0, MongoSchema_js_1.encodeMongoUint64)(output.satoshis),
352
+ score: (0, MongoSchema_js_1.encodeMongoUint64)(output.score),
353
+ scriptPayloadId: payloadId,
354
+ scriptOffset: (0, MongoSchema_js_1.encodeMongoUint64)(output.script.offset),
355
+ scriptByteLength: (0, MongoSchema_js_1.encodeMongoUint64)(output.script.byteLength),
356
+ state: 'unspent',
357
+ version: '1',
358
+ createdAt: now,
359
+ updatedAt: now
360
+ }, context.options());
361
+ }
362
+ catch (error) {
363
+ if (duplicateKey(error))
364
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
365
+ throw error;
366
+ }
367
+ await this.pin(context, output.script.payload, 'output', this.outputId(decision.topic, output), 'script');
368
+ }
369
+ async insertEdge(context, topic, edge) {
370
+ const now = new Date();
371
+ const id = (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), 'edge', topic, edge.source.txid, (0, MongoSchema_js_1.encodeMongoOutputIndex)(edge.source.outputIndex), edge.consumer.txid, (0, MongoSchema_js_1.encodeMongoOutputIndex)(edge.consumer.outputIndex));
372
+ await this.db.collection(MongoSchema_js_1.MongoCollectionNames.consumptionEdges).updateOne({ _id: id }, {
373
+ $setOnInsert: {
374
+ _id: id,
375
+ schemaVersion,
376
+ network: this.scope.network,
377
+ genesisHash: this.scope.genesisHash,
378
+ nodeId: this.scope.nodeId,
379
+ topic,
380
+ sourceTxid: edge.source.txid,
381
+ sourceOutputIndex: (0, MongoSchema_js_1.encodeMongoOutputIndex)(edge.source.outputIndex),
382
+ consumerTxid: edge.consumer.txid,
383
+ consumerOutputIndex: (0, MongoSchema_js_1.encodeMongoOutputIndex)(edge.consumer.outputIndex),
384
+ createdAt: now
385
+ },
386
+ $set: { updatedAt: now }
387
+ }, { upsert: true, ...context.options() });
388
+ }
389
+ async insertApplied(context, plan, decision) {
390
+ const now = new Date();
391
+ const proven = decision.applied.block !== undefined;
392
+ try {
393
+ await this.applied().insertOne({
394
+ _id: this.appliedId(decision.topic, decision.applied.txid),
395
+ schemaVersion,
396
+ network: this.scope.network,
397
+ genesisHash: this.scope.genesisHash,
398
+ nodeId: this.scope.nodeId,
399
+ topic: decision.topic,
400
+ txid: decision.applied.txid,
401
+ state: proven ? 'active' : 'unproven',
402
+ admissionId: plan.key.operationId,
403
+ ...(decision.applied.firstSeenHeight === undefined
404
+ ? {}
405
+ : { firstSeenHeight: (0, MongoSchema_js_1.encodeMongoUint64)(decision.applied.firstSeenHeight) }),
406
+ ...(decision.applied.proof === undefined
407
+ ? {}
408
+ : { proofPayloadId: this.payloadId(decision.applied.proof) }),
409
+ createdAt: now,
410
+ updatedAt: now
411
+ }, context.options());
412
+ }
413
+ catch (error) {
414
+ if (duplicateKey(error))
415
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
416
+ throw error;
417
+ }
418
+ if (decision.applied.proof !== undefined) {
419
+ await this.pin(context, decision.applied.proof, 'applied-history', this.appliedId(decision.topic, decision.applied.txid), 'proof');
420
+ }
421
+ }
422
+ async applyHistoryUpdate(context, decision, policyId) {
423
+ if (decision.historyUpdate === undefined)
424
+ return;
425
+ const now = new Date();
426
+ const next = decision.historyUpdate.nextTopicHistoryGeneration;
427
+ const updated = await this.generations().findOneAndUpdate({
428
+ _id: this.generationId(decision.topic),
429
+ chainEpoch: (0, MongoSchema_js_1.encodeMongoUint64)(decision.expectedHistory.chainEpoch),
430
+ topicHistoryGeneration: (0, MongoSchema_js_1.encodeMongoUint64)(decision.expectedHistory.topicHistoryGeneration)
431
+ }, {
432
+ $set: {
433
+ topicHistoryGeneration: (0, MongoSchema_js_1.encodeMongoUint64)(next),
434
+ policyId,
435
+ updatedAt: now
436
+ }
437
+ }, { ...context.options(), returnDocument: 'after' });
438
+ if (updated === null) {
439
+ if (decision.expectedHistory.chainEpoch !== '0' ||
440
+ decision.expectedHistory.topicHistoryGeneration !== '0') {
441
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('read-conflict');
442
+ }
443
+ try {
444
+ await this.generations().insertOne({
445
+ _id: this.generationId(decision.topic),
446
+ schemaVersion,
447
+ network: this.scope.network,
448
+ genesisHash: this.scope.genesisHash,
449
+ nodeId: this.scope.nodeId,
450
+ topic: decision.topic,
451
+ chainEpoch: (0, MongoSchema_js_1.encodeMongoUint64)(decision.expectedHistory.chainEpoch),
452
+ topicHistoryGeneration: (0, MongoSchema_js_1.encodeMongoUint64)(next),
453
+ policyId,
454
+ createdAt: now,
455
+ updatedAt: now
456
+ }, context.options());
457
+ }
458
+ catch (error) {
459
+ if (duplicateKey(error))
460
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('read-conflict');
461
+ throw error;
462
+ }
463
+ }
464
+ if (decision.historyUpdate.handoff !== undefined) {
465
+ await this.applyHandoff(context, decision, decision.historyUpdate.handoff.expected, next);
466
+ }
467
+ const bytes = Buffer.from(JSON.stringify(this.historyUpdateRecord(decision)), 'utf8');
468
+ const digest = (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
469
+ const ref = {
470
+ kind: 'outbox-data',
471
+ digest,
472
+ byteLength: (0, AdmissionStorage_js_1.asStorageUint64)(String(bytes.byteLength))
473
+ };
474
+ const payload = await this.db
475
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloads)
476
+ .findOne({ _id: this.payloadId(ref), state: 'ready' }, context.options());
477
+ if (payload === null)
478
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('payload-not-ready');
479
+ await this.replaceHistoryPin(context, decision.topic, decision.expectedHistory.topicHistoryGeneration, next, ref);
480
+ }
481
+ historyUpdateSlot(generation) {
482
+ return `history-update:${generation}`;
483
+ }
484
+ async replaceHistoryPin(context, topic, previousGeneration, nextGeneration, ref) {
485
+ const previousSlot = this.historyUpdateSlot(previousGeneration);
486
+ const previous = await this.db
487
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloadReferences)
488
+ .findOne({
489
+ network: this.scope.network,
490
+ genesisHash: this.scope.genesisHash,
491
+ nodeId: this.scope.nodeId,
492
+ ownerKind: 'basm-job',
493
+ ownerId: topic,
494
+ slot: previousSlot
495
+ }, context.options());
496
+ if (previous !== null) {
497
+ const previousPayload = await this.db
498
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloads)
499
+ .findOne({ _id: String(previous.payloadId) }, context.options());
500
+ if (previousPayload !== null &&
501
+ isPayloadKind(String(previousPayload.kind)) &&
502
+ typeof previousPayload.digest === 'string') {
503
+ const options = context.options();
504
+ await this.payloads.releaseReference(options.session, {
505
+ scope: this.scope,
506
+ payload: {
507
+ kind: previousPayload.kind,
508
+ digest: previousPayload.digest
509
+ },
510
+ ownerKind: 'basm-job',
511
+ ownerId: topic,
512
+ slot: previousSlot
513
+ }, { timeoutMS: options.timeoutMS, signal: context.signal });
514
+ }
515
+ }
516
+ await this.pin(context, ref, 'basm-job', topic, this.historyUpdateSlot(nextGeneration));
517
+ }
518
+ async applyHandoff(context, decision, expected, nextGeneration) {
519
+ var _a, _b;
520
+ var _c;
521
+ if (!(0, MongoAdmissionPlan_js_1.sameScope)(expected.scope, this.scope) ||
522
+ expected.topic !== decision.topic ||
523
+ expected.chainEpoch !== decision.expectedHistory.chainEpoch ||
524
+ expected.topicHistoryGeneration !== decision.expectedHistory.topicHistoryGeneration) {
525
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('read-conflict');
526
+ }
527
+ const now = new Date();
528
+ const result = await this.jobs().findOneAndUpdate({
529
+ _id: this.jobId(expected),
530
+ topic: expected.topic,
531
+ peerId: expected.peerId,
532
+ jobId: expected.jobId,
533
+ chainEpoch: (0, MongoSchema_js_1.encodeMongoUint64)(expected.chainEpoch),
534
+ topicHistoryGeneration: (0, MongoSchema_js_1.encodeMongoUint64)(expected.topicHistoryGeneration),
535
+ leaseToken: (0, MongoSchema_js_1.encodeMongoUint64)(expected.leaseToken),
536
+ $expr: { $gt: ['$leaseUntil', '$$NOW'] }
537
+ }, {
538
+ $set: {
539
+ topicHistoryGeneration: (0, MongoSchema_js_1.encodeMongoUint64)(nextGeneration),
540
+ checkpoint: (_c = (_b = (_a = decision.historyUpdate) === null || _a === void 0 ? void 0 : _a.handoff) === null || _b === void 0 ? void 0 : _b.checkpoint) !== null && _c !== void 0 ? _c : expected.jobId,
541
+ updatedAt: now
542
+ }
543
+ }, { ...context.options(), returnDocument: 'after' });
544
+ if (result === null)
545
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('read-conflict');
546
+ }
547
+ async upsertTransaction(context, plan) {
548
+ const raw = plan.payloads.find(ref => ref.kind === 'raw-transaction');
549
+ const manifest = plan.payloads.find(ref => ref.kind === 'beef-manifest');
550
+ const now = new Date();
551
+ const id = (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoChainKey)(this.scope), 'transaction', plan.identity.txid);
552
+ await this.db.collection(MongoSchema_js_1.MongoCollectionNames.transactions).updateOne({ _id: id }, {
553
+ $setOnInsert: {
554
+ _id: id,
555
+ schemaVersion,
556
+ network: this.scope.network,
557
+ genesisHash: this.scope.genesisHash,
558
+ txid: plan.identity.txid,
559
+ ...(raw === undefined ? {} : { rawPayloadId: this.payloadId(raw) }),
560
+ ...(manifest === undefined ? {} : { manifestPayloadId: this.payloadId(manifest) }),
561
+ createdAt: now
562
+ },
563
+ $set: { updatedAt: now }
564
+ }, { upsert: true, ...context.options() });
565
+ }
566
+ async insertOutbox(context, kind, intent) {
567
+ const now = new Date();
568
+ try {
569
+ await this.outbox(kind).insertOne({
570
+ _id: this.outboxId(kind, intent.eventId),
571
+ schemaVersion,
572
+ network: this.scope.network,
573
+ genesisHash: this.scope.genesisHash,
574
+ nodeId: this.scope.nodeId,
575
+ eventId: intent.eventId,
576
+ target: intent.target,
577
+ state: 'pending',
578
+ nextAttemptAt: now,
579
+ leaseUntil: new Date(0),
580
+ createdAt: now,
581
+ updatedAt: now
582
+ }, context.options());
583
+ }
584
+ catch (error) {
585
+ if (duplicateKey(error))
586
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
587
+ throw error;
588
+ }
589
+ for (const [index, payload] of intent.payloads.entries()) {
590
+ await this.pin(context, payload, `${kind}-outbox`, intent.eventId, String(index));
591
+ }
592
+ }
593
+ async pin(context, ref, ownerKind, ownerId, slot) {
594
+ if (!isPayloadKind(ref.kind))
595
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('invalid-plan');
596
+ const options = context.options();
597
+ try {
598
+ await this.payloads.addReference(options.session, {
599
+ scope: this.scope,
600
+ payload: { kind: ref.kind, digest: ref.digest },
601
+ ownerKind,
602
+ ownerId,
603
+ slot
604
+ }, { timeoutMS: options.timeoutMS, signal: context.signal });
605
+ }
606
+ catch (error) {
607
+ if (error instanceof Error && error.message === 'Mongo payload is not ready for reference') {
608
+ (0, MongoAdmissionPlan_js_1.rejectAdmission)('payload-not-ready');
609
+ }
610
+ throw error;
611
+ }
612
+ }
613
+ async outboxPayloads(kind, eventId) {
614
+ const refs = await this.db
615
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloadReferences)
616
+ .find({
617
+ network: this.scope.network,
618
+ genesisHash: this.scope.genesisHash,
619
+ nodeId: this.scope.nodeId,
620
+ ownerKind: `${kind}-outbox`,
621
+ ownerId: eventId
622
+ })
623
+ .sort({ slot: 1 })
624
+ .toArray();
625
+ const result = [];
626
+ for (const reference of refs) {
627
+ const payload = await this.db
628
+ .collection(MongoSchema_js_1.MongoCollectionNames.payloads)
629
+ .findOne({ _id: String(reference.payloadId) });
630
+ if (payload === null || !isPayloadKind(payload.kind))
631
+ continue;
632
+ result.push({
633
+ kind: payload.kind,
634
+ digest: payload.digest,
635
+ byteLength: (0, MongoSchema_js_1.decodeMongoUint64)(payload.byteLength)
636
+ });
637
+ }
638
+ return result;
639
+ }
640
+ payloadId(ref) {
641
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoChainKey)(this.scope), ref.kind, ref.digest);
642
+ }
643
+ outputId(topic, outpoint) {
644
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), 'output', topic, outpoint.txid, (0, MongoSchema_js_1.encodeMongoOutputIndex)(outpoint.outputIndex));
645
+ }
646
+ appliedId(topic, txid) {
647
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), 'applied', topic, txid);
648
+ }
649
+ generationId(topic) {
650
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), 'generation', topic);
651
+ }
652
+ jobId(lease) {
653
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), 'job', lease.topic, lease.peerId, lease.jobId);
654
+ }
655
+ outboxId(kind, eventId) {
656
+ return (0, MongoSchema_js_1.mongoRecordKey)((0, MongoSchema_js_1.mongoNodeKey)(this.scope), `${kind}-outbox`, eventId);
657
+ }
658
+ outputs() {
659
+ return this.db.collection(MongoSchema_js_1.MongoCollectionNames.outputs);
660
+ }
661
+ applied() {
662
+ return this.db.collection(MongoSchema_js_1.MongoCollectionNames.appliedTransactions);
663
+ }
664
+ generations() {
665
+ return this.db.collection(MongoSchema_js_1.MongoCollectionNames.topicGenerations);
666
+ }
667
+ jobs() {
668
+ return this.db.collection(MongoSchema_js_1.MongoCollectionNames.basmRecoveryJobs);
669
+ }
670
+ outbox(kind) {
671
+ return this.db.collection(kind === 'lookup' ? MongoSchema_js_1.MongoCollectionNames.lookupOutbox : MongoSchema_js_1.MongoCollectionNames.propagationOutbox);
672
+ }
673
+ }
674
+ exports.MongoAdmissionStorage = MongoAdmissionStorage;
675
+ //# sourceMappingURL=MongoAdmissionStorage.js.map