@party-stack/ontology 0.20.0 → 0.21.0

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 (355) hide show
  1. package/README.md +31 -0
  2. package/lib/OntologyPullConfig.d.ts +4 -17
  3. package/lib/OntologyPullConfig.d.ts.map +1 -1
  4. package/lib/authentication.d.ts +1068 -0
  5. package/lib/authentication.d.ts.map +1 -0
  6. package/lib/authentication.js +55 -0
  7. package/lib/authentication.js.map +1 -0
  8. package/lib/cli/index.js +19 -45
  9. package/lib/cli/index.js.map +1 -1
  10. package/lib/cli/pull.d.ts.map +1 -1
  11. package/lib/cli/pull.js +16 -29
  12. package/lib/cli/pull.js.map +1 -1
  13. package/lib/client.d.ts +11 -0
  14. package/lib/client.d.ts.map +1 -0
  15. package/lib/client.js +21 -0
  16. package/lib/client.js.map +1 -0
  17. package/lib/examples/blog.d.ts +2 -387
  18. package/lib/examples/blog.js +1 -353
  19. package/lib/examples/blog.live-queries.d.ts +1 -1
  20. package/lib/examples/blog.live-queries.d.ts.map +1 -1
  21. package/lib/examples/blog.live-queries.js +1 -1
  22. package/lib/examples/blog.live-queries.js.map +1 -1
  23. package/lib/examples/generated/collections.d.ts +7 -0
  24. package/lib/examples/generated/collections.d.ts.map +1 -0
  25. package/lib/examples/generated/collections.js +12 -0
  26. package/lib/examples/generated/collections.js.map +1 -0
  27. package/lib/examples/generated/live.d.ts +2 -2
  28. package/lib/examples/generated/live.d.ts.map +1 -1
  29. package/lib/examples/generated/live.js.map +1 -1
  30. package/lib/http.d.ts +13 -0
  31. package/lib/http.d.ts.map +1 -0
  32. package/lib/http.js +29 -0
  33. package/lib/http.js.map +1 -0
  34. package/lib/index.d.ts +19 -25
  35. package/lib/index.js +9 -15
  36. package/lib/json/index.d.ts +1 -16
  37. package/lib/json/index.js +2 -132
  38. package/lib/live/LiveOntology.d.ts +114 -50
  39. package/lib/live/LiveOntology.d.ts.map +1 -1
  40. package/lib/live/LiveOntology.js +23 -103
  41. package/lib/live/LiveOntology.js.map +1 -1
  42. package/lib/live/actions/createLiveOntologyAction.d.ts +15 -16
  43. package/lib/live/actions/createLiveOntologyAction.d.ts.map +1 -1
  44. package/lib/live/actions/createLiveOntologyAction.js +3 -11
  45. package/lib/live/actions/createLiveOntologyAction.js.map +1 -1
  46. package/lib/live/actions/types.d.ts +21 -0
  47. package/lib/live/actions/types.d.ts.map +1 -0
  48. package/lib/live/attachments/createLiveOntologyAttachments.d.ts +29 -19
  49. package/lib/live/attachments/createLiveOntologyAttachments.d.ts.map +1 -1
  50. package/lib/live/attachments/createLiveOntologyAttachments.js +43 -60
  51. package/lib/live/attachments/createLiveOntologyAttachments.js.map +1 -1
  52. package/lib/live/attachments/types.d.ts +3 -3
  53. package/lib/live/index.d.ts +10 -10
  54. package/lib/live/index.js +5 -6
  55. package/lib/live/mutators/createReadTx.d.ts +5 -0
  56. package/lib/live/mutators/createReadTx.d.ts.map +1 -0
  57. package/lib/live/mutators/createReadTx.js +19 -0
  58. package/lib/live/mutators/createReadTx.js.map +1 -0
  59. package/lib/live/mutators/types.d.ts +7 -2
  60. package/lib/live/mutators/types.d.ts.map +1 -1
  61. package/lib/live/objects/types.d.ts +6 -0
  62. package/lib/live/objects/types.d.ts.map +1 -0
  63. package/lib/live/outbox/types.d.ts +24 -15
  64. package/lib/live/outbox/types.d.ts.map +1 -1
  65. package/lib/live/outbox/types.js +1 -11
  66. package/lib/live/pins.d.ts +51 -0
  67. package/lib/live/pins.d.ts.map +1 -0
  68. package/lib/live/pins.js +113 -0
  69. package/lib/live/pins.js.map +1 -0
  70. package/lib/live/storageBackend.d.ts +50 -0
  71. package/lib/live/storageBackend.d.ts.map +1 -0
  72. package/lib/live/storageBackend.js +42 -0
  73. package/lib/live/storageBackend.js.map +1 -0
  74. package/lib/local.d.ts +15 -0
  75. package/lib/local.d.ts.map +1 -0
  76. package/lib/local.js +19 -0
  77. package/lib/local.js.map +1 -0
  78. package/lib/meta/generated/collections.d.ts +7 -0
  79. package/lib/meta/generated/collections.d.ts.map +1 -0
  80. package/lib/meta/generated/collections.js +15 -0
  81. package/lib/meta/generated/collections.js.map +1 -0
  82. package/lib/meta/generated/live.d.ts +3 -3
  83. package/lib/meta/generated/live.d.ts.map +1 -1
  84. package/lib/meta/generated/live.js +2 -2
  85. package/lib/meta/generated/live.js.map +1 -1
  86. package/lib/meta/pull.d.ts +5 -9
  87. package/lib/meta/pull.d.ts.map +1 -1
  88. package/lib/meta/pull.js +5 -43
  89. package/lib/meta/pull.js.map +1 -1
  90. package/lib/query.d.ts +1 -0
  91. package/lib/query.js +2 -0
  92. package/lib/runtime/host.d.ts +35 -0
  93. package/lib/runtime/host.d.ts.map +1 -0
  94. package/lib/runtime/host.js +39 -0
  95. package/lib/runtime/host.js.map +1 -0
  96. package/lib/runtime/index.d.ts +2 -0
  97. package/lib/runtime/index.js +1 -0
  98. package/lib/runtime/live.d.ts +25 -0
  99. package/lib/runtime/live.d.ts.map +1 -0
  100. package/lib/runtime/live.js +31 -0
  101. package/lib/runtime/live.js.map +1 -0
  102. package/lib/runtime/resource.d.ts +24 -0
  103. package/lib/runtime/resource.d.ts.map +1 -0
  104. package/lib/runtime/resource.js +127 -0
  105. package/lib/runtime/resource.js.map +1 -0
  106. package/lib/runtime/transactions.d.ts +27 -0
  107. package/lib/runtime/transactions.d.ts.map +1 -0
  108. package/lib/runtime/transactions.js +188 -0
  109. package/lib/runtime/transactions.js.map +1 -0
  110. package/lib/runtime/view.d.ts +25 -0
  111. package/lib/runtime/view.d.ts.map +1 -0
  112. package/lib/runtime/view.js +256 -0
  113. package/lib/runtime/view.js.map +1 -0
  114. package/lib/tanstack/collections.d.ts +73 -0
  115. package/lib/tanstack/collections.d.ts.map +1 -0
  116. package/lib/tanstack/collections.js +495 -0
  117. package/lib/tanstack/collections.js.map +1 -0
  118. package/lib/tanstack/createLocalCollection.d.ts +14 -0
  119. package/lib/tanstack/createLocalCollection.d.ts.map +1 -0
  120. package/lib/tanstack/createLocalCollection.js +9 -0
  121. package/lib/tanstack/createLocalCollection.js.map +1 -0
  122. package/lib/tanstack/descriptors.d.ts +33 -0
  123. package/lib/tanstack/descriptors.d.ts.map +1 -0
  124. package/lib/tanstack/descriptors.js +38 -0
  125. package/lib/tanstack/descriptors.js.map +1 -0
  126. package/lib/tanstack/diagnostics.d.ts +23 -0
  127. package/lib/tanstack/diagnostics.d.ts.map +1 -0
  128. package/lib/tanstack/diagnostics.js +14 -0
  129. package/lib/tanstack/diagnostics.js.map +1 -0
  130. package/lib/tanstack/index.d.ts +6 -0
  131. package/lib/tanstack/index.js +6 -0
  132. package/lib/tanstack/localCollection.d.ts +14 -0
  133. package/lib/tanstack/localCollection.d.ts.map +1 -0
  134. package/lib/tanstack/localCollection.js +73 -0
  135. package/lib/tanstack/localCollection.js.map +1 -0
  136. package/lib/tanstack/subset.d.ts +28 -0
  137. package/lib/tanstack/subset.d.ts.map +1 -0
  138. package/lib/tanstack/subset.js +290 -0
  139. package/lib/tanstack/subset.js.map +1 -0
  140. package/lib/testing/sqlite.d.ts +40 -0
  141. package/lib/testing/sqlite.d.ts.map +1 -0
  142. package/lib/testing/sqlite.js +409 -0
  143. package/lib/testing/sqlite.js.map +1 -0
  144. package/lib/testing/sqliteBackend.d.ts +68 -0
  145. package/lib/testing/sqliteBackend.d.ts.map +1 -0
  146. package/lib/testing/sqliteBackend.js +34 -0
  147. package/lib/testing/sqliteBackend.js.map +1 -0
  148. package/lib/utils/index.d.ts +1 -8
  149. package/lib/utils/index.js +2 -5
  150. package/lib/utils/values.d.ts +1 -30
  151. package/lib/worker.d.ts +19 -0
  152. package/lib/worker.d.ts.map +1 -0
  153. package/lib/worker.js +46 -0
  154. package/lib/worker.js.map +1 -0
  155. package/package.json +53 -18
  156. package/lib/cli/format.d.ts +0 -4
  157. package/lib/cli/format.d.ts.map +0 -1
  158. package/lib/cli/format.js +0 -19
  159. package/lib/cli/format.js.map +0 -1
  160. package/lib/cli/generate.d.ts +0 -10
  161. package/lib/cli/generate.d.ts.map +0 -1
  162. package/lib/cli/generate.js +0 -108
  163. package/lib/cli/generate.js.map +0 -1
  164. package/lib/examples/blog.d.ts.map +0 -1
  165. package/lib/examples/blog.js.map +0 -1
  166. package/lib/generate/builders.d.ts +0 -12
  167. package/lib/generate/builders.d.ts.map +0 -1
  168. package/lib/generate/builders.js +0 -58
  169. package/lib/generate/builders.js.map +0 -1
  170. package/lib/generate/constants.d.ts +0 -5
  171. package/lib/generate/constants.d.ts.map +0 -1
  172. package/lib/generate/constants.js +0 -28
  173. package/lib/generate/constants.js.map +0 -1
  174. package/lib/generate/index.d.ts +0 -6
  175. package/lib/generate/index.js +0 -6
  176. package/lib/generate/live.d.ts +0 -12
  177. package/lib/generate/live.d.ts.map +0 -1
  178. package/lib/generate/live.js +0 -48
  179. package/lib/generate/live.js.map +0 -1
  180. package/lib/generate/ontology.d.ts +0 -8
  181. package/lib/generate/ontology.d.ts.map +0 -1
  182. package/lib/generate/ontology.js +0 -501
  183. package/lib/generate/ontology.js.map +0 -1
  184. package/lib/generate/types.d.ts +0 -18
  185. package/lib/generate/types.d.ts.map +0 -1
  186. package/lib/generate/types.js +0 -216
  187. package/lib/generate/types.js.map +0 -1
  188. package/lib/generate/utils/buildJsDocs.d.ts +0 -10
  189. package/lib/generate/utils/buildJsDocs.d.ts.map +0 -1
  190. package/lib/generate/utils/buildJsDocs.js +0 -16
  191. package/lib/generate/utils/buildJsDocs.js.map +0 -1
  192. package/lib/infer.d.ts +0 -223
  193. package/lib/infer.d.ts.map +0 -1
  194. package/lib/infer.js +0 -14
  195. package/lib/infer.js.map +0 -1
  196. package/lib/installation/createMetaOntologyConfiguration.d.ts +0 -10
  197. package/lib/installation/createMetaOntologyConfiguration.d.ts.map +0 -1
  198. package/lib/installation/createMetaOntologyConfiguration.js +0 -16
  199. package/lib/installation/createMetaOntologyConfiguration.js.map +0 -1
  200. package/lib/installation/createOntologyBackendInstallation.d.ts +0 -5
  201. package/lib/installation/createOntologyBackendInstallation.d.ts.map +0 -1
  202. package/lib/installation/createOntologyBackendInstallation.js +0 -221
  203. package/lib/installation/createOntologyBackendInstallation.js.map +0 -1
  204. package/lib/installation/index.d.ts +0 -4
  205. package/lib/installation/index.js +0 -3
  206. package/lib/installation/types.d.ts +0 -94
  207. package/lib/installation/types.d.ts.map +0 -1
  208. package/lib/ir/generated/builders.d.ts +0 -380
  209. package/lib/ir/generated/builders.d.ts.map +0 -1
  210. package/lib/ir/generated/builders.js +0 -186
  211. package/lib/ir/generated/builders.js.map +0 -1
  212. package/lib/ir/generated/constants.d.ts +0 -265
  213. package/lib/ir/generated/constants.d.ts.map +0 -1
  214. package/lib/ir/generated/constants.js +0 -165
  215. package/lib/ir/generated/constants.js.map +0 -1
  216. package/lib/ir/generated/types.d.ts +0 -413
  217. package/lib/ir/generated/types.d.ts.map +0 -1
  218. package/lib/ir/index.d.ts +0 -4
  219. package/lib/ir/index.js +0 -3
  220. package/lib/ir/schema.d.ts +0 -2246
  221. package/lib/ir/schema.d.ts.map +0 -1
  222. package/lib/ir/schema.js +0 -1187
  223. package/lib/ir/schema.js.map +0 -1
  224. package/lib/ir/validate.d.ts +0 -8
  225. package/lib/ir/validate.d.ts.map +0 -1
  226. package/lib/ir/validate.js +0 -623
  227. package/lib/ir/validate.js.map +0 -1
  228. package/lib/json/index.d.ts.map +0 -1
  229. package/lib/json/index.js.map +0 -1
  230. package/lib/lenses.d.ts +0 -21
  231. package/lib/lenses.d.ts.map +0 -1
  232. package/lib/lenses.js +0 -110
  233. package/lib/lenses.js.map +0 -1
  234. package/lib/live/OntologyBackendAdapter.d.ts +0 -104
  235. package/lib/live/OntologyBackendAdapter.d.ts.map +0 -1
  236. package/lib/live/OntologyBackendAdapter.js +0 -1
  237. package/lib/live/actions/createLiveOntologyActions.d.ts +0 -28
  238. package/lib/live/actions/createLiveOntologyActions.d.ts.map +0 -1
  239. package/lib/live/actions/createLiveOntologyActions.js +0 -139
  240. package/lib/live/actions/createLiveOntologyActions.js.map +0 -1
  241. package/lib/live/actions/prepareActionParameters.d.ts +0 -19
  242. package/lib/live/actions/prepareActionParameters.d.ts.map +0 -1
  243. package/lib/live/actions/prepareActionParameters.js +0 -213
  244. package/lib/live/actions/prepareActionParameters.js.map +0 -1
  245. package/lib/live/attachments/attachmentSources.d.ts +0 -10
  246. package/lib/live/attachments/attachmentSources.d.ts.map +0 -1
  247. package/lib/live/attachments/attachmentSources.js +0 -64
  248. package/lib/live/attachments/attachmentSources.js.map +0 -1
  249. package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.d.ts +0 -5
  250. package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.d.ts.map +0 -1
  251. package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.js +0 -6
  252. package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.js.map +0 -1
  253. package/lib/live/expression.d.ts +0 -24
  254. package/lib/live/expression.d.ts.map +0 -1
  255. package/lib/live/expression.js +0 -160
  256. package/lib/live/expression.js.map +0 -1
  257. package/lib/live/mutators/OntologyEdits.d.ts +0 -15
  258. package/lib/live/mutators/OntologyEdits.d.ts.map +0 -1
  259. package/lib/live/mutators/OntologyEdits.js +0 -65
  260. package/lib/live/mutators/OntologyEdits.js.map +0 -1
  261. package/lib/live/mutators/createMutatorTx.d.ts +0 -11
  262. package/lib/live/mutators/createMutatorTx.d.ts.map +0 -1
  263. package/lib/live/mutators/createMutatorTx.js +0 -61
  264. package/lib/live/mutators/createMutatorTx.js.map +0 -1
  265. package/lib/live/mutators/runOptimisticAction.d.ts +0 -19
  266. package/lib/live/mutators/runOptimisticAction.d.ts.map +0 -1
  267. package/lib/live/mutators/runOptimisticAction.js +0 -30
  268. package/lib/live/mutators/runOptimisticAction.js.map +0 -1
  269. package/lib/live/objects/OntologyObject.d.ts +0 -4
  270. package/lib/live/objects/OntologyObject.d.ts.map +0 -1
  271. package/lib/live/objects/OntologyObject.js +0 -1
  272. package/lib/live/objects/createLiveOntologyObjectCollection.d.ts +0 -17
  273. package/lib/live/objects/createLiveOntologyObjectCollection.d.ts.map +0 -1
  274. package/lib/live/objects/createLiveOntologyObjectCollection.js +0 -69
  275. package/lib/live/objects/createLiveOntologyObjectCollection.js.map +0 -1
  276. package/lib/live/objects/ontologyObjectCollectionId.d.ts +0 -4
  277. package/lib/live/objects/ontologyObjectCollectionId.d.ts.map +0 -1
  278. package/lib/live/objects/ontologyObjectCollectionId.js +0 -8
  279. package/lib/live/objects/ontologyObjectCollectionId.js.map +0 -1
  280. package/lib/live/outbox/createOntologyOutbox.d.ts +0 -23
  281. package/lib/live/outbox/createOntologyOutbox.d.ts.map +0 -1
  282. package/lib/live/outbox/createOntologyOutbox.js +0 -292
  283. package/lib/live/outbox/createOntologyOutbox.js.map +0 -1
  284. package/lib/live/outbox/leaderExecutor.d.ts +0 -20
  285. package/lib/live/outbox/leaderExecutor.d.ts.map +0 -1
  286. package/lib/live/outbox/leaderExecutor.js +0 -130
  287. package/lib/live/outbox/leaderExecutor.js.map +0 -1
  288. package/lib/live/outbox/outboxService.d.ts +0 -7
  289. package/lib/live/outbox/outboxService.d.ts.map +0 -1
  290. package/lib/live/outbox/outboxService.js +0 -68
  291. package/lib/live/outbox/outboxService.js.map +0 -1
  292. package/lib/live/outbox/projectionManager.d.ts +0 -31
  293. package/lib/live/outbox/projectionManager.d.ts.map +0 -1
  294. package/lib/live/outbox/projectionManager.js +0 -127
  295. package/lib/live/outbox/projectionManager.js.map +0 -1
  296. package/lib/live/outbox/repository.d.ts +0 -31
  297. package/lib/live/outbox/repository.d.ts.map +0 -1
  298. package/lib/live/outbox/repository.js +0 -196
  299. package/lib/live/outbox/repository.js.map +0 -1
  300. package/lib/live/outbox/service.d.ts +0 -61
  301. package/lib/live/outbox/service.d.ts.map +0 -1
  302. package/lib/live/outbox/service.js +0 -6
  303. package/lib/live/outbox/service.js.map +0 -1
  304. package/lib/live/outbox/types.js.map +0 -1
  305. package/lib/live/waitForCollectionReady.d.ts +0 -5
  306. package/lib/live/waitForCollectionReady.d.ts.map +0 -1
  307. package/lib/live/waitForCollectionReady.js +0 -49
  308. package/lib/live/waitForCollectionReady.js.map +0 -1
  309. package/lib/meta/createLocalMetaOntologyBackendAdapter.d.ts +0 -7
  310. package/lib/meta/createLocalMetaOntologyBackendAdapter.d.ts.map +0 -1
  311. package/lib/meta/createLocalMetaOntologyBackendAdapter.js +0 -44
  312. package/lib/meta/createLocalMetaOntologyBackendAdapter.js.map +0 -1
  313. package/lib/meta/generated/constants.d.ts +0 -265
  314. package/lib/meta/generated/constants.d.ts.map +0 -1
  315. package/lib/meta/generated/constants.js +0 -165
  316. package/lib/meta/generated/constants.js.map +0 -1
  317. package/lib/meta/generated/types.d.ts +0 -417
  318. package/lib/meta/generated/types.d.ts.map +0 -1
  319. package/lib/meta/generated/types.js +0 -1
  320. package/lib/meta/ontology.d.ts +0 -26
  321. package/lib/meta/ontology.d.ts.map +0 -1
  322. package/lib/meta/ontology.js +0 -111
  323. package/lib/meta/ontology.js.map +0 -1
  324. package/lib/utils/links.d.ts +0 -50
  325. package/lib/utils/links.d.ts.map +0 -1
  326. package/lib/utils/links.js +0 -13
  327. package/lib/utils/links.js.map +0 -1
  328. package/lib/utils/paths.d.ts +0 -6
  329. package/lib/utils/paths.d.ts.map +0 -1
  330. package/lib/utils/paths.js +0 -42
  331. package/lib/utils/paths.js.map +0 -1
  332. package/lib/utils/provide.d.ts +0 -4
  333. package/lib/utils/provide.d.ts.map +0 -1
  334. package/lib/utils/provide.js +0 -9
  335. package/lib/utils/provide.js.map +0 -1
  336. package/lib/utils/targets.d.ts +0 -37
  337. package/lib/utils/targets.d.ts.map +0 -1
  338. package/lib/utils/targets.js +0 -1
  339. package/lib/utils/typeNames.d.ts +0 -28
  340. package/lib/utils/typeNames.d.ts.map +0 -1
  341. package/lib/utils/typeNames.js +0 -1
  342. package/lib/utils/types.d.ts +0 -12
  343. package/lib/utils/types.d.ts.map +0 -1
  344. package/lib/utils/types.js +0 -48
  345. package/lib/utils/types.js.map +0 -1
  346. package/lib/utils/uncertain.d.ts +0 -11
  347. package/lib/utils/uncertain.d.ts.map +0 -1
  348. package/lib/utils/uncertain.js +0 -14
  349. package/lib/utils/uncertain.js.map +0 -1
  350. package/lib/utils/validation.d.ts +0 -7
  351. package/lib/utils/validation.d.ts.map +0 -1
  352. package/lib/utils/validation.js +0 -1
  353. package/lib/utils/values.d.ts.map +0 -1
  354. /package/lib/{installation → live/actions}/types.js +0 -0
  355. /package/lib/{ir/generated → live/objects}/types.js +0 -0
@@ -1,127 +0,0 @@
1
- import { requestFingerprint } from "./repository.js";
2
- //#region src/live/outbox/projectionManager.ts
3
- function normalizeError(error) {
4
- return error instanceof Error ? error : new Error(String(error));
5
- }
6
- function desiredProjections(entries) {
7
- return [...entries].filter((entry) => entry.status !== "failed" || entry.retryable).sort((left, right) => left.sequence - right.sequence).map((entry) => ({
8
- entry,
9
- fingerprint: requestFingerprint(entry.request)
10
- }));
11
- }
12
- var OutboxProjectionManager = class {
13
- project;
14
- desired = [];
15
- projections = /* @__PURE__ */ new Map();
16
- installedFingerprints = /* @__PURE__ */ new Map();
17
- versions = /* @__PURE__ */ new Map();
18
- tail = Promise.resolve();
19
- closed = false;
20
- disabledError;
21
- constructor(project) {
22
- this.project = project;
23
- }
24
- get error() {
25
- return this.disabledError;
26
- }
27
- restore(entries) {
28
- return this.schedule(() => this.applyDesired(desiredProjections(entries)));
29
- }
30
- reconcile(entries) {
31
- return this.schedule(() => this.applyDesired(desiredProjections(entries)));
32
- }
33
- ensure(entry) {
34
- return this.schedule(() => {
35
- const entries = this.desired.filter((candidate) => candidate.entry.id !== entry.id).map((candidate) => candidate.entry);
36
- entries.push(entry);
37
- return this.applyDesired(desiredProjections(entries));
38
- });
39
- }
40
- discard(id, error) {
41
- return this.schedule(() => this.applyDesired(this.desired.filter((candidate) => candidate.entry.id !== id), (removed) => removed.entry.id === id ? error : /* @__PURE__ */ new Error("Outbox optimistic projection replayed.")));
42
- }
43
- close() {
44
- if (this.closed) return Promise.resolve();
45
- this.closed = true;
46
- const error = /* @__PURE__ */ new Error("Outbox disposed.");
47
- const settlements = this.desired.map((candidate) => this.invalidate(candidate.entry.id, error));
48
- this.desired = [];
49
- return Promise.all(settlements).then(() => void 0);
50
- }
51
- schedule(work) {
52
- if (this.closed) return Promise.resolve();
53
- const scheduled = this.tail.catch(() => void 0).then(async () => {
54
- if (!this.closed) await work();
55
- });
56
- this.tail = scheduled.catch(() => void 0);
57
- return scheduled;
58
- }
59
- async applyDesired(next, removalError = () => /* @__PURE__ */ new Error("Outbox optimistic projection replaced.")) {
60
- if (this.disabledError) return;
61
- const divergence = this.firstDivergence(this.desired, next);
62
- if (divergence === -1) {
63
- for (const candidate of next) if (this.installedFingerprints.get(candidate.entry.id) !== candidate.fingerprint) try {
64
- await this.install(candidate);
65
- } catch (error) {
66
- await this.disable(normalizeError(error));
67
- return;
68
- }
69
- return;
70
- }
71
- for (let index = this.desired.length - 1; index >= divergence; index -= 1) {
72
- const removed = this.desired[index];
73
- await this.invalidate(removed.entry.id, removalError(removed));
74
- }
75
- this.desired = next;
76
- for (let index = divergence; index < next.length; index += 1) {
77
- const candidate = next[index];
78
- try {
79
- await this.install(candidate);
80
- } catch (error) {
81
- await this.disable(normalizeError(error));
82
- return;
83
- }
84
- }
85
- }
86
- async disable(error) {
87
- for (let index = this.desired.length - 1; index >= 0; index -= 1) await this.invalidate(this.desired[index].entry.id, error);
88
- this.desired = [];
89
- this.disabledError = error;
90
- }
91
- firstDivergence(current, next) {
92
- const length = Math.max(current.length, next.length);
93
- for (let index = 0; index < length; index += 1) {
94
- const previous = current[index];
95
- const candidate = next[index];
96
- if (previous?.entry.id !== candidate?.entry.id || previous?.fingerprint !== candidate?.fingerprint) return index;
97
- }
98
- return -1;
99
- }
100
- async install(candidate) {
101
- if (this.installedFingerprints.get(candidate.entry.id) === candidate.fingerprint) return;
102
- await this.invalidate(candidate.entry.id, /* @__PURE__ */ new Error("Outbox optimistic projection replaced."));
103
- const version = this.versions.get(candidate.entry.id) ?? 0;
104
- const projection = await this.project?.(candidate.entry);
105
- if (this.closed || this.versions.get(candidate.entry.id) !== version) {
106
- await this.settle(projection, /* @__PURE__ */ new Error(this.closed ? "Outbox disposed." : "Outbox projection became stale."));
107
- return;
108
- }
109
- if (projection) this.projections.set(candidate.entry.id, projection);
110
- this.installedFingerprints.set(candidate.entry.id, candidate.fingerprint);
111
- }
112
- async invalidate(id, error) {
113
- this.versions.set(id, (this.versions.get(id) ?? 0) + 1);
114
- await this.settle(this.projections.get(id), error);
115
- this.projections.delete(id);
116
- this.installedFingerprints.delete(id);
117
- }
118
- async settle(projection, error) {
119
- try {
120
- await projection?.settle(error);
121
- } catch {}
122
- }
123
- };
124
- //#endregion
125
- export { OutboxProjectionManager };
126
-
127
- //# sourceMappingURL=projectionManager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"projectionManager.js","names":[],"sources":["../../../src/live/outbox/projectionManager.ts"],"sourcesContent":["import { requestFingerprint } from \"./repository.js\";\nimport type { OntologyOutboxEntry } from \"./types.js\";\n\nexport interface OutboxProjection {\n settle(error?: Error): void | Promise<void>;\n}\n\ninterface DesiredProjection {\n entry: OntologyOutboxEntry;\n fingerprint: string;\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction desiredProjections(entries: readonly OntologyOutboxEntry[]): DesiredProjection[] {\n return [...entries]\n .filter((entry) => entry.status !== \"failed\" || entry.retryable)\n .sort((left, right) => left.sequence - right.sequence)\n .map((entry) => ({\n entry,\n fingerprint: requestFingerprint(entry.request),\n }));\n}\n\nexport class OutboxProjectionManager {\n private desired: DesiredProjection[] = [];\n private readonly projections = new Map<string, OutboxProjection>();\n private readonly installedFingerprints = new Map<string, string>();\n private readonly versions = new Map<string, number>();\n private tail = Promise.resolve();\n private closed = false;\n private disabledError: Error | undefined;\n\n constructor(\n private readonly project:\n | ((entry: OntologyOutboxEntry) => Promise<OutboxProjection | undefined>)\n | undefined\n ) {}\n\n get error(): Error | undefined {\n return this.disabledError;\n }\n\n restore(entries: readonly OntologyOutboxEntry[]): Promise<void> {\n return this.schedule(() => this.applyDesired(desiredProjections(entries)));\n }\n\n reconcile(entries: readonly OntologyOutboxEntry[]): Promise<void> {\n return this.schedule(() => this.applyDesired(desiredProjections(entries)));\n }\n\n ensure(entry: OntologyOutboxEntry): Promise<void> {\n return this.schedule(() => {\n const entries = this.desired\n .filter((candidate) => candidate.entry.id !== entry.id)\n .map((candidate) => candidate.entry);\n entries.push(entry);\n return this.applyDesired(desiredProjections(entries));\n });\n }\n\n discard(id: string, error?: Error): Promise<void> {\n return this.schedule(() =>\n this.applyDesired(\n this.desired.filter((candidate) => candidate.entry.id !== id),\n (removed) =>\n removed.entry.id === id ? error : new Error(\"Outbox optimistic projection replayed.\")\n )\n );\n }\n\n close(): Promise<void> {\n if (this.closed) return Promise.resolve();\n this.closed = true;\n const error = new Error(\"Outbox disposed.\");\n const settlements = this.desired.map((candidate) => this.invalidate(candidate.entry.id, error));\n this.desired = [];\n return Promise.all(settlements).then(() => undefined);\n }\n\n private schedule(work: () => Promise<void>): Promise<void> {\n if (this.closed) return Promise.resolve();\n const scheduled = this.tail\n .catch(() => undefined)\n .then(async () => {\n if (!this.closed) await work();\n });\n this.tail = scheduled.catch(() => undefined);\n return scheduled;\n }\n\n private async applyDesired(\n next: DesiredProjection[],\n removalError: (removed: DesiredProjection) => Error | undefined = () =>\n new Error(\"Outbox optimistic projection replaced.\")\n ): Promise<void> {\n if (this.disabledError) return;\n const divergence = this.firstDivergence(this.desired, next);\n if (divergence === -1) {\n for (const candidate of next) {\n if (this.installedFingerprints.get(candidate.entry.id) !== candidate.fingerprint) {\n try {\n await this.install(candidate);\n } catch (error) {\n await this.disable(normalizeError(error));\n return;\n }\n }\n }\n return;\n }\n\n for (let index = this.desired.length - 1; index >= divergence; index -= 1) {\n const removed = this.desired[index]!;\n await this.invalidate(removed.entry.id, removalError(removed));\n }\n this.desired = next;\n\n for (let index = divergence; index < next.length; index += 1) {\n const candidate = next[index]!;\n try {\n await this.install(candidate);\n } catch (error) {\n await this.disable(normalizeError(error));\n return;\n }\n }\n }\n\n private async disable(error: Error): Promise<void> {\n for (let index = this.desired.length - 1; index >= 0; index -= 1) {\n await this.invalidate(this.desired[index]!.entry.id, error);\n }\n this.desired = [];\n this.disabledError = error;\n }\n\n private firstDivergence(\n current: readonly DesiredProjection[],\n next: readonly DesiredProjection[]\n ): number {\n const length = Math.max(current.length, next.length);\n for (let index = 0; index < length; index += 1) {\n const previous = current[index];\n const candidate = next[index];\n if (\n previous?.entry.id !== candidate?.entry.id ||\n previous?.fingerprint !== candidate?.fingerprint\n ) {\n return index;\n }\n }\n return -1;\n }\n\n private async install(candidate: DesiredProjection): Promise<void> {\n if (this.installedFingerprints.get(candidate.entry.id) === candidate.fingerprint) {\n return;\n }\n\n await this.invalidate(candidate.entry.id, new Error(\"Outbox optimistic projection replaced.\"));\n const version = this.versions.get(candidate.entry.id) ?? 0;\n const projection = await this.project?.(candidate.entry);\n if (this.closed || this.versions.get(candidate.entry.id) !== version) {\n await this.settle(\n projection,\n new Error(this.closed ? \"Outbox disposed.\" : \"Outbox projection became stale.\")\n );\n return;\n }\n\n if (projection) {\n this.projections.set(candidate.entry.id, projection);\n }\n this.installedFingerprints.set(candidate.entry.id, candidate.fingerprint);\n }\n\n private async invalidate(id: string, error?: Error): Promise<void> {\n this.versions.set(id, (this.versions.get(id) ?? 0) + 1);\n await this.settle(this.projections.get(id), error);\n this.projections.delete(id);\n this.installedFingerprints.delete(id);\n }\n\n private async settle(projection: OutboxProjection | undefined, error?: Error): Promise<void> {\n try {\n await projection?.settle(error);\n } catch {\n // Projection teardown is isolated from outbox state.\n }\n }\n}\n"],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import { OntologyActionRequest, OntologyOutboxEntry } from "./types.js";
2
- import { OutboxErrorDetails } from "./service.js";
3
- import { Collection } from "@tanstack/db";
4
- //#region src/live/outbox/repository.d.ts
5
- export declare function requestFingerprint(request: OntologyActionRequest): string;
6
- export declare class OntologyOutboxRepository {
7
- readonly collection: Collection<OntologyOutboxEntry, string>;
8
- constructor(collection: Collection<OntologyOutboxEntry, string>);
9
- preload(): Promise<void>;
10
- get(id: string): OntologyOutboxEntry | undefined;
11
- entries(): Promise<OntologyOutboxEntry[]>;
12
- enqueue(proposed: OntologyOutboxEntry): Promise<OntologyOutboxEntry>;
13
- edit(id: string, request: OntologyActionRequest): Promise<OntologyOutboxEntry>;
14
- remove(id: string): Promise<void>;
15
- retry(id: string): Promise<void>;
16
- recover(failureStrategy: "pause" | "discard-all", maxRetries: number): Promise<OntologyOutboxEntry[]>;
17
- claim(): Promise<OntologyOutboxEntry | undefined>;
18
- nextRetryAt(): Promise<number | undefined>;
19
- complete(id: string, executionId: string): Promise<void>;
20
- fail(id: string, executionId: string, retryable: boolean, error: OutboxErrorDetails, retryAt?: number): Promise<OntologyOutboxEntry>;
21
- discardAll(id: string, executionId: string): Promise<OntologyOutboxEntry[]>;
22
- discardFrom(id: string): Promise<OntologyOutboxEntry[]>;
23
- private head;
24
- private nextSequence;
25
- private assertCurrentExecution;
26
- private update;
27
- private delete;
28
- private deleteEntries;
29
- }
30
- //#endregion
31
- //# sourceMappingURL=repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repository.d.ts","names":[],"sources":["../../../src/live/outbox/repository.ts"],"mappings":";;;;wBAKgB,mBAAmB,SAAS;qBAI/B;WACY,YAAY,WAAW;EAA5C,YAAqB,YAAY,WAAW;EAE5C,WAAW;EAIX,IAAI,aAAa;EAIjB,WAAW,QAAQ;EAsBb,QAAQ,UAAU,sBAAsB,QAAQ;EAchD,KAAK,YAAY,SAAS,wBAAwB,QAAQ;EAmB1D,OAAO,aAAa;EAUpB,MAAM,aAAa;EAmBnB,QACF,0CACA,qBACD,QAAQ;EA2CL,SAAS,QAAQ;EAcjB,eAAe;EAKf,SAAS,YAAY,sBAAsB;EAK3C,KACF,YACA,qBACA,oBACA,OAAO,oBACP,mBACD,QAAQ;EAcL,WAAW,YAAY,sBAAsB,QAAQ;EAKrD,YAAY,aAAa,QAAQ;UAQzB;UAuBA;UAaN;UAWM;UAaA;UAOA"}
@@ -1,196 +0,0 @@
1
- import { CoordinationTaskRejectedError } from "@party-stack/runtime";
2
- import { queryOnce } from "@tanstack/db";
3
- //#region src/live/outbox/repository.ts
4
- function requestFingerprint(request) {
5
- return JSON.stringify(request);
6
- }
7
- var OntologyOutboxRepository = class {
8
- collection;
9
- constructor(collection) {
10
- this.collection = collection;
11
- }
12
- preload() {
13
- return this.collection.preload();
14
- }
15
- get(id) {
16
- return this.collection.get(id);
17
- }
18
- entries() {
19
- return queryOnce((query) => query.from({ entry: this.collection }).orderBy(({ entry }) => entry.sequence, "asc").select(({ entry }) => ({
20
- id: entry.id,
21
- sequence: entry.sequence,
22
- request: entry.request,
23
- visibility: entry.visibility,
24
- status: entry.status,
25
- createdAt: entry.createdAt,
26
- updatedAt: entry.updatedAt,
27
- attempts: entry.attempts,
28
- retryable: entry.retryable ?? true,
29
- nextAttemptAt: entry.nextAttemptAt,
30
- executionId: entry.executionId,
31
- lastError: entry.lastError
32
- })));
33
- }
34
- async enqueue(proposed) {
35
- const existing = this.get(proposed.id);
36
- if (existing) return existing;
37
- const entry = {
38
- ...proposed,
39
- sequence: await this.nextSequence()
40
- };
41
- await this.collection.insert(entry, { optimistic: false }).isPersisted.promise;
42
- return entry;
43
- }
44
- async edit(id, request) {
45
- const entry = this.get(id);
46
- if (!entry || !["queued", "failed"].includes(entry.status)) throw new CoordinationTaskRejectedError(`Outbox entry "${id}" cannot be edited.`);
47
- const now = Date.now();
48
- return this.update(id, (draft) => {
49
- draft.request = request;
50
- draft.status = "queued";
51
- draft.retryable = true;
52
- draft.attempts = 0;
53
- draft.executionId = void 0;
54
- draft.nextAttemptAt = now;
55
- draft.updatedAt = now;
56
- draft.lastError = void 0;
57
- });
58
- }
59
- async remove(id) {
60
- const entry = this.get(id);
61
- if (entry && !["queued", "failed"].includes(entry.status)) throw new CoordinationTaskRejectedError(`Outbox entry "${id}" cannot be removed while it is ${entry.status}.`);
62
- await this.delete(id);
63
- }
64
- async retry(id) {
65
- const entry = this.get(id);
66
- if (!entry?.retryable) throw new CoordinationTaskRejectedError(`Outbox entry "${id}" is not retriable.`);
67
- if (entry.status === "executing") throw new CoordinationTaskRejectedError(`Outbox entry "${id}" is already executing.`);
68
- const now = Date.now();
69
- await this.update(id, (draft) => {
70
- draft.status = "queued";
71
- draft.executionId = void 0;
72
- draft.nextAttemptAt = now;
73
- draft.updatedAt = now;
74
- draft.lastError = void 0;
75
- });
76
- }
77
- async recover(failureStrategy, maxRetries) {
78
- const entries = await this.entries();
79
- const head = entries[0];
80
- if (!head) return [];
81
- const interrupted = head.status === "executing" || head.lastError?.name === "InterruptedExecution";
82
- const exhausted = head.status === "failed" && (!head.retryable || head.attempts > maxRetries || head.lastError?.name === "ProjectionRestoreError");
83
- if (failureStrategy === "discard-all" && (interrupted || exhausted)) {
84
- await this.deleteEntries(entries);
85
- return entries;
86
- }
87
- if (head.status === "failed" && head.retryable && head.attempts <= maxRetries) {
88
- const now = Date.now();
89
- await this.update(head.id, (draft) => {
90
- draft.status = "queued";
91
- draft.executionId = void 0;
92
- draft.nextAttemptAt = now;
93
- draft.updatedAt = now;
94
- });
95
- return [];
96
- }
97
- if (head.status === "executing") {
98
- const now = Date.now();
99
- await this.update(head.id, (draft) => {
100
- draft.status = "failed";
101
- draft.retryable = true;
102
- draft.executionId = void 0;
103
- draft.updatedAt = now;
104
- draft.lastError = {
105
- name: "InterruptedExecution",
106
- message: "Execution was interrupted; retry manually."
107
- };
108
- });
109
- }
110
- return [];
111
- }
112
- async claim() {
113
- const entry = await this.head();
114
- if (entry?.status !== "queued" || entry.nextAttemptAt > Date.now()) return;
115
- const executionId = crypto.randomUUID();
116
- return this.update(entry.id, (draft) => {
117
- draft.status = "executing";
118
- draft.executionId = executionId;
119
- draft.updatedAt = Date.now();
120
- });
121
- }
122
- async nextRetryAt() {
123
- const entry = await this.head();
124
- return entry?.status === "queued" ? entry.nextAttemptAt : void 0;
125
- }
126
- async complete(id, executionId) {
127
- this.assertCurrentExecution(id, executionId);
128
- await this.delete(id);
129
- }
130
- async fail(id, executionId, retryable, error, retryAt) {
131
- const entry = this.assertCurrentExecution(id, executionId);
132
- const now = Date.now();
133
- return this.update(id, (draft) => {
134
- draft.status = retryAt === void 0 ? "failed" : "queued";
135
- draft.retryable = retryable;
136
- draft.attempts = entry.attempts + 1;
137
- draft.executionId = void 0;
138
- draft.nextAttemptAt = retryAt ?? now;
139
- draft.updatedAt = now;
140
- draft.lastError = error;
141
- });
142
- }
143
- async discardAll(id, executionId) {
144
- this.assertCurrentExecution(id, executionId);
145
- return this.discardFrom(id);
146
- }
147
- async discardFrom(id) {
148
- const failed = this.get(id);
149
- if (!failed) return [];
150
- const discarded = (await this.entries()).filter((entry) => entry.sequence >= failed.sequence);
151
- await this.deleteEntries(discarded);
152
- return discarded;
153
- }
154
- async head() {
155
- return await queryOnce((query) => query.from({ entry: this.collection }).orderBy(({ entry }) => entry.sequence, "asc").select(({ entry }) => ({
156
- id: entry.id,
157
- sequence: entry.sequence,
158
- request: entry.request,
159
- visibility: entry.visibility,
160
- status: entry.status,
161
- createdAt: entry.createdAt,
162
- updatedAt: entry.updatedAt,
163
- attempts: entry.attempts,
164
- retryable: entry.retryable ?? true,
165
- nextAttemptAt: entry.nextAttemptAt,
166
- executionId: entry.executionId,
167
- lastError: entry.lastError
168
- })).findOne());
169
- }
170
- async nextSequence() {
171
- return ((await queryOnce((query) => query.from({ entry: this.collection }).orderBy(({ entry }) => entry.sequence, "desc").select(({ entry }) => ({ sequence: entry.sequence })).findOne()))?.sequence ?? 0) + 1;
172
- }
173
- assertCurrentExecution(id, executionId) {
174
- const entry = this.get(id);
175
- if (entry?.status !== "executing" || entry.executionId !== executionId) throw new CoordinationTaskRejectedError(`Outbox execution claim for "${id}" is no longer current.`, "STALE_EXECUTION");
176
- return entry;
177
- }
178
- async update(id, update) {
179
- await this.collection.update(id, { optimistic: false }, update).isPersisted.promise;
180
- const entry = this.get(id);
181
- if (!entry) throw new Error(`Outbox entry "${id}" disappeared during an update.`);
182
- return entry;
183
- }
184
- async delete(id) {
185
- if (!this.collection.has(id)) return;
186
- await this.collection.delete(id, { optimistic: false }).isPersisted.promise;
187
- }
188
- async deleteEntries(entries) {
189
- if (entries.length === 0) return;
190
- await this.collection.delete(entries.map((entry) => entry.id), { optimistic: false }).isPersisted.promise;
191
- }
192
- };
193
- //#endregion
194
- export { OntologyOutboxRepository, requestFingerprint };
195
-
196
- //# sourceMappingURL=repository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repository.js","names":[],"sources":["../../../src/live/outbox/repository.ts"],"sourcesContent":["import { CoordinationTaskRejectedError } from \"@party-stack/runtime\";\nimport { queryOnce, type Collection } from \"@tanstack/db\";\nimport type { OutboxErrorDetails } from \"./service.js\";\nimport type { OntologyActionRequest, OntologyOutboxEntry } from \"./types.js\";\n\nexport function requestFingerprint(request: OntologyActionRequest): string {\n return JSON.stringify(request);\n}\n\nexport class OntologyOutboxRepository {\n constructor(readonly collection: Collection<OntologyOutboxEntry, string>) {}\n\n preload(): Promise<void> {\n return this.collection.preload();\n }\n\n get(id: string): OntologyOutboxEntry | undefined {\n return this.collection.get(id);\n }\n\n entries(): Promise<OntologyOutboxEntry[]> {\n return queryOnce((query) =>\n query\n .from({ entry: this.collection })\n .orderBy(({ entry }) => entry.sequence, \"asc\")\n .select(({ entry }) => ({\n id: entry.id,\n sequence: entry.sequence,\n request: entry.request,\n visibility: entry.visibility,\n status: entry.status,\n createdAt: entry.createdAt,\n updatedAt: entry.updatedAt,\n attempts: entry.attempts,\n retryable: entry.retryable ?? true,\n nextAttemptAt: entry.nextAttemptAt,\n executionId: entry.executionId,\n lastError: entry.lastError,\n }))\n );\n }\n\n async enqueue(proposed: OntologyOutboxEntry): Promise<OntologyOutboxEntry> {\n const existing = this.get(proposed.id);\n if (existing) return existing;\n\n const entry = {\n ...proposed,\n sequence: await this.nextSequence(),\n };\n await this.collection.insert(entry, {\n optimistic: false,\n }).isPersisted.promise;\n return entry;\n }\n\n async edit(id: string, request: OntologyActionRequest): Promise<OntologyOutboxEntry> {\n const entry = this.get(id);\n if (!entry || ![\"queued\", \"failed\"].includes(entry.status)) {\n throw new CoordinationTaskRejectedError(`Outbox entry \"${id}\" cannot be edited.`);\n }\n\n const now = Date.now();\n return this.update(id, (draft) => {\n draft.request = request;\n draft.status = \"queued\";\n draft.retryable = true;\n draft.attempts = 0;\n draft.executionId = undefined;\n draft.nextAttemptAt = now;\n draft.updatedAt = now;\n draft.lastError = undefined;\n });\n }\n\n async remove(id: string): Promise<void> {\n const entry = this.get(id);\n if (entry && ![\"queued\", \"failed\"].includes(entry.status)) {\n throw new CoordinationTaskRejectedError(\n `Outbox entry \"${id}\" cannot be removed while it is ${entry.status}.`\n );\n }\n await this.delete(id);\n }\n\n async retry(id: string): Promise<void> {\n const entry = this.get(id);\n if (!entry?.retryable) {\n throw new CoordinationTaskRejectedError(`Outbox entry \"${id}\" is not retriable.`);\n }\n if (entry.status === \"executing\") {\n throw new CoordinationTaskRejectedError(`Outbox entry \"${id}\" is already executing.`);\n }\n\n const now = Date.now();\n await this.update(id, (draft) => {\n draft.status = \"queued\";\n draft.executionId = undefined;\n draft.nextAttemptAt = now;\n draft.updatedAt = now;\n draft.lastError = undefined;\n });\n }\n\n async recover(\n failureStrategy: \"pause\" | \"discard-all\",\n maxRetries: number\n ): Promise<OntologyOutboxEntry[]> {\n const entries = await this.entries();\n const head = entries[0];\n if (!head) return [];\n\n const interrupted = head.status === \"executing\" || head.lastError?.name === \"InterruptedExecution\";\n const exhausted =\n head.status === \"failed\" &&\n (!head.retryable ||\n head.attempts > maxRetries ||\n head.lastError?.name === \"ProjectionRestoreError\");\n if (failureStrategy === \"discard-all\" && (interrupted || exhausted)) {\n await this.deleteEntries(entries);\n return entries;\n }\n\n if (head.status === \"failed\" && head.retryable && head.attempts <= maxRetries) {\n const now = Date.now();\n await this.update(head.id, (draft) => {\n draft.status = \"queued\";\n draft.executionId = undefined;\n draft.nextAttemptAt = now;\n draft.updatedAt = now;\n });\n return [];\n }\n\n if (head.status === \"executing\") {\n const now = Date.now();\n await this.update(head.id, (draft) => {\n draft.status = \"failed\";\n draft.retryable = true;\n draft.executionId = undefined;\n draft.updatedAt = now;\n draft.lastError = {\n name: \"InterruptedExecution\",\n message: \"Execution was interrupted; retry manually.\",\n };\n });\n }\n return [];\n }\n\n async claim(): Promise<OntologyOutboxEntry | undefined> {\n const entry = await this.head();\n if (entry?.status !== \"queued\" || entry.nextAttemptAt > Date.now()) {\n return;\n }\n\n const executionId = crypto.randomUUID();\n return this.update(entry.id, (draft) => {\n draft.status = \"executing\";\n draft.executionId = executionId;\n draft.updatedAt = Date.now();\n });\n }\n\n async nextRetryAt(): Promise<number | undefined> {\n const entry = await this.head();\n return entry?.status === \"queued\" ? entry.nextAttemptAt : undefined;\n }\n\n async complete(id: string, executionId: string): Promise<void> {\n this.assertCurrentExecution(id, executionId);\n await this.delete(id);\n }\n\n async fail(\n id: string,\n executionId: string,\n retryable: boolean,\n error: OutboxErrorDetails,\n retryAt?: number\n ): Promise<OntologyOutboxEntry> {\n const entry = this.assertCurrentExecution(id, executionId);\n const now = Date.now();\n return this.update(id, (draft) => {\n draft.status = retryAt === undefined ? \"failed\" : \"queued\";\n draft.retryable = retryable;\n draft.attempts = entry.attempts + 1;\n draft.executionId = undefined;\n draft.nextAttemptAt = retryAt ?? now;\n draft.updatedAt = now;\n draft.lastError = error;\n });\n }\n\n async discardAll(id: string, executionId: string): Promise<OntologyOutboxEntry[]> {\n this.assertCurrentExecution(id, executionId);\n return this.discardFrom(id);\n }\n\n async discardFrom(id: string): Promise<OntologyOutboxEntry[]> {\n const failed = this.get(id);\n if (!failed) return [];\n const discarded = (await this.entries()).filter((entry) => entry.sequence >= failed.sequence);\n await this.deleteEntries(discarded);\n return discarded;\n }\n\n private async head(): Promise<OntologyOutboxEntry | undefined> {\n return await queryOnce((query) =>\n query\n .from({ entry: this.collection })\n .orderBy(({ entry }) => entry.sequence, \"asc\")\n .select(({ entry }) => ({\n id: entry.id,\n sequence: entry.sequence,\n request: entry.request,\n visibility: entry.visibility,\n status: entry.status,\n createdAt: entry.createdAt,\n updatedAt: entry.updatedAt,\n attempts: entry.attempts,\n retryable: entry.retryable ?? true,\n nextAttemptAt: entry.nextAttemptAt,\n executionId: entry.executionId,\n lastError: entry.lastError,\n }))\n .findOne()\n );\n }\n\n private async nextSequence(): Promise<number> {\n const latest = (await queryOnce((query) =>\n query\n .from({ entry: this.collection })\n .orderBy(({ entry }) => entry.sequence, \"desc\")\n .select(({ entry }) => ({\n sequence: entry.sequence,\n }))\n .findOne()\n )) as { sequence: number } | undefined;\n return (latest?.sequence ?? 0) + 1;\n }\n\n private assertCurrentExecution(id: string, executionId: string): OntologyOutboxEntry {\n const entry = this.get(id);\n if (entry?.status !== \"executing\" || entry.executionId !== executionId) {\n throw new CoordinationTaskRejectedError(\n `Outbox execution claim for \"${id}\" is no longer current.`,\n \"STALE_EXECUTION\"\n );\n }\n return entry;\n }\n\n private async update(\n id: string,\n update: (draft: OntologyOutboxEntry) => void\n ): Promise<OntologyOutboxEntry> {\n const transaction = this.collection.update(id, { optimistic: false }, update);\n await transaction.isPersisted.promise;\n const entry = this.get(id);\n if (!entry) {\n throw new Error(`Outbox entry \"${id}\" disappeared during an update.`);\n }\n return entry;\n }\n\n private async delete(id: string): Promise<void> {\n if (!this.collection.has(id)) return;\n await this.collection.delete(id, {\n optimistic: false,\n }).isPersisted.promise;\n }\n\n private async deleteEntries(entries: readonly OntologyOutboxEntry[]): Promise<void> {\n if (entries.length === 0) return;\n await this.collection.delete(\n entries.map((entry) => entry.id),\n { optimistic: false }\n ).isPersisted.promise;\n }\n}\n"],"mappings":"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"}
@@ -1,61 +0,0 @@
1
- import { OntologyActionRequest, OntologyOutboxEntry } from "./types.js";
2
- //#region src/live/outbox/service.d.ts
3
- export declare const OUTBOX_COORDINATION_SERVICE = "party-stack.outbox.v1";
4
- export interface OutboxErrorDetails {
5
- name: string;
6
- message: string;
7
- }
8
- export type OutboxResultEvent = {
9
- type: "completed";
10
- id: string;
11
- result: unknown;
12
- } | {
13
- type: "rejected";
14
- id: string;
15
- error: OutboxErrorDetails;
16
- };
17
- export interface OutboxCoordinationService {
18
- methods: {
19
- enqueue(input: {
20
- entry: OntologyOutboxEntry;
21
- }): Promise<OntologyOutboxEntry>;
22
- edit(input: {
23
- id: string;
24
- request: OntologyActionRequest;
25
- }): Promise<OntologyOutboxEntry>;
26
- remove(input: {
27
- id: string;
28
- }): Promise<void>;
29
- retry(input: {
30
- id: string;
31
- }): Promise<void>;
32
- recover(input: {
33
- failureStrategy: "pause" | "discard-all";
34
- maxRetries: number;
35
- }): Promise<void>;
36
- claim(input: Record<string, never>): Promise<OntologyOutboxEntry | undefined>;
37
- nextRetryAt(input: Record<string, never>): Promise<number | undefined>;
38
- complete(input: {
39
- id: string;
40
- executionId: string;
41
- result: unknown;
42
- }): Promise<void>;
43
- fail(input: {
44
- id: string;
45
- executionId: string;
46
- retryable: boolean;
47
- retryAt?: number;
48
- error: OutboxErrorDetails;
49
- }): Promise<OntologyOutboxEntry>;
50
- discardAll(input: {
51
- id: string;
52
- executionId: string;
53
- error: OutboxErrorDetails;
54
- }): Promise<void>;
55
- };
56
- events: {
57
- result: OutboxResultEvent;
58
- };
59
- }
60
- //#endregion
61
- //# sourceMappingURL=service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.d.ts","names":[],"sources":["../../../src/live/outbox/service.ts"],"mappings":";;qBAEa;iBAEI;EACb;EACA;;YAGQ;EAEF;EACA;EACA;;EAGA;EACA;EACA,OAAO;;iBAGA;EACb;IACI,QAAQ;MAAS,OAAO;QAAwB,QAAQ;IACxD,KAAK;MAAS;MAAY,SAAS;QAA0B,QAAQ;IACrE,OAAO;MAAS;QAAe;IAC/B,MAAM;MAAS;QAAe;IAC9B,QAAQ;MAAS;MAA0C;QAAuB;IAClF,MAAM,OAAO,wBAAwB,QAAQ;IAC7C,YAAY,OAAO,wBAAwB;IAC3C,SAAS;MAAS;MAAY;MAAqB;QAAoB;IACvE,KAAK;MACD;MACA;MACA;MACA;MACA,OAAO;QACP,QAAQ;IACZ,WAAW;MAAS;MAAY;MAAqB,OAAO;QAAuB;;EAEvF;IACI,QAAQ"}
@@ -1,6 +0,0 @@
1
- //#region src/live/outbox/service.ts
2
- const OUTBOX_COORDINATION_SERVICE = "party-stack.outbox.v1";
3
- //#endregion
4
- export { OUTBOX_COORDINATION_SERVICE };
5
-
6
- //# sourceMappingURL=service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../src/live/outbox/service.ts"],"sourcesContent":["import type { OntologyActionRequest, OntologyOutboxEntry } from \"./types.js\";\n\nexport const OUTBOX_COORDINATION_SERVICE = \"party-stack.outbox.v1\";\n\nexport interface OutboxErrorDetails {\n name: string;\n message: string;\n}\n\nexport type OutboxResultEvent =\n | {\n type: \"completed\";\n id: string;\n result: unknown;\n }\n | {\n type: \"rejected\";\n id: string;\n error: OutboxErrorDetails;\n };\n\nexport interface OutboxCoordinationService {\n methods: {\n enqueue(input: { entry: OntologyOutboxEntry }): Promise<OntologyOutboxEntry>;\n edit(input: { id: string; request: OntologyActionRequest }): Promise<OntologyOutboxEntry>;\n remove(input: { id: string }): Promise<void>;\n retry(input: { id: string }): Promise<void>;\n recover(input: { failureStrategy: \"pause\" | \"discard-all\"; maxRetries: number }): Promise<void>;\n claim(input: Record<string, never>): Promise<OntologyOutboxEntry | undefined>;\n nextRetryAt(input: Record<string, never>): Promise<number | undefined>;\n complete(input: { id: string; executionId: string; result: unknown }): Promise<void>;\n fail(input: {\n id: string;\n executionId: string;\n retryable: boolean;\n retryAt?: number;\n error: OutboxErrorDetails;\n }): Promise<OntologyOutboxEntry>;\n discardAll(input: { id: string; executionId: string; error: OutboxErrorDetails }): Promise<void>;\n };\n events: {\n result: OutboxResultEvent;\n };\n}\n"],"mappings":";AAEA,MAAa,8BAA8B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/live/outbox/types.ts"],"sourcesContent":["import type { Collection } from \"@tanstack/db\";\n\nexport type OntologyOutboxStatus = \"queued\" | \"executing\" | \"failed\";\n\nexport class NonRetryableError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"NonRetryableError\";\n }\n}\n\nexport interface OntologyActionRequest {\n actionTypeName: string;\n parameters: Record<string, unknown>;\n idempotencyKey: string;\n}\n\nexport interface OntologyOutboxEntry {\n id: string;\n sequence: number;\n request: OntologyActionRequest;\n visibility?: \"confirmed\" | \"optimistic\";\n status: OntologyOutboxStatus;\n createdAt: number;\n updatedAt: number;\n attempts: number;\n retryable: boolean;\n nextAttemptAt: number;\n executionId?: string;\n lastError?: {\n name: string;\n message: string;\n };\n}\n\nexport interface EnqueuedOntologyAction<Result = unknown> {\n entry: OntologyOutboxEntry;\n completed: Promise<Result>;\n}\n\nexport interface OntologyOutbox {\n readonly collection: Collection<OntologyOutboxEntry, string>;\n readonly ready: Promise<void>;\n enqueue<Result = unknown>(\n request: Omit<OntologyActionRequest, \"idempotencyKey\"> & {\n idempotencyKey?: string;\n },\n options?: {\n visibility?: \"confirmed\" | \"optimistic\";\n }\n ): Promise<EnqueuedOntologyAction<Result>>;\n edit(id: string, update: (request: OntologyActionRequest) => void): Promise<OntologyOutboxEntry>;\n remove(id: string): Promise<void>;\n retry(id: string): Promise<void>;\n cleanup(): Promise<void>;\n}\n"],"mappings":";AAIA,IAAa,oBAAb,cAAuC,MAAM;CACzC,YAAY,SAAiB,SAAwB;EACjD,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;CAChB;AACJ"}
@@ -1,5 +0,0 @@
1
- import { Collection } from "@tanstack/db";
2
- //#region src/live/waitForCollectionReady.d.ts
3
- export declare function waitForCollectionsReady(collections: Iterable<Collection<Record<string, unknown>, string | number>>): Promise<void>;
4
- //#endregion
5
- //# sourceMappingURL=waitForCollectionReady.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"waitForCollectionReady.d.ts","names":[],"sources":["../../src/live/waitForCollectionReady.ts"],"mappings":";;wBAkEsB,wBAClB,aAAa,SAAS,WAAW,6CAClC"}
@@ -1,49 +0,0 @@
1
- //#region src/live/waitForCollectionReady.ts
2
- /**
3
- * Starts idle/on-demand collection synchronization and waits until the
4
- * collection is ready.
5
- *
6
- * TanStack's `onFirstReady` only registers a callback: it does not start an
7
- * idle collection, report terminal errors, or distinguish cleanup from
8
- * readiness. Pending callbacks are also invoked during cleanup. This helper
9
- * starts sync, returns an awaitable promise, and rejects on error or cleanup.
10
- *
11
- * Race-safe: status listeners are registered before starting sync / reading
12
- * the current status, so a transition cannot be missed.
13
- */
14
- async function waitForCollectionReady(collection) {
15
- if (collection.status === "ready") return;
16
- if (collection.status === "error") throw new Error(`Collection "${collection.id}" is in an error state.`);
17
- if (collection.status === "cleaned-up") throw new Error(`Collection "${collection.id}" has been cleaned up.`);
18
- await new Promise((resolve, reject) => {
19
- let settled = false;
20
- const finish = (error) => {
21
- if (settled) return;
22
- settled = true;
23
- off();
24
- if (error) reject(error);
25
- else resolve();
26
- };
27
- const off = collection.on("status:change", (event) => {
28
- if (event.status === "ready") finish();
29
- else if (event.status === "error") finish(/* @__PURE__ */ new Error(`Collection "${collection.id}" is in an error state.`));
30
- else if (event.status === "cleaned-up") finish(/* @__PURE__ */ new Error(`Collection "${collection.id}" has been cleaned up.`));
31
- });
32
- if (collection.status === "idle") try {
33
- collection.startSyncImmediate();
34
- } catch (error) {
35
- finish(error instanceof Error ? error : new Error(String(error)));
36
- return;
37
- }
38
- if (collection.status === "ready") finish();
39
- else if (collection.status === "error") finish(/* @__PURE__ */ new Error(`Collection "${collection.id}" is in an error state.`));
40
- else if (collection.status === "cleaned-up") finish(/* @__PURE__ */ new Error(`Collection "${collection.id}" has been cleaned up.`));
41
- });
42
- }
43
- async function waitForCollectionsReady(collections) {
44
- await Promise.all([...collections].map((collection) => waitForCollectionReady(collection)));
45
- }
46
- //#endregion
47
- export { waitForCollectionsReady };
48
-
49
- //# sourceMappingURL=waitForCollectionReady.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"waitForCollectionReady.js","names":[],"sources":["../../src/live/waitForCollectionReady.ts"],"sourcesContent":["import type { Collection } from \"@tanstack/db\";\n\n/**\n * Starts idle/on-demand collection synchronization and waits until the\n * collection is ready.\n *\n * TanStack's `onFirstReady` only registers a callback: it does not start an\n * idle collection, report terminal errors, or distinguish cleanup from\n * readiness. Pending callbacks are also invoked during cleanup. This helper\n * starts sync, returns an awaitable promise, and rejects on error or cleanup.\n *\n * Race-safe: status listeners are registered before starting sync / reading\n * the current status, so a transition cannot be missed.\n */\nasync function waitForCollectionReady(\n collection: Collection<Record<string, unknown>, string | number>\n): Promise<void> {\n if (collection.status === \"ready\") return;\n if (collection.status === \"error\") {\n throw new Error(`Collection \"${collection.id}\" is in an error state.`);\n }\n if (collection.status === \"cleaned-up\") {\n throw new Error(`Collection \"${collection.id}\" has been cleaned up.`);\n }\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n off();\n if (error) reject(error);\n else resolve();\n };\n\n const off = collection.on(\"status:change\", (event) => {\n if (event.status === \"ready\") {\n finish();\n } else if (event.status === \"error\") {\n finish(new Error(`Collection \"${collection.id}\" is in an error state.`));\n } else if (event.status === \"cleaned-up\") {\n finish(new Error(`Collection \"${collection.id}\" has been cleaned up.`));\n }\n });\n\n // Start sync after the listener is attached so we cannot miss ready.\n if (collection.status === \"idle\") {\n try {\n collection.startSyncImmediate();\n } catch (error) {\n finish(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n }\n\n // Close the TOCTOU window for a status that was already terminal.\n if (collection.status === \"ready\") {\n finish();\n } else if (collection.status === \"error\") {\n finish(new Error(`Collection \"${collection.id}\" is in an error state.`));\n } else if (collection.status === \"cleaned-up\") {\n finish(new Error(`Collection \"${collection.id}\" has been cleaned up.`));\n }\n });\n}\n\nexport async function waitForCollectionsReady(\n collections: Iterable<Collection<Record<string, unknown>, string | number>>\n): Promise<void> {\n await Promise.all([...collections].map((collection) => waitForCollectionReady(collection)));\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,eAAe,uBACX,YACa;CACb,IAAI,WAAW,WAAW,SAAS;CACnC,IAAI,WAAW,WAAW,SACtB,MAAM,IAAI,MAAM,eAAe,WAAW,GAAG,wBAAwB;CAEzE,IAAI,WAAW,WAAW,cACtB,MAAM,IAAI,MAAM,eAAe,WAAW,GAAG,uBAAuB;CAGxE,MAAM,IAAI,SAAe,SAAS,WAAW;EACzC,IAAI,UAAU;EACd,MAAM,UAAU,UAAkB;GAC9B,IAAI,SAAS;GACb,UAAU;GACV,IAAI;GACJ,IAAI,OAAO,OAAO,KAAK;QAClB,QAAQ;EACjB;EAEA,MAAM,MAAM,WAAW,GAAG,kBAAkB,UAAU;GAClD,IAAI,MAAM,WAAW,SACjB,OAAO;QACJ,IAAI,MAAM,WAAW,SACxB,uBAAO,IAAI,MAAM,eAAe,WAAW,GAAG,wBAAwB,CAAC;QACpE,IAAI,MAAM,WAAW,cACxB,uBAAO,IAAI,MAAM,eAAe,WAAW,GAAG,uBAAuB,CAAC;EAE9E,CAAC;EAGD,IAAI,WAAW,WAAW,QACtB,IAAI;GACA,WAAW,mBAAmB;EAClC,SAAS,OAAO;GACZ,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;GAChE;EACJ;EAIJ,IAAI,WAAW,WAAW,SACtB,OAAO;OACJ,IAAI,WAAW,WAAW,SAC7B,uBAAO,IAAI,MAAM,eAAe,WAAW,GAAG,wBAAwB,CAAC;OACpE,IAAI,WAAW,WAAW,cAC7B,uBAAO,IAAI,MAAM,eAAe,WAAW,GAAG,uBAAuB,CAAC;CAE9E,CAAC;AACL;AAEA,eAAsB,wBAClB,aACa;CACb,MAAM,QAAQ,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,KAAK,eAAe,uBAAuB,UAAU,CAAC,CAAC;AAC9F"}
@@ -1,7 +0,0 @@
1
- import { OntologyIR } from "../ir/generated/types.js";
2
- import "../ir/index.js";
3
- import { OntologyBackendAdapter } from "../live/OntologyBackendAdapter.js";
4
- //#region src/meta/createLocalMetaOntologyBackendAdapter.d.ts
5
- export declare function createLocalMetaOntologyBackendAdapter(ir: OntologyIR): OntologyBackendAdapter;
6
- //#endregion
7
- //# sourceMappingURL=createLocalMetaOntologyBackendAdapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createLocalMetaOntologyBackendAdapter.d.ts","names":[],"sources":["../../src/meta/createLocalMetaOntologyBackendAdapter.ts"],"mappings":";;;;wBAmBgB,sCAAsC,IAAI,aAAa"}
@@ -1,44 +0,0 @@
1
- import { localOnlyCollectionOptions } from "@tanstack/db";
2
- //#region src/meta/createLocalMetaOntologyBackendAdapter.ts
3
- function localId(kind, name) {
4
- return `local:${kind}:${encodeURIComponent(name)}`;
5
- }
6
- function collectionOptions(rows, getKey) {
7
- return localOnlyCollectionOptions({
8
- getKey,
9
- initialData: rows
10
- });
11
- }
12
- function createLocalMetaOntologyBackendAdapter(ir) {
13
- const objectTypes = ir.objectTypes.map((objectType) => ({
14
- ...objectType,
15
- id: localId("ObjectType", objectType.name),
16
- properties: objectType.properties.map((property) => ({
17
- ...property,
18
- id: localId("Property", `${objectType.name}.${property.name}`)
19
- }))
20
- }));
21
- const actionTypes = ir.actionTypes.map((actionType) => ({
22
- ...actionType,
23
- id: localId("ActionType", actionType.name)
24
- }));
25
- return {
26
- name: "local-metadata",
27
- getCollectionOptions(objectType) {
28
- switch (objectType) {
29
- case "ObjectType": return collectionOptions(objectTypes, (row) => row.name);
30
- case "ValueType": return collectionOptions(ir.types, (row) => row.name);
31
- case "LinkType": return collectionOptions(ir.linkTypes, (row) => row.id);
32
- case "ActionType": return collectionOptions(actionTypes, (row) => row.name);
33
- case "QueryFunctionType": return collectionOptions(ir.queryFunctionTypes, (row) => row.name);
34
- default: throw new Error(`Unsupported local metadata object type "${objectType}".`);
35
- }
36
- },
37
- applyAction: () => Promise.reject(/* @__PURE__ */ new Error("Local metadata is read-only.")),
38
- runQueryFunction: () => Promise.reject(/* @__PURE__ */ new Error("Local metadata has no query functions."))
39
- };
40
- }
41
- //#endregion
42
- export { createLocalMetaOntologyBackendAdapter };
43
-
44
- //# sourceMappingURL=createLocalMetaOntologyBackendAdapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createLocalMetaOntologyBackendAdapter.js","names":[],"sources":["../../src/meta/createLocalMetaOntologyBackendAdapter.ts"],"sourcesContent":["import { localOnlyCollectionOptions } from \"@tanstack/db\";\nimport type { OntologyIR } from \"../ir/index.js\";\nimport type { OntologyBackendAdapter, OntologyCollectionOptions } from \"../live/OntologyBackendAdapter.js\";\nimport type { ActionType, ObjectType } from \"./generated/types.js\";\n\nfunction localId(kind: \"ActionType\" | \"ObjectType\" | \"Property\", name: string): string {\n return `local:${kind}:${encodeURIComponent(name)}`;\n}\n\nfunction collectionOptions<T extends object>(\n rows: T[],\n getKey: (row: T) => string\n): OntologyCollectionOptions {\n return localOnlyCollectionOptions({\n getKey,\n initialData: rows,\n }) as unknown as OntologyCollectionOptions;\n}\n\nexport function createLocalMetaOntologyBackendAdapter(ir: OntologyIR): OntologyBackendAdapter {\n const objectTypes: ObjectType[] = ir.objectTypes.map((objectType) => ({\n ...objectType,\n id: localId(\"ObjectType\", objectType.name),\n properties: objectType.properties.map((property) => ({\n ...property,\n id: localId(\"Property\", `${objectType.name}.${property.name}`),\n })),\n }));\n const actionTypes: ActionType[] = ir.actionTypes.map((actionType) => ({\n ...actionType,\n id: localId(\"ActionType\", actionType.name),\n }));\n\n return {\n name: \"local-metadata\",\n getCollectionOptions(objectType) {\n switch (objectType) {\n case \"ObjectType\":\n return collectionOptions(objectTypes, (row) => row.name);\n case \"ValueType\":\n return collectionOptions(ir.types, (row) => row.name);\n case \"LinkType\":\n return collectionOptions(ir.linkTypes, (row) => row.id);\n case \"ActionType\":\n return collectionOptions(actionTypes, (row) => row.name);\n case \"QueryFunctionType\":\n return collectionOptions(ir.queryFunctionTypes, (row) => row.name);\n default:\n throw new Error(`Unsupported local metadata object type \"${objectType}\".`);\n }\n },\n applyAction: () => Promise.reject(new Error(\"Local metadata is read-only.\")),\n runQueryFunction: () => Promise.reject(new Error(\"Local metadata has no query functions.\")),\n };\n}\n"],"mappings":";;AAKA,SAAS,QAAQ,MAAgD,MAAsB;CACnF,OAAO,SAAS,KAAK,GAAG,mBAAmB,IAAI;AACnD;AAEA,SAAS,kBACL,MACA,QACyB;CACzB,OAAO,2BAA2B;EAC9B;EACA,aAAa;CACjB,CAAC;AACL;AAEA,SAAgB,sCAAsC,IAAwC;CAC1F,MAAM,cAA4B,GAAG,YAAY,KAAK,gBAAgB;EAClE,GAAG;EACH,IAAI,QAAQ,cAAc,WAAW,IAAI;EACzC,YAAY,WAAW,WAAW,KAAK,cAAc;GACjD,GAAG;GACH,IAAI,QAAQ,YAAY,GAAG,WAAW,KAAK,GAAG,SAAS,MAAM;EACjE,EAAE;CACN,EAAE;CACF,MAAM,cAA4B,GAAG,YAAY,KAAK,gBAAgB;EAClE,GAAG;EACH,IAAI,QAAQ,cAAc,WAAW,IAAI;CAC7C,EAAE;CAEF,OAAO;EACH,MAAM;EACN,qBAAqB,YAAY;GAC7B,QAAQ,YAAR;IACI,KAAK,cACD,OAAO,kBAAkB,cAAc,QAAQ,IAAI,IAAI;IAC3D,KAAK,aACD,OAAO,kBAAkB,GAAG,QAAQ,QAAQ,IAAI,IAAI;IACxD,KAAK,YACD,OAAO,kBAAkB,GAAG,YAAY,QAAQ,IAAI,EAAE;IAC1D,KAAK,cACD,OAAO,kBAAkB,cAAc,QAAQ,IAAI,IAAI;IAC3D,KAAK,qBACD,OAAO,kBAAkB,GAAG,qBAAqB,QAAQ,IAAI,IAAI;IACrE,SACI,MAAM,IAAI,MAAM,2CAA2C,WAAW,GAAG;GACjF;EACJ;EACA,mBAAmB,QAAQ,uBAAO,IAAI,MAAM,8BAA8B,CAAC;EAC3E,wBAAwB,QAAQ,uBAAO,IAAI,MAAM,wCAAwC,CAAC;CAC9F;AACJ"}