@opetope/runtime 0.1.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 (314) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +345 -0
  4. package/README.ru.md +344 -0
  5. package/dist/application-compiler-edges.d.ts +3 -0
  6. package/dist/application-compiler-edges.js +2 -0
  7. package/dist/application-compiler-edges.js.map +1 -0
  8. package/dist/application-compiler-graph.d.ts +8 -0
  9. package/dist/application-compiler-graph.js +2 -0
  10. package/dist/application-compiler-graph.js.map +1 -0
  11. package/dist/application-compiler.d.ts +116 -0
  12. package/dist/application-compiler.js +2 -0
  13. package/dist/application-compiler.js.map +1 -0
  14. package/dist/application-conditions.d.ts +18 -0
  15. package/dist/application-conditions.js +2 -0
  16. package/dist/application-conditions.js.map +1 -0
  17. package/dist/application-definition.d.ts +30 -0
  18. package/dist/application-definition.js +2 -0
  19. package/dist/application-definition.js.map +1 -0
  20. package/dist/application-error.d.ts +10 -0
  21. package/dist/application-error.js +2 -0
  22. package/dist/application-error.js.map +1 -0
  23. package/dist/application-execution.d.ts +43 -0
  24. package/dist/application-execution.js +2 -0
  25. package/dist/application-execution.js.map +1 -0
  26. package/dist/application-feature-bindings.d.ts +11 -0
  27. package/dist/application-feature-bindings.js +2 -0
  28. package/dist/application-feature-bindings.js.map +1 -0
  29. package/dist/application-feature-instance.d.ts +5 -0
  30. package/dist/application-feature-instance.js +2 -0
  31. package/dist/application-feature-instance.js.map +1 -0
  32. package/dist/application-group-order.d.ts +29 -0
  33. package/dist/application-group-order.js +2 -0
  34. package/dist/application-group-order.js.map +1 -0
  35. package/dist/application-instance-retirement.d.ts +36 -0
  36. package/dist/application-instance-retirement.js +2 -0
  37. package/dist/application-instance-retirement.js.map +1 -0
  38. package/dist/application-open-options.d.ts +29 -0
  39. package/dist/application-open-options.js +2 -0
  40. package/dist/application-open-options.js.map +1 -0
  41. package/dist/application-port-compiler.d.ts +28 -0
  42. package/dist/application-port-compiler.js +2 -0
  43. package/dist/application-port-compiler.js.map +1 -0
  44. package/dist/attachment-call-declaration.d.ts +43 -0
  45. package/dist/attachment-call-declaration.js +2 -0
  46. package/dist/attachment-call-declaration.js.map +1 -0
  47. package/dist/attachment-declaration.d.ts +68 -0
  48. package/dist/attachment-declaration.js +2 -0
  49. package/dist/attachment-declaration.js.map +1 -0
  50. package/dist/attachment-execution.d.ts +9 -0
  51. package/dist/attachment-execution.js +2 -0
  52. package/dist/attachment-execution.js.map +1 -0
  53. package/dist/attachment-retirement-scheduler.d.ts +14 -0
  54. package/dist/attachment-retirement-scheduler.js +2 -0
  55. package/dist/attachment-retirement-scheduler.js.map +1 -0
  56. package/dist/call-option-snapshot.d.ts +20 -0
  57. package/dist/call-option-snapshot.js +2 -0
  58. package/dist/call-option-snapshot.js.map +1 -0
  59. package/dist/compile-call-target-bindings.d.ts +14 -0
  60. package/dist/compile-call-target-bindings.js +2 -0
  61. package/dist/compile-call-target-bindings.js.map +1 -0
  62. package/dist/compile-module-template.d.ts +38 -0
  63. package/dist/compile-module-template.js +2 -0
  64. package/dist/compile-module-template.js.map +1 -0
  65. package/dist/condition-group-execution.d.ts +44 -0
  66. package/dist/condition-group-execution.js +2 -0
  67. package/dist/condition-group-execution.js.map +1 -0
  68. package/dist/condition-override.d.ts +28 -0
  69. package/dist/condition-override.js +2 -0
  70. package/dist/condition-override.js.map +1 -0
  71. package/dist/condition-source.d.ts +10 -0
  72. package/dist/condition-source.js +2 -0
  73. package/dist/condition-source.js.map +1 -0
  74. package/dist/condition-types.d.ts +14 -0
  75. package/dist/condition.d.ts +28 -0
  76. package/dist/condition.js +2 -0
  77. package/dist/condition.js.map +1 -0
  78. package/dist/control-registry.d.ts +56 -0
  79. package/dist/control-registry.js +2 -0
  80. package/dist/control-registry.js.map +1 -0
  81. package/dist/dynamic-scope-child.d.ts +23 -0
  82. package/dist/dynamic-scope-child.js +2 -0
  83. package/dist/dynamic-scope-child.js.map +1 -0
  84. package/dist/dynamic-scope-controller.d.ts +16 -0
  85. package/dist/dynamic-scope-controller.js +2 -0
  86. package/dist/dynamic-scope-controller.js.map +1 -0
  87. package/dist/feature-attachment-authoring-types.d.ts +51 -0
  88. package/dist/feature-attachment-lowering.d.ts +18 -0
  89. package/dist/feature-attachment-lowering.js +2 -0
  90. package/dist/feature-attachment-lowering.js.map +1 -0
  91. package/dist/feature-attachment.d.ts +45 -0
  92. package/dist/feature-attachment.js +2 -0
  93. package/dist/feature-attachment.js.map +1 -0
  94. package/dist/feature-authoring-types.d.ts +196 -0
  95. package/dist/feature-authoring.d.ts +15 -0
  96. package/dist/feature-authoring.js +2 -0
  97. package/dist/feature-authoring.js.map +1 -0
  98. package/dist/feature-body.d.ts +53 -0
  99. package/dist/feature-body.js +2 -0
  100. package/dist/feature-body.js.map +1 -0
  101. package/dist/feature-call-authority.d.ts +8 -0
  102. package/dist/feature-call-authority.js +2 -0
  103. package/dist/feature-call-authority.js.map +1 -0
  104. package/dist/feature-call-types.d.ts +39 -0
  105. package/dist/feature-call.d.ts +18 -0
  106. package/dist/feature-call.js +2 -0
  107. package/dist/feature-call.js.map +1 -0
  108. package/dist/feature-calls.d.ts +6 -0
  109. package/dist/feature-calls.js +2 -0
  110. package/dist/feature-calls.js.map +1 -0
  111. package/dist/feature-contract.d.ts +70 -0
  112. package/dist/feature-contract.js +2 -0
  113. package/dist/feature-contract.js.map +1 -0
  114. package/dist/feature-contribution-model.d.ts +38 -0
  115. package/dist/feature-contribution-model.js +2 -0
  116. package/dist/feature-contribution-model.js.map +1 -0
  117. package/dist/feature-contribution.d.ts +126 -0
  118. package/dist/feature-contribution.js +2 -0
  119. package/dist/feature-contribution.js.map +1 -0
  120. package/dist/feature-definition-api.d.ts +53 -0
  121. package/dist/feature-definition-support.d.ts +21 -0
  122. package/dist/feature-definition-support.js +2 -0
  123. package/dist/feature-definition-support.js.map +1 -0
  124. package/dist/feature-effect.d.ts +26 -0
  125. package/dist/feature-effect.js +2 -0
  126. package/dist/feature-effect.js.map +1 -0
  127. package/dist/feature-event.d.ts +32 -0
  128. package/dist/feature-event.js +2 -0
  129. package/dist/feature-event.js.map +1 -0
  130. package/dist/feature-generation.d.ts +34 -0
  131. package/dist/feature-generation.js +2 -0
  132. package/dist/feature-generation.js.map +1 -0
  133. package/dist/feature-lazy-generation.d.ts +6 -0
  134. package/dist/feature-lazy-generation.js +2 -0
  135. package/dist/feature-lazy-generation.js.map +1 -0
  136. package/dist/feature-lazy.d.ts +44 -0
  137. package/dist/feature-lazy.js +2 -0
  138. package/dist/feature-lazy.js.map +1 -0
  139. package/dist/feature-materialization-binding.d.ts +31 -0
  140. package/dist/feature-materialization-binding.js +2 -0
  141. package/dist/feature-materialization-binding.js.map +1 -0
  142. package/dist/feature-materialization-types.d.ts +45 -0
  143. package/dist/feature-model-dependencies.d.ts +23 -0
  144. package/dist/feature-model-dependencies.js +2 -0
  145. package/dist/feature-model-dependencies.js.map +1 -0
  146. package/dist/feature-model.d.ts +60 -0
  147. package/dist/feature-model.js +2 -0
  148. package/dist/feature-model.js.map +1 -0
  149. package/dist/feature-optional.d.ts +15 -0
  150. package/dist/feature-optional.js +2 -0
  151. package/dist/feature-optional.js.map +1 -0
  152. package/dist/feature-own-lowering.d.ts +22 -0
  153. package/dist/feature-own-lowering.js +2 -0
  154. package/dist/feature-own-lowering.js.map +1 -0
  155. package/dist/feature-port-binding.d.ts +6 -0
  156. package/dist/feature-port-binding.js +2 -0
  157. package/dist/feature-port-binding.js.map +1 -0
  158. package/dist/feature-port.d.ts +66 -0
  159. package/dist/feature-port.js +2 -0
  160. package/dist/feature-port.js.map +1 -0
  161. package/dist/feature-record.d.ts +6 -0
  162. package/dist/feature-record.js +2 -0
  163. package/dist/feature-record.js.map +1 -0
  164. package/dist/feature-resource.d.ts +29 -0
  165. package/dist/feature-resource.js +2 -0
  166. package/dist/feature-resource.js.map +1 -0
  167. package/dist/feature-scope-types.d.ts +35 -0
  168. package/dist/feature-scope.d.ts +29 -0
  169. package/dist/feature-scope.js +2 -0
  170. package/dist/feature-scope.js.map +1 -0
  171. package/dist/feature-stream.d.ts +37 -0
  172. package/dist/feature-stream.js +2 -0
  173. package/dist/feature-stream.js.map +1 -0
  174. package/dist/feature-timers.d.ts +14 -0
  175. package/dist/feature-timers.js +2 -0
  176. package/dist/feature-timers.js.map +1 -0
  177. package/dist/index.d.ts +19 -0
  178. package/dist/index.js +2 -0
  179. package/dist/index.js.map +1 -0
  180. package/dist/inspection-activity-protocol.d.ts +63 -0
  181. package/dist/inspection-activity.d.ts +54 -0
  182. package/dist/inspection-activity.js +2 -0
  183. package/dist/inspection-activity.js.map +1 -0
  184. package/dist/inspection-diff.d.ts +10 -0
  185. package/dist/inspection-diff.js +2 -0
  186. package/dist/inspection-diff.js.map +1 -0
  187. package/dist/inspection-module-activity.d.ts +4 -0
  188. package/dist/inspection-module-activity.js +2 -0
  189. package/dist/inspection-module-activity.js.map +1 -0
  190. package/dist/inspection-observer.d.ts +38 -0
  191. package/dist/inspection-observer.js +2 -0
  192. package/dist/inspection-observer.js.map +1 -0
  193. package/dist/inspection-plan.d.ts +33 -0
  194. package/dist/inspection-plan.js +2 -0
  195. package/dist/inspection-plan.js.map +1 -0
  196. package/dist/inspection-protocol.d.ts +333 -0
  197. package/dist/inspection-protocol.js +2 -0
  198. package/dist/inspection-protocol.js.map +1 -0
  199. package/dist/inspection-registry.d.ts +41 -0
  200. package/dist/inspection-registry.js +2 -0
  201. package/dist/inspection-registry.js.map +1 -0
  202. package/dist/inspection-session.d.ts +92 -0
  203. package/dist/inspection-session.js +2 -0
  204. package/dist/inspection-session.js.map +1 -0
  205. package/dist/inspection-snapshot.d.ts +4 -0
  206. package/dist/inspection-snapshot.js +2 -0
  207. package/dist/inspection-snapshot.js.map +1 -0
  208. package/dist/inspection-state.d.ts +91 -0
  209. package/dist/inspection-state.js +2 -0
  210. package/dist/inspection-state.js.map +1 -0
  211. package/dist/instance-demand.d.ts +31 -0
  212. package/dist/instance-demand.js +2 -0
  213. package/dist/instance-demand.js.map +1 -0
  214. package/dist/internal.d.ts +41 -0
  215. package/dist/internal.js +2 -0
  216. package/dist/internal.js.map +1 -0
  217. package/dist/keyed-scope-controller.d.ts +11 -0
  218. package/dist/keyed-scope-controller.js +2 -0
  219. package/dist/keyed-scope-controller.js.map +1 -0
  220. package/dist/model-kernel.d.ts +18 -0
  221. package/dist/model-kernel.js +2 -0
  222. package/dist/model-kernel.js.map +1 -0
  223. package/dist/module-call-context.d.ts +7 -0
  224. package/dist/module-call-context.js +2 -0
  225. package/dist/module-call-context.js.map +1 -0
  226. package/dist/module-call-runtime.d.ts +21 -0
  227. package/dist/module-call-runtime.js +2 -0
  228. package/dist/module-call-runtime.js.map +1 -0
  229. package/dist/module-generation.d.ts +57 -0
  230. package/dist/module-generation.js +2 -0
  231. package/dist/module-generation.js.map +1 -0
  232. package/dist/module-instance-types.d.ts +156 -0
  233. package/dist/module-instance.d.ts +19 -0
  234. package/dist/module-instance.js +2 -0
  235. package/dist/module-instance.js.map +1 -0
  236. package/dist/module-runtime-identity.d.ts +4 -0
  237. package/dist/module-runtime-identity.js +2 -0
  238. package/dist/module-runtime-identity.js.map +1 -0
  239. package/dist/module-scope-open.d.ts +4 -0
  240. package/dist/module-scope-open.js +2 -0
  241. package/dist/module-scope-open.js.map +1 -0
  242. package/dist/module-scope-retirement.d.ts +3 -0
  243. package/dist/module-scope-retirement.js +2 -0
  244. package/dist/module-scope-retirement.js.map +1 -0
  245. package/dist/module-template-ir.d.ts +59 -0
  246. package/dist/owner-generation-retirement.d.ts +6 -0
  247. package/dist/owner-generation-retirement.js +2 -0
  248. package/dist/owner-generation-retirement.js.map +1 -0
  249. package/dist/owner-generation-state.d.ts +123 -0
  250. package/dist/owner-generation-state.js +2 -0
  251. package/dist/owner-generation-state.js.map +1 -0
  252. package/dist/owner-generation.d.ts +16 -0
  253. package/dist/owner-generation.js +2 -0
  254. package/dist/owner-generation.js.map +1 -0
  255. package/dist/public-module-definition.d.ts +9 -0
  256. package/dist/public-module-definition.js +2 -0
  257. package/dist/public-module-definition.js.map +1 -0
  258. package/dist/public-module-instance.d.ts +6 -0
  259. package/dist/public-module-instance.js +2 -0
  260. package/dist/public-module-instance.js.map +1 -0
  261. package/dist/public-module-retirement-diagnostics.d.ts +5 -0
  262. package/dist/public-module-retirement-diagnostics.js +2 -0
  263. package/dist/public-module-retirement-diagnostics.js.map +1 -0
  264. package/dist/public-module-retirement.d.ts +3 -0
  265. package/dist/public-module-retirement.js +2 -0
  266. package/dist/public-module-retirement.js.map +1 -0
  267. package/dist/public-module-scope.d.ts +5 -0
  268. package/dist/public-module-scope.js +2 -0
  269. package/dist/public-module-scope.js.map +1 -0
  270. package/dist/public-module-state.d.ts +28 -0
  271. package/dist/public-module-state.js +2 -0
  272. package/dist/public-module-state.js.map +1 -0
  273. package/dist/public-module-types.d.ts +295 -0
  274. package/dist/public-module.d.ts +4 -0
  275. package/dist/resource-cache.d.ts +12 -0
  276. package/dist/resource-cache.js +2 -0
  277. package/dist/resource-cache.js.map +1 -0
  278. package/dist/resource-controller.d.ts +29 -0
  279. package/dist/resource-controller.js +2 -0
  280. package/dist/resource-controller.js.map +1 -0
  281. package/dist/resource-policy.d.ts +16 -0
  282. package/dist/resource-policy.js +2 -0
  283. package/dist/resource-policy.js.map +1 -0
  284. package/dist/resource-snapshot.d.ts +12 -0
  285. package/dist/resource-snapshot.js +2 -0
  286. package/dist/resource-snapshot.js.map +1 -0
  287. package/dist/resource-types.d.ts +3 -0
  288. package/dist/runtime-error-reporting.d.ts +4 -0
  289. package/dist/runtime-error-reporting.js +2 -0
  290. package/dist/runtime-error-reporting.js.map +1 -0
  291. package/dist/stream-backpressure.d.ts +18 -0
  292. package/dist/stream-backpressure.js +2 -0
  293. package/dist/stream-backpressure.js.map +1 -0
  294. package/dist/stream-cleanup.d.ts +17 -0
  295. package/dist/stream-cleanup.js +2 -0
  296. package/dist/stream-cleanup.js.map +1 -0
  297. package/dist/stream-controller-types.d.ts +51 -0
  298. package/dist/stream-controller.d.ts +5 -0
  299. package/dist/stream-controller.js +2 -0
  300. package/dist/stream-controller.js.map +1 -0
  301. package/docs/agent-guide.md +214 -0
  302. package/docs/agent-guide.ru.md +208 -0
  303. package/docs/cookbook.md +734 -0
  304. package/docs/cookbook.ru.md +729 -0
  305. package/docs/decisions.md +1437 -0
  306. package/docs/devtools.md +423 -0
  307. package/docs/devtools.ru.md +419 -0
  308. package/docs/how-it-works.md +521 -0
  309. package/docs/how-it-works.ru.md +495 -0
  310. package/docs/releases.md +78 -0
  311. package/docs/releases.ru.md +78 -0
  312. package/docs/spec.md +874 -0
  313. package/docs/spec.ru.md +884 -0
  314. package/package.json +72 -0
@@ -0,0 +1,6 @@
1
+ import type { OwnerBoundAttachmentIdentity, OwnerGeneration, OwnerGenerationController, OwnerGenerationPlanRetirement, OwnerGenerationRetirement } from './owner-generation-state.js';
2
+ declare function retireOwnedGeneration(controller: OwnerGenerationController, generation: OwnerGeneration, requestedAttachments: readonly OwnerBoundAttachmentIdentity[]): OwnerGenerationRetirement;
3
+ /** Package-private C4c seam; intentionally absent from `./internal`. */
4
+ declare function retirePlannedOwnerGeneration(controller: OwnerGenerationController, generation: OwnerGeneration, requestedPlan: readonly OwnerBoundAttachmentIdentity[]): OwnerGenerationPlanRetirement;
5
+ declare function acknowledgeOwnerGenerationDrain(controller: OwnerGenerationController, generation: OwnerGeneration, requestedAttachments: readonly OwnerBoundAttachmentIdentity[], receipt: OwnerGenerationRetirement): void;
6
+ export { acknowledgeOwnerGenerationDrain, retireOwnedGeneration, retirePlannedOwnerGeneration };
@@ -0,0 +1,2 @@
1
+ import{FeatureError as E}from"@opetope/core";import{abortWithReason as b,createAggregateError as D}from"@opetope/core/internal";import{getControllerDefinition as u,assertCurrentGeneration as l,flushPublications as T,sameCompletedAttachments as p,getAttachmentDefinition as h,sameAttachments as A,makeRetirementReceipt as R,stageSourceSnapshot as k,physicalGenerationIsOccupied as v}from"./owner-generation-state.js";function j(e,r){if(r.length!==e.ownedAttachments.size)throw new TypeError("Owner retirement must contain every live owner-bound attachment exactly once.");const n=new Set;for(const t of r){if(n.has(t)||!e.ownedAttachments.has(t))throw new TypeError("Owner retirement must contain every live owner-bound attachment exactly once.");n.add(t)}}function x(e,r,n){const t=Object.freeze([...n]),o=new Set;for(const a of t){if(h(a).owner!==e)throw new TypeError("Owner attachment plan contains an attachment from another owner.");if(o.has(a))throw new TypeError("Owner attachment plan contains the same attachment more than once.");o.add(a)}for(const a of r.ownedAttachments)if(!o.has(a))throw new TypeError("Owner attachment plan does not cover every live owner-bound attachment.");return t}function z(e,r,n){if(!e.ownedAttachments.has(n))return;const t=h(n);if(t.generation===r)return v(t.controller.diagnostics())?void 0:t}function I(e){return e.disposed||e.awaitingDrain}function S(e){return e.state==="closed"&&!e.activeIntent}function C(e,r,n){const t=h(n);if(t.owner!==e)throw new TypeError("Owner retirement contains an attachment from another owner.");if(t.generation!==r)throw new TypeError("Owner retirement attachment belongs to another generation.");t.controller.assertRetirable(r);const o=t.controller.diagnostics();if(I(o))throw new TypeError("Owner retirement attachment cannot join the coordinated logical fence.");if(S(o))throw new TypeError("Owner retirement attachment has no live physical generation to retire.");return t}function g(e,r,n){return n.map(t=>C(e,r,t))}function G(e,r){if(e.generation!==r)throw new TypeError("Owner-bound attachment changed generation during logical retirement.");return e.controller.retireExpected(r)}function P(e){if(e===void 0)throw new TypeError("Owner generation cannot complete with an unfenced attachment.");return e}function F(e,r,n){const t=n.handles.map(P);n.state.retirements=Object.freeze(t);for(const o of n.attachmentDefinitions)o.generation===n.generation&&(o.generation=void 0);return e.current=void 0,e.activeRetirement=void 0,e.completedRetirements.set(n.generation,{attachmentOrdinals:Object.freeze(n.attachmentDefinitions.map(o=>o.ordinal)),receipt:n.receipt}),r.ownedAttachments.clear(),n.receipt}function y(e,r,n){if(n.running)return n.receipt;n.running=!0;let t;try{for(const[o,a]of n.attachmentDefinitions.entries())if(n.handles[o]===void 0)try{n.handles[o]=G(a,n.generation)}catch(i){(t??(t=[])).push(i)}if(t!==void 0)throw r.phase="retire-failed",D(t,`Owner generation ${e.ownerId} failed its logical retirement.`);return F(e,r,n)}finally{n.running=!1}}function W(e,r,n){const t=e.completedRetirements.get(r);if(t!==void 0){if(!p(e,t,n))throw new TypeError("Repeated owner retirement must use the same exact attachment set and order.");return t.receipt}}function L(e,r,n){const t=e.activeRetirement;if((t==null?void 0:t.generation)!==r)return;if(!A(t.attachments,n))throw new TypeError("Repeated owner retirement must use the same exact attachment set and order.");const o=e.current;if(o===void 0)throw new TypeError("Owner retirement lost its current generation.");return y(e,o,t)}function O(e,r){if(r.phase!=="opening"&&r.phase!=="ready")throw new TypeError(`Owner generation ${e.ownerId} cannot retire while ${r.phase}.`)}function $(e,r,n){const t=e.sourceSnapshot.kind==="ready";return t&&k(e,Object.freeze({kind:"inactive",reason:n,revision:e.sourceSnapshot.revision+1})),b(r.state.abort,n),t}function w(e,r,n){const t=u(e),o=W(t,r,n);if(o!==void 0)return o;const a=L(t,r,n);if(a!==void 0)return a;const i=l(t,r);O(t,i),j(i,n);const s=Object.freeze([...n]),m=g(t,r,s),d={retirements:void 0},c={attachmentDefinitions:m,attachments:s,generation:r,handles:Array.from({length:s.length}),receipt:R(d),running:!0,state:d};t.activeRetirement=c,i.phase="retiring",i.state.active=!1;const f=new E("retired",t.ownerId);return $(t,i,f)&&T(t),c.running=!1,y(t,i,c)}function H(e,r,n){var d;const t=u(e),o=l(t,r),a=x(t,o,n),i=new Map;for(const c of a){const f=z(o,r,c);f!==void 0&&i.set(c,f)}const s=Object.freeze(a.filter(c=>o.ownedAttachments.has(c)&&!i.has(c)));if(((d=t.activeRetirement)==null?void 0:d.generation)===r){const c=w(e,r,s);return Object.freeze({attachments:s,retirement:c})}O(t,o),g(t,r,s);for(const[c,f]of i)f.generation=void 0,o.ownedAttachments.delete(c);const m=w(e,r,s);return Object.freeze({attachments:s,retirement:m})}function J(e,r,n,t){const o=e.completedRetirements.get(r);if(o===void 0||o.receipt!==t||!p(e,o,n))throw new TypeError("Owner drain acknowledgement is foreign, stale or does not match its exact attachment set.");return o}function M(e){const r=e.generation;if(r===void 0)return!1;const n=e.controller.diagnostics();return n.state!=="ready"||n.activeIntent||n.awaitingDrain?!1:(e.controller.assertRetirable(r),!0)}function N(e){const r=h(e);if(M(r))return;const n=r.controller.diagnostics();if(n.activeIntent||n.awaitingDrain||n.state!=="closed")throw new TypeError("Owner drain acknowledgement arrived before every retired attachment became workspace.")}function B(e,r,n,t){const o=u(e);J(o,r,n,t),n.forEach(N),o.completedRetirements.delete(r)}export{B as acknowledgeOwnerGenerationDrain,w as retireOwnedGeneration,H as retirePlannedOwnerGeneration};
2
+ //# sourceMappingURL=owner-generation-retirement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-generation-retirement.js","sources":["../src/owner-generation-retirement.ts"],"sourcesContent":["import { FeatureError } from '@opetope/core';\nimport { abortWithReason, createAggregateError } from '@opetope/core/internal';\nimport type { AttachmentLifecycleController, AttachmentRetirement } from '@opetope/core/internal';\n\nimport {\n assertCurrentGeneration,\n flushPublications,\n getAttachmentDefinition,\n getControllerDefinition,\n makeRetirementReceipt,\n physicalGenerationIsOccupied,\n sameAttachments,\n sameCompletedAttachments,\n stageSourceSnapshot,\n} from './owner-generation-state';\nimport type {\n ActiveRetirement,\n CompletedRetirement,\n CurrentGeneration,\n OwnerBoundAttachmentDefinition,\n OwnerBoundAttachmentIdentity,\n OwnerGeneration,\n OwnerGenerationController,\n OwnerGenerationDefinition,\n OwnerGenerationPlanRetirement,\n OwnerGenerationRetirement,\n RetirementState,\n} from './owner-generation-state';\n\nfunction assertCompleteOwnership(\n current: CurrentGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): void {\n if (attachments.length !== current.ownedAttachments.size) {\n throw new TypeError('Owner retirement must contain every live owner-bound attachment exactly once.');\n }\n\n const seen = new Set<OwnerBoundAttachmentIdentity>();\n\n for (const attachment of attachments) {\n if (seen.has(attachment) || !current.ownedAttachments.has(attachment)) {\n throw new TypeError('Owner retirement must contain every live owner-bound attachment exactly once.');\n }\n\n seen.add(attachment);\n }\n}\n\nfunction validateCompleteOwnerAttachmentPlan(\n definition: OwnerGenerationDefinition,\n current: CurrentGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): readonly OwnerBoundAttachmentIdentity[] {\n const plan = Object.freeze([...attachments]);\n const seen = new Set<OwnerBoundAttachmentIdentity>();\n\n for (const attachment of plan) {\n const attachmentDefinition = getAttachmentDefinition(attachment);\n\n if (attachmentDefinition.owner !== definition) {\n throw new TypeError('Owner attachment plan contains an attachment from another owner.');\n }\n\n if (seen.has(attachment)) {\n throw new TypeError('Owner attachment plan contains the same attachment more than once.');\n }\n\n seen.add(attachment);\n }\n\n for (const attachment of current.ownedAttachments) {\n if (!seen.has(attachment)) {\n throw new TypeError('Owner attachment plan does not cover every live owner-bound attachment.');\n }\n }\n\n return plan;\n}\n\n/**\n * Terminality is decided once: the plan pass keeps the definition it proved workspace, so the reconciliation pass\n * clears it instead of re-deriving the same predicate (D165).\n */\nfunction workspacePlanAttachmentDefinition(\n current: CurrentGeneration,\n generation: OwnerGeneration,\n attachment: OwnerBoundAttachmentIdentity,\n): OwnerBoundAttachmentDefinition<unknown> | undefined {\n if (!current.ownedAttachments.has(attachment)) return undefined;\n\n const definition = getAttachmentDefinition(attachment);\n\n if (definition.generation !== generation) return undefined;\n\n return physicalGenerationIsOccupied(definition.controller.diagnostics()) ? undefined : definition;\n}\n\n/**\n * A closing attachment joins the fence instead of refusing it: its drain is already running, the coordinated\n * retirement waits for it and reports its outcome, so one member in rollback no longer costs its siblings their\n * Close.\n */\nfunction attachmentCannotJoinFence(\n diagnostics: ReturnType<AttachmentLifecycleController<object, unknown>['diagnostics']>,\n): boolean {\n return diagnostics.disposed || diagnostics.awaitingDrain;\n}\n\nfunction attachmentHasNoLiveGeneration(\n diagnostics: ReturnType<AttachmentLifecycleController<object, unknown>['diagnostics']>,\n): boolean {\n return diagnostics.state === 'closed' && !diagnostics.activeIntent;\n}\n\nfunction preflightOwnedAttachment(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n attachment: OwnerBoundAttachmentIdentity,\n): OwnerBoundAttachmentDefinition<unknown> {\n const attachmentDefinition = getAttachmentDefinition(attachment);\n\n if (attachmentDefinition.owner !== definition) {\n throw new TypeError('Owner retirement contains an attachment from another owner.');\n }\n\n if (attachmentDefinition.generation !== generation) {\n throw new TypeError('Owner retirement attachment belongs to another generation.');\n }\n\n attachmentDefinition.controller.assertRetirable(generation);\n const diagnostics = attachmentDefinition.controller.diagnostics();\n\n if (attachmentCannotJoinFence(diagnostics)) {\n throw new TypeError('Owner retirement attachment cannot join the coordinated logical fence.');\n }\n\n if (attachmentHasNoLiveGeneration(diagnostics)) {\n throw new TypeError('Owner retirement attachment has no live physical generation to retire.');\n }\n\n return attachmentDefinition;\n}\n\nfunction preflightOwnedAttachments(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): readonly OwnerBoundAttachmentDefinition<unknown>[] {\n return attachments.map(attachment => preflightOwnedAttachment(definition, generation, attachment));\n}\n\nfunction retireExpected(\n definition: OwnerBoundAttachmentDefinition<unknown>,\n generation: OwnerGeneration,\n): AttachmentRetirement {\n if (definition.generation !== generation) {\n throw new TypeError('Owner-bound attachment changed generation during logical retirement.');\n }\n\n return definition.controller.retireExpected(generation);\n}\n\nfunction requireAttachmentRetirement(retirement: AttachmentRetirement | undefined): AttachmentRetirement {\n if (retirement === undefined) throw new TypeError('Owner generation cannot complete with an unfenced attachment.');\n\n return retirement;\n}\n\nfunction completeLogicalRetirement(\n definition: OwnerGenerationDefinition,\n current: CurrentGeneration,\n activeRetirement: ActiveRetirement,\n): OwnerGenerationRetirement {\n const retirements = activeRetirement.handles.map(requireAttachmentRetirement);\n activeRetirement.state.retirements = Object.freeze(retirements);\n\n for (const attachmentDefinition of activeRetirement.attachmentDefinitions) {\n if (attachmentDefinition.generation === activeRetirement.generation) {\n attachmentDefinition.generation = undefined;\n }\n }\n\n definition.current = undefined;\n definition.activeRetirement = undefined;\n definition.completedRetirements.set(activeRetirement.generation, {\n attachmentOrdinals: Object.freeze(activeRetirement.attachmentDefinitions.map(attachment => attachment.ordinal)),\n receipt: activeRetirement.receipt,\n });\n current.ownedAttachments.clear();\n\n return activeRetirement.receipt;\n}\n\nfunction driveLogicalRetirement(\n definition: OwnerGenerationDefinition,\n current: CurrentGeneration,\n activeRetirement: ActiveRetirement,\n): OwnerGenerationRetirement {\n if (activeRetirement.running) return activeRetirement.receipt;\n\n activeRetirement.running = true;\n let failures: unknown[] | undefined;\n\n try {\n for (const [index, attachmentDefinition] of activeRetirement.attachmentDefinitions.entries()) {\n if (activeRetirement.handles[index] !== undefined) continue;\n\n try {\n activeRetirement.handles[index] = retireExpected(attachmentDefinition, activeRetirement.generation);\n } catch (error) {\n (failures ??= []).push(error);\n }\n }\n\n if (failures !== undefined) {\n current.phase = 'retire-failed';\n throw createAggregateError(failures, `Owner generation ${definition.ownerId} failed its logical retirement.`);\n }\n\n return completeLogicalRetirement(definition, current, activeRetirement);\n } finally {\n activeRetirement.running = false;\n }\n}\n\nfunction completedRetirementFor(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): OwnerGenerationRetirement | undefined {\n const completed = definition.completedRetirements.get(generation);\n\n if (completed === undefined) return undefined;\n\n if (!sameCompletedAttachments(definition, completed, attachments)) {\n throw new TypeError('Repeated owner retirement must use the same exact attachment set and order.');\n }\n\n return completed.receipt;\n}\n\nfunction activeRetirementFor(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): OwnerGenerationRetirement | undefined {\n const active = definition.activeRetirement;\n\n if (active?.generation !== generation) return undefined;\n\n if (!sameAttachments(active.attachments, attachments)) {\n throw new TypeError('Repeated owner retirement must use the same exact attachment set and order.');\n }\n\n const current = definition.current;\n\n if (current === undefined) throw new TypeError('Owner retirement lost its current generation.');\n\n return driveLogicalRetirement(definition, current, active);\n}\n\nfunction assertRetirementPhase(definition: OwnerGenerationDefinition, current: CurrentGeneration): void {\n if (current.phase !== 'opening' && current.phase !== 'ready') {\n throw new TypeError(`Owner generation ${definition.ownerId} cannot retire while ${current.phase}.`);\n }\n}\n\nfunction stageOwnerInactive(\n definition: OwnerGenerationDefinition,\n current: CurrentGeneration,\n reason: FeatureError,\n): boolean {\n const sourceWasReady = definition.sourceSnapshot.kind === 'ready';\n\n if (sourceWasReady) {\n stageSourceSnapshot(\n definition,\n Object.freeze({\n kind: 'inactive' as const,\n reason,\n revision: definition.sourceSnapshot.revision + 1,\n }),\n );\n }\n\n abortWithReason(current.state.abort, reason);\n\n return sourceWasReady;\n}\n\nfunction retireOwnedGeneration(\n controller: OwnerGenerationController,\n generation: OwnerGeneration,\n requestedAttachments: readonly OwnerBoundAttachmentIdentity[],\n): OwnerGenerationRetirement {\n const definition = getControllerDefinition(controller);\n const completed = completedRetirementFor(definition, generation, requestedAttachments);\n\n if (completed !== undefined) return completed;\n\n const joined = activeRetirementFor(definition, generation, requestedAttachments);\n\n if (joined !== undefined) return joined;\n\n const current = assertCurrentGeneration(definition, generation);\n assertRetirementPhase(definition, current);\n assertCompleteOwnership(current, requestedAttachments);\n const attachments = Object.freeze([...requestedAttachments]);\n const attachmentDefinitions = preflightOwnedAttachments(definition, generation, attachments);\n const retirementState: RetirementState = { retirements: undefined };\n const activeRetirement: ActiveRetirement = {\n attachmentDefinitions,\n attachments,\n generation,\n handles: Array.from({ length: attachments.length }),\n receipt: makeRetirementReceipt(retirementState),\n running: true,\n state: retirementState,\n };\n definition.activeRetirement = activeRetirement;\n current.phase = 'retiring';\n current.state.active = false;\n const inactiveReason = new FeatureError('retired', definition.ownerId);\n const sourceWasReady = stageOwnerInactive(definition, current, inactiveReason);\n\n if (sourceWasReady) flushPublications(definition);\n\n activeRetirement.running = false;\n\n return driveLogicalRetirement(definition, current, activeRetirement);\n}\n\n/** Package-private C4c seam; intentionally absent from `./internal`. */\nfunction retirePlannedOwnerGeneration(\n controller: OwnerGenerationController,\n generation: OwnerGeneration,\n requestedPlan: readonly OwnerBoundAttachmentIdentity[],\n): OwnerGenerationPlanRetirement {\n const definition = getControllerDefinition(controller);\n const current = assertCurrentGeneration(definition, generation);\n const plan = validateCompleteOwnerAttachmentPlan(definition, current, requestedPlan);\n const workspaceAttachments = new Map<OwnerBoundAttachmentIdentity, OwnerBoundAttachmentDefinition<unknown>>();\n\n for (const attachment of plan) {\n const workspace = workspacePlanAttachmentDefinition(current, generation, attachment);\n\n if (workspace !== undefined) workspaceAttachments.set(attachment, workspace);\n }\n\n const attachments = Object.freeze(\n plan.filter(attachment => current.ownedAttachments.has(attachment) && !workspaceAttachments.has(attachment)),\n );\n\n if (definition.activeRetirement?.generation === generation) {\n const retirement = retireOwnedGeneration(controller, generation, attachments);\n\n return Object.freeze({ attachments, retirement });\n }\n\n assertRetirementPhase(definition, current);\n preflightOwnedAttachments(definition, generation, attachments);\n\n for (const [attachment, workspace] of workspaceAttachments) {\n workspace.generation = undefined;\n current.ownedAttachments.delete(attachment);\n }\n\n const retirement = retireOwnedGeneration(controller, generation, attachments);\n\n return Object.freeze({ attachments, retirement });\n}\n\nfunction completedDrainAcknowledgement(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n receipt: OwnerGenerationRetirement,\n): CompletedRetirement {\n const completed = definition.completedRetirements.get(generation);\n\n if (\n completed === undefined ||\n completed.receipt !== receipt ||\n !sameCompletedAttachments(definition, completed, attachments)\n ) {\n throw new TypeError('Owner drain acknowledgement is foreign, stale or does not match its exact attachment set.');\n }\n\n return completed;\n}\n\nfunction hasReadyReplacement(definition: OwnerBoundAttachmentDefinition<unknown>): boolean {\n const generation = definition.generation;\n\n if (generation === undefined) return false;\n\n const diagnostics = definition.controller.diagnostics();\n\n if (diagnostics.state !== 'ready' || diagnostics.activeIntent || diagnostics.awaitingDrain) return false;\n\n definition.controller.assertRetirable(generation);\n\n return true;\n}\n\nfunction assertAttachmentDrainTerminal(attachment: OwnerBoundAttachmentIdentity): void {\n const definition = getAttachmentDefinition(attachment);\n\n if (hasReadyReplacement(definition)) return;\n\n const diagnostics = definition.controller.diagnostics();\n\n if (diagnostics.activeIntent || diagnostics.awaitingDrain || diagnostics.state !== 'closed') {\n throw new TypeError('Owner drain acknowledgement arrived before every retired attachment became workspace.');\n }\n}\n\nfunction acknowledgeOwnerGenerationDrain(\n controller: OwnerGenerationController,\n generation: OwnerGeneration,\n requestedAttachments: readonly OwnerBoundAttachmentIdentity[],\n receipt: OwnerGenerationRetirement,\n): void {\n const definition = getControllerDefinition(controller);\n completedDrainAcknowledgement(definition, generation, requestedAttachments, receipt);\n requestedAttachments.forEach(assertAttachmentDrainTerminal);\n\n definition.completedRetirements.delete(generation);\n}\n\nexport { acknowledgeOwnerGenerationDrain, retireOwnedGeneration, retirePlannedOwnerGeneration };\n"],"names":["assertCompleteOwnership","current","attachments","seen","attachment","validateCompleteOwnerAttachmentPlan","definition","plan","getAttachmentDefinition","workspacePlanAttachmentDefinition","generation","physicalGenerationIsOccupied","attachmentCannotJoinFence","diagnostics","attachmentHasNoLiveGeneration","preflightOwnedAttachment","attachmentDefinition","preflightOwnedAttachments","retireExpected","requireAttachmentRetirement","retirement","completeLogicalRetirement","activeRetirement","retirements","driveLogicalRetirement","failures","index","error","createAggregateError","completedRetirementFor","completed","sameCompletedAttachments","activeRetirementFor","active","sameAttachments","assertRetirementPhase","stageOwnerInactive","reason","sourceWasReady","stageSourceSnapshot","abortWithReason","retireOwnedGeneration","controller","requestedAttachments","getControllerDefinition","joined","assertCurrentGeneration","attachmentDefinitions","retirementState","makeRetirementReceipt","inactiveReason","FeatureError","flushPublications","retirePlannedOwnerGeneration","requestedPlan","workspaceAttachments","workspace","_a","completedDrainAcknowledgement","receipt","hasReadyReplacement","assertAttachmentDrainTerminal","acknowledgeOwnerGenerationDrain"],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import type { DeclarationId, Readable } from '@opetope/core';
2
+ import type { AttachmentLifecycleController, AttachmentReadinessRef, AttachmentRetirement, CallAuthority, CallAuthoritySource, CallAuthoritySourceEvent, CallAuthoritySourceSnapshot } from '@opetope/core/internal';
3
+ declare const ownerBoundAttachmentBrand: unique symbol;
4
+ declare const ownerBoundAttachmentValueBrand: unique symbol;
5
+ declare const ownerGenerationBrand: unique symbol;
6
+ declare const ownerGenerationControllerBrand: unique symbol;
7
+ declare const ownerGenerationRefBrand: unique symbol;
8
+ declare const ownerGenerationRetirementBrand: unique symbol;
9
+ type PublicListenerRegistration = {
10
+ readonly listener: () => void;
11
+ };
12
+ type SourceListenerRegistration = {
13
+ readonly listener: (event: CallAuthoritySourceEvent) => void;
14
+ };
15
+ type OwnerGenerationSnapshot = {
16
+ readonly kind: 'inactive';
17
+ } | {
18
+ readonly kind: 'ready';
19
+ };
20
+ interface OwnerGenerationRef extends Readable<OwnerGenerationSnapshot> {
21
+ readonly id: DeclarationId;
22
+ readonly [ownerGenerationRefBrand]: true;
23
+ }
24
+ interface OwnerGeneration extends CallAuthority {
25
+ readonly [ownerGenerationBrand]: true;
26
+ readonly signal: AbortSignal;
27
+ }
28
+ interface OwnerGenerationController {
29
+ readonly begin: () => OwnerGeneration;
30
+ readonly commit: (generation: OwnerGeneration) => void;
31
+ readonly [ownerGenerationControllerBrand]: true;
32
+ readonly ref: OwnerGenerationRef;
33
+ }
34
+ interface OwnerBoundAttachmentIdentity {
35
+ readonly [ownerBoundAttachmentBrand]: true;
36
+ readonly readiness: AttachmentReadinessRef;
37
+ }
38
+ interface OwnerBoundAttachment<Value> extends OwnerBoundAttachmentIdentity {
39
+ readonly [ownerBoundAttachmentValueBrand]: (_value: Value) => Value;
40
+ }
41
+ interface OwnerGenerationRetirement {
42
+ readonly [ownerGenerationRetirementBrand]: true;
43
+ readonly retirements: readonly AttachmentRetirement[];
44
+ }
45
+ interface OwnerGenerationPlanRetirement {
46
+ readonly attachments: readonly OwnerBoundAttachmentIdentity[];
47
+ readonly retirement: OwnerGenerationRetirement;
48
+ }
49
+ type GenerationState = {
50
+ readonly abort: AbortController;
51
+ active: boolean;
52
+ committed: boolean;
53
+ };
54
+ type CurrentGeneration = {
55
+ readonly generation: OwnerGeneration;
56
+ readonly ownedAttachments: Set<OwnerBoundAttachmentIdentity>;
57
+ phase: 'opening' | 'ready' | 'retire-failed' | 'retiring';
58
+ readonly state: GenerationState;
59
+ };
60
+ type RetirementState = {
61
+ retirements: readonly AttachmentRetirement[] | undefined;
62
+ };
63
+ type ActiveRetirement = {
64
+ readonly attachmentDefinitions: readonly OwnerBoundAttachmentDefinition<unknown>[];
65
+ readonly attachments: readonly OwnerBoundAttachmentIdentity[];
66
+ readonly generation: OwnerGeneration;
67
+ readonly handles: (AttachmentRetirement | undefined)[];
68
+ readonly receipt: OwnerGenerationRetirement;
69
+ running: boolean;
70
+ readonly state: RetirementState;
71
+ };
72
+ type CompletedRetirement = {
73
+ readonly attachmentOrdinals: readonly number[];
74
+ readonly receipt: OwnerGenerationRetirement;
75
+ };
76
+ type OwnerGenerationDefinition = {
77
+ activeRetirement: ActiveRetirement | undefined;
78
+ readonly completedRetirements: WeakMap<OwnerGeneration, CompletedRetirement>;
79
+ current: CurrentGeneration | undefined;
80
+ nextAttachmentOrdinal: number;
81
+ readonly ownerId: DeclarationId;
82
+ readonly pendingSourceEvents: CallAuthoritySourceEvent[];
83
+ readonly publicListeners: Set<PublicListenerRegistration>;
84
+ publishing: boolean;
85
+ readonly sourceListeners: Set<SourceListenerRegistration>;
86
+ sourceSnapshot: CallAuthoritySourceSnapshot;
87
+ };
88
+ type OwnerBoundAttachmentDefinition<Value> = {
89
+ readonly controller: AttachmentLifecycleController<OwnerGeneration, Value>;
90
+ generation: OwnerGeneration | undefined;
91
+ readonly ordinal: number;
92
+ readonly owner: OwnerGenerationDefinition;
93
+ };
94
+ declare const inactiveSnapshot: Readonly<{
95
+ kind: "inactive";
96
+ }>;
97
+ declare const readySnapshot: Readonly<{
98
+ kind: "ready";
99
+ }>;
100
+ declare const controllerDefinitions: WeakMap<OwnerGenerationController, OwnerGenerationDefinition>;
101
+ declare const ownerDefinitions: WeakMap<OwnerGenerationRef, OwnerGenerationDefinition>;
102
+ declare const ownerSources: WeakMap<OwnerGenerationController, CallAuthoritySource>;
103
+ declare const attachmentDefinitions: WeakMap<OwnerBoundAttachmentIdentity, OwnerBoundAttachmentDefinition<unknown>>;
104
+ declare const controllerBindings: WeakMap<object, OwnerBoundAttachmentIdentity>;
105
+ declare function subscribePublic(definition: OwnerGenerationDefinition, listener: () => void): () => void;
106
+ declare function subscribeSource(definition: OwnerGenerationDefinition, listener: (event: CallAuthoritySourceEvent) => void): () => void;
107
+ declare function flushPublications(definition: OwnerGenerationDefinition): void;
108
+ declare function stageSourceSnapshot(definition: OwnerGenerationDefinition, next: CallAuthoritySourceSnapshot): void;
109
+ declare function publishSourceSnapshot(definition: OwnerGenerationDefinition, next: CallAuthoritySourceSnapshot): void;
110
+ declare function getControllerDefinition(controller: OwnerGenerationController): OwnerGenerationDefinition;
111
+ declare function getTypedAttachmentDefinition<Value>(attachment: OwnerBoundAttachment<Value>): OwnerBoundAttachmentDefinition<Value>;
112
+ declare function getAttachmentDefinition(attachment: OwnerBoundAttachmentIdentity): OwnerBoundAttachmentDefinition<unknown>;
113
+ declare function assertCurrentGeneration(definition: OwnerGenerationDefinition, generation: OwnerGeneration): CurrentGeneration;
114
+ declare function makeGeneration(ownerId: DeclarationId): {
115
+ readonly generation: OwnerGeneration;
116
+ readonly state: GenerationState;
117
+ };
118
+ declare function makeRetirementReceipt(state: RetirementState): OwnerGenerationRetirement;
119
+ declare function sameAttachments(left: readonly OwnerBoundAttachmentIdentity[], right: readonly OwnerBoundAttachmentIdentity[]): boolean;
120
+ declare function sameCompletedAttachments(definition: OwnerGenerationDefinition, completed: CompletedRetirement, attachments: readonly OwnerBoundAttachmentIdentity[]): boolean;
121
+ declare function physicalGenerationIsOccupied(diagnostics: ReturnType<AttachmentLifecycleController<object, unknown>['diagnostics']>): boolean;
122
+ export { assertCurrentGeneration, attachmentDefinitions, controllerBindings, controllerDefinitions, flushPublications, getAttachmentDefinition, getControllerDefinition, getTypedAttachmentDefinition, inactiveSnapshot, makeGeneration, makeRetirementReceipt, ownerBoundAttachmentBrand, ownerDefinitions, ownerGenerationControllerBrand, ownerGenerationRefBrand, ownerSources, physicalGenerationIsOccupied, publishSourceSnapshot, readySnapshot, sameAttachments, sameCompletedAttachments, stageSourceSnapshot, subscribePublic, subscribeSource, };
123
+ export type { ActiveRetirement, CompletedRetirement, CurrentGeneration, OwnerBoundAttachment, OwnerBoundAttachmentDefinition, OwnerBoundAttachmentIdentity, OwnerGeneration, OwnerGenerationController, OwnerGenerationDefinition, OwnerGenerationPlanRetirement, OwnerGenerationRef, OwnerGenerationRetirement, OwnerGenerationSnapshot, PublicListenerRegistration, RetirementState, SourceListenerRegistration, };
@@ -0,0 +1,2 @@
1
+ import{FeatureError as h}from"@opetope/core";import{reportDetachedError as s}from"@opetope/core/internal";const w=Symbol("opetope.owner-bound-attachment"),d=Symbol("opetope.owner-generation"),g=Symbol("opetope.owner-generation-controller"),m=Symbol("opetope.owner-generation-ref"),b=Symbol("opetope.owner-generation-retirement"),v=Object.freeze({kind:"inactive"}),S=Object.freeze({kind:"ready"}),c=new WeakMap,a=new WeakMap,y=new WeakMap,E=new WeakMap,o=new WeakMap,O=new WeakMap;function k(e,n){const t={listener:n};e.publicListeners.add(t);let r=!0;return()=>{r&&(r=!1,e.publicListeners.delete(t))}}function D(e,n){const t={listener:n};e.sourceListeners.add(t);let r=!0;return()=>{r&&(r=!1,e.sourceListeners.delete(t))}}function B(e,n){for(const{listener:t}of[...e.sourceListeners])try{t(n)}catch(r){s(r)}}function A(e){let n=0;for(;n<e.pendingSourceEvents.length;){const t=e.pendingSourceEvents[n];n+=1,t!==void 0&&B(e,t)}e.pendingSourceEvents.length=0}function C(e){const n=e.sourceSnapshot.revision;for(const{listener:t}of[...e.publicListeners]){if(e.sourceSnapshot.revision!==n)break;try{t()}catch(r){s(r)}}}function u(e){if(!e.publishing){e.publishing=!0;try{for(;e.pendingSourceEvents.length>0;)A(e),C(e)}finally{e.publishing=!1}}}function l(e,n){const t=Object.freeze({current:n,previous:e.sourceSnapshot});e.sourceSnapshot=n,e.pendingSourceEvents.push(t)}function G(e,n){l(e,n),u(e)}function L(e){const n=c.get(e);if(n===void 0)throw new TypeError("OwnerGenerationController is not authentic.");return n}function M(e){const n=o.get(e);if(n===void 0)throw new TypeError("OwnerBoundAttachment is not authentic.");return n}function p(e){const n=o.get(e);if(n===void 0)throw new TypeError("OwnerBoundAttachment is not authentic.");return n}function R(e,n){const t=a.get(n),r=e.current;if(t===void 0||(r==null?void 0:r.generation)!==n||r.state!==t||!t.active)throw new TypeError(`Owner generation ${e.ownerId} is foreign, stale or inactive.`);return r}function T(e){const n={abort:new AbortController,active:!0,committed:!1},t=Object.freeze({assertCurrent(){if(!n.active||!n.committed)throw new h("retired",e)},isCurrent(){return n.active&&n.committed},[d]:!0,signal:n.abort.signal});return a.set(t,n),{generation:t,state:n}}function W(e){return Object.freeze({[b]:!0,get retirements(){const n=e.retirements;if(n===void 0)throw new TypeError("Owner generation logical retirement has not finished fencing every attachment.");return n}})}function j(e,n){return e.length!==n.length?!1:e.every((t,r)=>t===n[r])}function z(e,n,t){return n.attachmentOrdinals.length!==t.length?!1:t.every((r,f)=>{const i=p(r);return i.owner===e&&i.ordinal===n.attachmentOrdinals[f]})}function I(e){return e.activeIntent||e.awaitingDrain||e.state!=="closed"}export{R as assertCurrentGeneration,o as attachmentDefinitions,O as controllerBindings,c as controllerDefinitions,u as flushPublications,p as getAttachmentDefinition,L as getControllerDefinition,M as getTypedAttachmentDefinition,v as inactiveSnapshot,T as makeGeneration,W as makeRetirementReceipt,w as ownerBoundAttachmentBrand,y as ownerDefinitions,g as ownerGenerationControllerBrand,m as ownerGenerationRefBrand,E as ownerSources,I as physicalGenerationIsOccupied,G as publishSourceSnapshot,S as readySnapshot,j as sameAttachments,z as sameCompletedAttachments,l as stageSourceSnapshot,k as subscribePublic,D as subscribeSource};
2
+ //# sourceMappingURL=owner-generation-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-generation-state.js","sources":["../src/owner-generation-state.ts"],"sourcesContent":["import { FeatureError } from '@opetope/core';\nimport type { DeclarationId, Readable } from '@opetope/core';\nimport type {\n AttachmentLifecycleController,\n AttachmentReadinessRef,\n AttachmentRetirement,\n CallAuthority,\n CallAuthoritySource,\n CallAuthoritySourceEvent,\n CallAuthoritySourceSnapshot,\n} from '@opetope/core/internal';\nimport { reportDetachedError } from '@opetope/core/internal';\n\nconst ownerBoundAttachmentBrand = Symbol('opetope.owner-bound-attachment');\ndeclare const ownerBoundAttachmentValueBrand: unique symbol;\nconst ownerGenerationBrand = Symbol('opetope.owner-generation');\nconst ownerGenerationControllerBrand = Symbol('opetope.owner-generation-controller');\nconst ownerGenerationRefBrand = Symbol('opetope.owner-generation-ref');\nconst ownerGenerationRetirementBrand = Symbol('opetope.owner-generation-retirement');\n\ntype PublicListenerRegistration = { readonly listener: () => void };\ntype SourceListenerRegistration = { readonly listener: (event: CallAuthoritySourceEvent) => void };\n\ntype OwnerGenerationSnapshot = { readonly kind: 'inactive' } | { readonly kind: 'ready' };\n\ninterface OwnerGenerationRef extends Readable<OwnerGenerationSnapshot> {\n readonly id: DeclarationId;\n readonly [ownerGenerationRefBrand]: true;\n}\n\ninterface OwnerGeneration extends CallAuthority {\n readonly [ownerGenerationBrand]: true;\n readonly signal: AbortSignal;\n}\n\ninterface OwnerGenerationController {\n readonly begin: () => OwnerGeneration;\n readonly commit: (generation: OwnerGeneration) => void;\n readonly [ownerGenerationControllerBrand]: true;\n readonly ref: OwnerGenerationRef;\n}\n\ninterface OwnerBoundAttachmentIdentity {\n readonly [ownerBoundAttachmentBrand]: true;\n readonly readiness: AttachmentReadinessRef;\n}\n\ninterface OwnerBoundAttachment<Value> extends OwnerBoundAttachmentIdentity {\n readonly [ownerBoundAttachmentValueBrand]: (_value: Value) => Value;\n}\n\ninterface OwnerGenerationRetirement {\n readonly [ownerGenerationRetirementBrand]: true;\n readonly retirements: readonly AttachmentRetirement[];\n}\n\ninterface OwnerGenerationPlanRetirement {\n readonly attachments: readonly OwnerBoundAttachmentIdentity[];\n readonly retirement: OwnerGenerationRetirement;\n}\n\ntype GenerationState = {\n readonly abort: AbortController;\n active: boolean;\n committed: boolean;\n};\n\ntype CurrentGeneration = {\n readonly generation: OwnerGeneration;\n readonly ownedAttachments: Set<OwnerBoundAttachmentIdentity>;\n phase: 'opening' | 'ready' | 'retire-failed' | 'retiring';\n readonly state: GenerationState;\n};\n\ntype RetirementState = {\n retirements: readonly AttachmentRetirement[] | undefined;\n};\n\ntype ActiveRetirement = {\n readonly attachmentDefinitions: readonly OwnerBoundAttachmentDefinition<unknown>[];\n readonly attachments: readonly OwnerBoundAttachmentIdentity[];\n readonly generation: OwnerGeneration;\n readonly handles: (AttachmentRetirement | undefined)[];\n readonly receipt: OwnerGenerationRetirement;\n running: boolean;\n readonly state: RetirementState;\n};\n\ntype CompletedRetirement = {\n readonly attachmentOrdinals: readonly number[];\n readonly receipt: OwnerGenerationRetirement;\n};\n\ntype OwnerGenerationDefinition = {\n activeRetirement: ActiveRetirement | undefined;\n readonly completedRetirements: WeakMap<OwnerGeneration, CompletedRetirement>;\n current: CurrentGeneration | undefined;\n nextAttachmentOrdinal: number;\n readonly ownerId: DeclarationId;\n readonly pendingSourceEvents: CallAuthoritySourceEvent[];\n readonly publicListeners: Set<PublicListenerRegistration>;\n publishing: boolean;\n readonly sourceListeners: Set<SourceListenerRegistration>;\n sourceSnapshot: CallAuthoritySourceSnapshot;\n};\n\ntype OwnerBoundAttachmentDefinition<Value> = {\n readonly controller: AttachmentLifecycleController<OwnerGeneration, Value>;\n generation: OwnerGeneration | undefined;\n readonly ordinal: number;\n readonly owner: OwnerGenerationDefinition;\n};\n\nconst inactiveSnapshot = Object.freeze({ kind: 'inactive' as const });\nconst readySnapshot = Object.freeze({ kind: 'ready' as const });\nconst controllerDefinitions = new WeakMap<OwnerGenerationController, OwnerGenerationDefinition>();\nconst generationDefinitions = new WeakMap<OwnerGeneration, GenerationState>();\nconst ownerDefinitions = new WeakMap<OwnerGenerationRef, OwnerGenerationDefinition>();\nconst ownerSources = new WeakMap<OwnerGenerationController, CallAuthoritySource>();\nconst attachmentDefinitions = new WeakMap<OwnerBoundAttachmentIdentity, OwnerBoundAttachmentDefinition<unknown>>();\nconst controllerBindings = new WeakMap<object, OwnerBoundAttachmentIdentity>();\n\nfunction subscribePublic(definition: OwnerGenerationDefinition, listener: () => void): () => void {\n const registration = { listener };\n definition.publicListeners.add(registration);\n let subscribed = true;\n\n return (): void => {\n if (!subscribed) return;\n\n subscribed = false;\n definition.publicListeners.delete(registration);\n };\n}\n\nfunction subscribeSource(\n definition: OwnerGenerationDefinition,\n listener: (event: CallAuthoritySourceEvent) => void,\n): () => void {\n const registration = { listener };\n definition.sourceListeners.add(registration);\n let subscribed = true;\n\n return (): void => {\n if (!subscribed) return;\n\n subscribed = false;\n definition.sourceListeners.delete(registration);\n };\n}\n\nfunction publishSourceEvent(definition: OwnerGenerationDefinition, event: CallAuthoritySourceEvent): void {\n for (const { listener } of [...definition.sourceListeners]) {\n try {\n listener(event);\n } catch (error) {\n reportDetachedError(error);\n }\n }\n}\n\nfunction publishPendingSourceEvents(definition: OwnerGenerationDefinition): void {\n let pendingEventIndex = 0;\n\n while (pendingEventIndex < definition.pendingSourceEvents.length) {\n const event = definition.pendingSourceEvents[pendingEventIndex];\n pendingEventIndex += 1;\n\n if (event !== undefined) publishSourceEvent(definition, event);\n }\n\n definition.pendingSourceEvents.length = 0;\n}\n\nfunction publishPublicRevision(definition: OwnerGenerationDefinition): void {\n const publicRevision = definition.sourceSnapshot.revision;\n\n for (const { listener } of [...definition.publicListeners]) {\n if (definition.sourceSnapshot.revision !== publicRevision) break;\n\n try {\n listener();\n } catch (error) {\n reportDetachedError(error);\n }\n }\n}\n\nfunction flushPublications(definition: OwnerGenerationDefinition): void {\n if (definition.publishing) return;\n\n definition.publishing = true;\n\n try {\n while (definition.pendingSourceEvents.length > 0) {\n publishPendingSourceEvents(definition);\n publishPublicRevision(definition);\n }\n } finally {\n definition.publishing = false;\n }\n}\n\nfunction stageSourceSnapshot(definition: OwnerGenerationDefinition, next: CallAuthoritySourceSnapshot): void {\n const event = Object.freeze({ current: next, previous: definition.sourceSnapshot });\n definition.sourceSnapshot = next;\n definition.pendingSourceEvents.push(event);\n}\n\nfunction publishSourceSnapshot(definition: OwnerGenerationDefinition, next: CallAuthoritySourceSnapshot): void {\n stageSourceSnapshot(definition, next);\n flushPublications(definition);\n}\n\nfunction getControllerDefinition(controller: OwnerGenerationController): OwnerGenerationDefinition {\n const definition = controllerDefinitions.get(controller);\n\n if (definition === undefined) throw new TypeError('OwnerGenerationController is not authentic.');\n\n return definition;\n}\n\nfunction getTypedAttachmentDefinition<Value>(\n attachment: OwnerBoundAttachment<Value>,\n): OwnerBoundAttachmentDefinition<Value> {\n const definition = attachmentDefinitions.get(attachment);\n\n if (definition === undefined) throw new TypeError('OwnerBoundAttachment is not authentic.');\n\n return definition;\n}\n\nfunction getAttachmentDefinition(attachment: OwnerBoundAttachmentIdentity): OwnerBoundAttachmentDefinition<unknown> {\n const definition = attachmentDefinitions.get(attachment);\n\n if (definition === undefined) throw new TypeError('OwnerBoundAttachment is not authentic.');\n\n return definition;\n}\n\nfunction assertCurrentGeneration(\n definition: OwnerGenerationDefinition,\n generation: OwnerGeneration,\n): CurrentGeneration {\n const state = generationDefinitions.get(generation);\n const current = definition.current;\n\n if (state === undefined || current?.generation !== generation || current.state !== state || !state.active) {\n throw new TypeError(`Owner generation ${definition.ownerId} is foreign, stale or inactive.`);\n }\n\n return current;\n}\n\nfunction makeGeneration(ownerId: DeclarationId): {\n readonly generation: OwnerGeneration;\n readonly state: GenerationState;\n} {\n const state: GenerationState = { abort: new AbortController(), active: true, committed: false };\n const generation = Object.freeze({\n assertCurrent(): void {\n if (!state.active || !state.committed) throw new FeatureError('retired', ownerId);\n },\n isCurrent(): boolean {\n return state.active && state.committed;\n },\n [ownerGenerationBrand]: true as const,\n signal: state.abort.signal,\n });\n generationDefinitions.set(generation, state);\n\n return { generation, state };\n}\n\nfunction makeRetirementReceipt(state: RetirementState): OwnerGenerationRetirement {\n return Object.freeze({\n [ownerGenerationRetirementBrand]: true as const,\n get retirements(): readonly AttachmentRetirement[] {\n const retirements = state.retirements;\n\n if (retirements === undefined) {\n throw new TypeError('Owner generation logical retirement has not finished fencing every attachment.');\n }\n\n return retirements;\n },\n });\n}\n\nfunction sameAttachments(\n left: readonly OwnerBoundAttachmentIdentity[],\n right: readonly OwnerBoundAttachmentIdentity[],\n): boolean {\n if (left.length !== right.length) return false;\n\n return left.every((attachment, index) => attachment === right[index]);\n}\n\nfunction sameCompletedAttachments(\n definition: OwnerGenerationDefinition,\n completed: CompletedRetirement,\n attachments: readonly OwnerBoundAttachmentIdentity[],\n): boolean {\n if (completed.attachmentOrdinals.length !== attachments.length) return false;\n\n return attachments.every((attachment, index) => {\n const attachmentDefinition = getAttachmentDefinition(attachment);\n\n return (\n attachmentDefinition.owner === definition && attachmentDefinition.ordinal === completed.attachmentOrdinals[index]\n );\n });\n}\n\nfunction physicalGenerationIsOccupied(\n diagnostics: ReturnType<AttachmentLifecycleController<object, unknown>['diagnostics']>,\n): boolean {\n return diagnostics.activeIntent || diagnostics.awaitingDrain || diagnostics.state !== 'closed';\n}\n\nexport {\n assertCurrentGeneration,\n attachmentDefinitions,\n controllerBindings,\n controllerDefinitions,\n flushPublications,\n getAttachmentDefinition,\n getControllerDefinition,\n getTypedAttachmentDefinition,\n inactiveSnapshot,\n makeGeneration,\n makeRetirementReceipt,\n ownerBoundAttachmentBrand,\n ownerDefinitions,\n ownerGenerationControllerBrand,\n ownerGenerationRefBrand,\n ownerSources,\n physicalGenerationIsOccupied,\n publishSourceSnapshot,\n readySnapshot,\n sameAttachments,\n sameCompletedAttachments,\n stageSourceSnapshot,\n subscribePublic,\n subscribeSource,\n};\nexport type {\n ActiveRetirement,\n CompletedRetirement,\n CurrentGeneration,\n OwnerBoundAttachment,\n OwnerBoundAttachmentDefinition,\n OwnerBoundAttachmentIdentity,\n OwnerGeneration,\n OwnerGenerationController,\n OwnerGenerationDefinition,\n OwnerGenerationPlanRetirement,\n OwnerGenerationRef,\n OwnerGenerationRetirement,\n OwnerGenerationSnapshot,\n PublicListenerRegistration,\n RetirementState,\n SourceListenerRegistration,\n};\n"],"names":["ownerBoundAttachmentBrand","ownerGenerationBrand","ownerGenerationControllerBrand","ownerGenerationRefBrand","ownerGenerationRetirementBrand","inactiveSnapshot","readySnapshot","controllerDefinitions","generationDefinitions","ownerDefinitions","ownerSources","attachmentDefinitions","controllerBindings","subscribePublic","definition","listener","registration","subscribed","subscribeSource","publishSourceEvent","event","error","reportDetachedError","publishPendingSourceEvents","pendingEventIndex","publishPublicRevision","publicRevision","flushPublications","stageSourceSnapshot","next","publishSourceSnapshot","getControllerDefinition","controller","getTypedAttachmentDefinition","attachment","getAttachmentDefinition","assertCurrentGeneration","generation","state","current","makeGeneration","ownerId","FeatureError","makeRetirementReceipt","retirements","sameAttachments","left","right","index","sameCompletedAttachments","completed","attachments","attachmentDefinition","physicalGenerationIsOccupied","diagnostics"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AttachmentIntentOutcome, AttachmentLifecycleController, AttachmentRetryOutcome, CallAuthoritySource } from '@opetope/core/internal';
2
+ import type { OwnerBoundAttachment, OwnerGeneration, OwnerGenerationController, OwnerGenerationRef } from './owner-generation-state.js';
3
+ declare function createOwnerGenerationSlot(options: {
4
+ readonly id: string;
5
+ }): OwnerGenerationController;
6
+ /**
7
+ * Package-private source used by later runtime lowering; intentionally absent from `./internal`. A controller that is
8
+ * not authentic has no source either, so one lookup proves both (D165).
9
+ */
10
+ declare function getOwnerGenerationAuthoritySource(controller: OwnerGenerationController): CallAuthoritySource;
11
+ declare function bindAttachmentLifecycleToOwner<Value>(owner: OwnerGenerationRef, controller: AttachmentLifecycleController<OwnerGeneration, Value>): OwnerBoundAttachment<Value>;
12
+ declare function openOwnerBoundAttachment<Value>(attachment: OwnerBoundAttachment<Value>, generation: OwnerGeneration, value: Value): Promise<AttachmentIntentOutcome>;
13
+ declare function retryOwnerBoundAttachmentClose<Value>(attachment: OwnerBoundAttachment<Value>): Promise<AttachmentRetryOutcome>;
14
+ export { acknowledgeOwnerGenerationDrain, retireOwnedGeneration, retirePlannedOwnerGeneration, } from './owner-generation-retirement.js';
15
+ export { bindAttachmentLifecycleToOwner, createOwnerGenerationSlot, getOwnerGenerationAuthoritySource, openOwnerBoundAttachment, retryOwnerBoundAttachmentClose, };
16
+ export type { OwnerBoundAttachment, OwnerGeneration, OwnerGenerationController, OwnerGenerationPlanRetirement, OwnerGenerationRef, OwnerGenerationRetirement, OwnerGenerationSnapshot, } from './owner-generation-state.js';
@@ -0,0 +1,2 @@
1
+ import{declarationId as y,FeatureError as O}from"@opetope/core";import{reportDetachedError as b}from"@opetope/core/internal";import{ownerDefinitions as h,controllerBindings as l,getAttachmentDefinition as S,ownerBoundAttachmentBrand as A,attachmentDefinitions as v,controllerDefinitions as E,ownerSources as w,getTypedAttachmentDefinition as p,assertCurrentGeneration as g,ownerGenerationControllerBrand as G,publishSourceSnapshot as R,makeGeneration as k,subscribePublic as C,ownerGenerationRefBrand as D,readySnapshot as T,inactiveSnapshot as x,subscribeSource as B,physicalGenerationIsOccupied as f}from"./owner-generation-state.js";function j(n){const e=y(n.id),t=new Set,r=new Set,o=Object.freeze({kind:"inactive",reason:new O("retired",e),revision:0}),i={activeRetirement:void 0,completedRetirements:new WeakMap,current:void 0,nextAttachmentOrdinal:0,ownerId:e,pendingSourceEvents:[],publicListeners:r,publishing:!1,sourceListeners:t,sourceSnapshot:o},u=Object.freeze({getSnapshot:()=>i.sourceSnapshot,subscribe(s){return B(i,s)}}),c=Object.freeze({getSnapshot(){return i.sourceSnapshot.kind==="ready"?T:x},id:e,[D]:!0,subscribe(s){return C(i,s)}}),a=Object.freeze({begin(){if(i.current!==void 0||i.activeRetirement!==void 0)throw new TypeError(`Owner generation ${e} is already active or retiring.`);const s=k(e);return i.current={generation:s.generation,ownedAttachments:new Set,phase:"opening",state:s.state},s.generation},commit(s){const d=g(i,s);if(d.phase!=="ready"){if(d.phase!=="opening")throw new TypeError(`Owner generation ${e} cannot commit while ${d.phase}.`);d.phase="ready",d.state.committed=!0,R(i,Object.freeze({authority:s,kind:"ready",revision:i.sourceSnapshot.revision+1}))}},[G]:!0,ref:c});return E.set(a,i),h.set(c,i),w.set(a,u),a}function z(n){const e=w.get(n);if(e===void 0)throw new TypeError("OwnerGenerationController source is unavailable.");return e}function $(n,e){const t=h.get(n);if(t===void 0)throw new TypeError("OwnerGenerationRef is not authentic.");const r=l.get(e);if(r!==void 0){if(S(r).owner!==t)throw new TypeError("Attachment lifecycle is already bound to another owner generation slot.");return r}const o=Object.freeze({[A]:!0,readiness:e.ref}),i={controller:e,generation:void 0,ordinal:t.nextAttachmentOrdinal,owner:t};return t.nextAttachmentOrdinal+=1,v.set(o,i),l.set(e,o),o}function I(n,e,t){if(e.phase!=="opening"&&e.phase!=="ready")throw new TypeError(`Owner-bound attachment cannot open while owner is ${e.phase}.`);if(n.generation===void 0||n.generation===t)return;const r=n.controller.diagnostics();if(f(r))throw new TypeError("Owner-bound attachment still belongs to a previous physical generation.")}function L(n){return n.kind==="committed"&&n.state==="ready"}function m(n,e,t){return n.generation===t&&n.owner.current===e}function q(n,e,t,r,o){if(L(o)||!m(e,t,r)||t.phase!=="opening"&&t.phase!=="ready")return;const i=e.controller.diagnostics();f(i)||(e.generation=void 0,t.ownedAttachments.delete(n))}function F(n){return n.kind==="recovered"||n.kind==="not-needed"&&n.state==="closed"}function M(n){return n.phase==="opening"||n.phase==="ready"}function P(n,e,t,r){if(!F(r))return;const o=e.owner.current;o===void 0||!m(e,o,t)||M(o)&&(f(e.controller.diagnostics())||(e.generation=void 0,o.ownedAttachments.delete(n)))}function W(n,e,t){const r=p(n),o=g(r.owner,e),i=r.generation,u=o.ownedAttachments.has(n);I(r,o,e),r.generation=e,o.ownedAttachments.add(n);let c;try{c=r.controller.request({key:e,signal:e.signal,value:t})}catch(a){throw r.generation=i,u||o.ownedAttachments.delete(n),a}return c.then(a=>q(n,r,o,e,a),b),c}async function H(n){const e=p(n),t=e.generation,r=await e.controller.retryClose();return t!==void 0&&P(n,e,t,r),r}export{$ as bindAttachmentLifecycleToOwner,j as createOwnerGenerationSlot,z as getOwnerGenerationAuthoritySource,W as openOwnerBoundAttachment,H as retryOwnerBoundAttachmentClose};
2
+ //# sourceMappingURL=owner-generation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-generation.js","sources":["../src/owner-generation.ts"],"sourcesContent":["import { declarationId, FeatureError } from '@opetope/core';\nimport { reportDetachedError } from '@opetope/core/internal';\nimport type {\n AttachmentIntentOutcome,\n AttachmentLifecycleController,\n AttachmentRetryOutcome,\n CallAuthoritySource,\n CallAuthoritySourceEvent,\n CallAuthoritySourceSnapshot,\n} from '@opetope/core/internal';\n\nimport {\n assertCurrentGeneration,\n attachmentDefinitions,\n controllerBindings,\n controllerDefinitions,\n getAttachmentDefinition,\n getTypedAttachmentDefinition,\n inactiveSnapshot,\n makeGeneration,\n ownerBoundAttachmentBrand,\n ownerDefinitions,\n ownerGenerationControllerBrand,\n ownerGenerationRefBrand,\n ownerSources,\n physicalGenerationIsOccupied,\n publishSourceSnapshot,\n readySnapshot,\n subscribePublic,\n subscribeSource,\n} from './owner-generation-state';\nimport type {\n CurrentGeneration,\n OwnerBoundAttachment,\n OwnerBoundAttachmentDefinition,\n OwnerBoundAttachmentIdentity,\n OwnerGeneration,\n OwnerGenerationController,\n OwnerGenerationDefinition,\n OwnerGenerationRef,\n OwnerGenerationSnapshot,\n PublicListenerRegistration,\n SourceListenerRegistration,\n} from './owner-generation-state';\n\nfunction createOwnerGenerationSlot(options: { readonly id: string }): OwnerGenerationController {\n const ownerId = declarationId(options.id);\n const sourceListeners = new Set<SourceListenerRegistration>();\n const publicListeners = new Set<PublicListenerRegistration>();\n const initialSourceSnapshot = Object.freeze({\n kind: 'inactive' as const,\n reason: new FeatureError('retired', ownerId),\n revision: 0,\n });\n const definition: OwnerGenerationDefinition = {\n activeRetirement: undefined,\n completedRetirements: new WeakMap(),\n current: undefined,\n nextAttachmentOrdinal: 0,\n ownerId,\n pendingSourceEvents: [],\n publicListeners,\n publishing: false,\n sourceListeners,\n sourceSnapshot: initialSourceSnapshot,\n };\n const source = Object.freeze({\n getSnapshot: (): CallAuthoritySourceSnapshot => definition.sourceSnapshot,\n subscribe(listener: (event: CallAuthoritySourceEvent) => void): () => void {\n return subscribeSource(definition, listener);\n },\n });\n const ref = Object.freeze({\n getSnapshot(): OwnerGenerationSnapshot {\n return definition.sourceSnapshot.kind === 'ready' ? readySnapshot : inactiveSnapshot;\n },\n id: ownerId,\n [ownerGenerationRefBrand]: true as const,\n subscribe(listener: () => void): () => void {\n return subscribePublic(definition, listener);\n },\n });\n const controller = Object.freeze({\n begin(): OwnerGeneration {\n if (definition.current !== undefined || definition.activeRetirement !== undefined) {\n throw new TypeError(`Owner generation ${ownerId} is already active or retiring.`);\n }\n\n const created = makeGeneration(ownerId);\n definition.current = {\n generation: created.generation,\n ownedAttachments: new Set(),\n phase: 'opening',\n state: created.state,\n };\n\n return created.generation;\n },\n commit(generation: OwnerGeneration): void {\n const current = assertCurrentGeneration(definition, generation);\n\n if (current.phase === 'ready') return;\n\n if (current.phase !== 'opening') {\n throw new TypeError(`Owner generation ${ownerId} cannot commit while ${current.phase}.`);\n }\n\n current.phase = 'ready';\n current.state.committed = true;\n publishSourceSnapshot(\n definition,\n Object.freeze({\n authority: generation,\n kind: 'ready' as const,\n revision: definition.sourceSnapshot.revision + 1,\n }),\n );\n },\n [ownerGenerationControllerBrand]: true as const,\n ref,\n });\n controllerDefinitions.set(controller, definition);\n ownerDefinitions.set(ref, definition);\n ownerSources.set(controller, source);\n\n return controller;\n}\n\n/**\n * Package-private source used by later runtime lowering; intentionally absent from `./internal`. A controller that is\n * not authentic has no source either, so one lookup proves both (D165).\n */\nfunction getOwnerGenerationAuthoritySource(controller: OwnerGenerationController): CallAuthoritySource {\n const source = ownerSources.get(controller);\n\n if (source === undefined) throw new TypeError('OwnerGenerationController source is unavailable.');\n\n return source;\n}\n\nfunction bindAttachmentLifecycleToOwner<Value>(\n owner: OwnerGenerationRef,\n controller: AttachmentLifecycleController<OwnerGeneration, Value>,\n): OwnerBoundAttachment<Value> {\n const ownerDefinition = ownerDefinitions.get(owner);\n\n if (ownerDefinition === undefined) throw new TypeError('OwnerGenerationRef is not authentic.');\n\n const existing = controllerBindings.get(controller);\n\n if (existing !== undefined) {\n const existingDefinition = getAttachmentDefinition(existing);\n\n if (existingDefinition.owner !== ownerDefinition) {\n throw new TypeError('Attachment lifecycle is already bound to another owner generation slot.');\n }\n\n return existing as OwnerBoundAttachment<Value>;\n }\n\n const attachment = Object.freeze({\n [ownerBoundAttachmentBrand]: true as const,\n readiness: controller.ref,\n }) as OwnerBoundAttachment<Value>;\n const definition: OwnerBoundAttachmentDefinition<Value> = {\n controller,\n generation: undefined,\n ordinal: ownerDefinition.nextAttachmentOrdinal,\n owner: ownerDefinition,\n };\n ownerDefinition.nextAttachmentOrdinal += 1;\n attachmentDefinitions.set(attachment, definition as OwnerBoundAttachmentDefinition<unknown>);\n controllerBindings.set(controller, attachment);\n\n return attachment;\n}\n\nfunction assertAttachmentCanOpen<Value>(\n definition: OwnerBoundAttachmentDefinition<Value>,\n current: CurrentGeneration,\n generation: OwnerGeneration,\n): void {\n if (current.phase !== 'opening' && current.phase !== 'ready') {\n throw new TypeError(`Owner-bound attachment cannot open while owner is ${current.phase}.`);\n }\n\n if (definition.generation === undefined || definition.generation === generation) return;\n\n const diagnostics = definition.controller.diagnostics();\n\n if (physicalGenerationIsOccupied(diagnostics)) {\n throw new TypeError('Owner-bound attachment still belongs to a previous physical generation.');\n }\n}\n\nfunction isCommittedReady(outcome: AttachmentIntentOutcome): boolean {\n return outcome.kind === 'committed' && outcome.state === 'ready';\n}\n\nfunction isSettledOpenOwner<Value>(\n definition: OwnerBoundAttachmentDefinition<Value>,\n current: CurrentGeneration,\n generation: OwnerGeneration,\n): boolean {\n return definition.generation === generation && definition.owner.current === current;\n}\n\nfunction releaseSettledAttachment<Value>(\n attachment: OwnerBoundAttachmentIdentity,\n definition: OwnerBoundAttachmentDefinition<Value>,\n current: CurrentGeneration,\n generation: OwnerGeneration,\n outcome: AttachmentIntentOutcome,\n): void {\n if (isCommittedReady(outcome)) return;\n\n if (!isSettledOpenOwner(definition, current, generation)) return;\n\n if (current.phase !== 'opening' && current.phase !== 'ready') return;\n\n const diagnostics = definition.controller.diagnostics();\n\n if (physicalGenerationIsOccupied(diagnostics)) return;\n\n definition.generation = undefined;\n current.ownedAttachments.delete(attachment);\n}\n\nfunction isRecoveredCloseOutcome(outcome: AttachmentRetryOutcome): boolean {\n return outcome.kind === 'recovered' || (outcome.kind === 'not-needed' && outcome.state === 'closed');\n}\n\nfunction ownerCanReleaseRecoveredAttachment(current: CurrentGeneration): boolean {\n return current.phase === 'opening' || current.phase === 'ready';\n}\n\nfunction releaseRecoveredAttachment<Value>(\n attachment: OwnerBoundAttachment<Value>,\n definition: OwnerBoundAttachmentDefinition<Value>,\n generation: OwnerGeneration,\n outcome: AttachmentRetryOutcome,\n): void {\n if (!isRecoveredCloseOutcome(outcome)) return;\n\n const current = definition.owner.current;\n\n if (current === undefined || !isSettledOpenOwner(definition, current, generation)) return;\n\n if (!ownerCanReleaseRecoveredAttachment(current)) return;\n\n if (physicalGenerationIsOccupied(definition.controller.diagnostics())) return;\n\n definition.generation = undefined;\n current.ownedAttachments.delete(attachment);\n}\n\nfunction openOwnerBoundAttachment<Value>(\n attachment: OwnerBoundAttachment<Value>,\n generation: OwnerGeneration,\n value: Value,\n): Promise<AttachmentIntentOutcome> {\n const definition = getTypedAttachmentDefinition(attachment);\n const current = assertCurrentGeneration(definition.owner, generation);\n const previousGeneration = definition.generation;\n const alreadyOwned = current.ownedAttachments.has(attachment);\n assertAttachmentCanOpen(definition, current, generation);\n\n definition.generation = generation;\n current.ownedAttachments.add(attachment);\n\n let request: Promise<AttachmentIntentOutcome>;\n\n try {\n request = definition.controller.request({ key: generation, signal: generation.signal, value });\n } catch (error) {\n definition.generation = previousGeneration;\n\n if (!alreadyOwned) current.ownedAttachments.delete(attachment);\n\n throw error;\n }\n\n void request.then(\n outcome => releaseSettledAttachment(attachment, definition, current, generation, outcome),\n reportDetachedError,\n );\n\n return request;\n}\n\nasync function retryOwnerBoundAttachmentClose<Value>(\n attachment: OwnerBoundAttachment<Value>,\n): Promise<AttachmentRetryOutcome> {\n const definition = getTypedAttachmentDefinition(attachment);\n const generation = definition.generation;\n const outcome = await definition.controller.retryClose();\n\n if (generation !== undefined) releaseRecoveredAttachment(attachment, definition, generation, outcome);\n\n return outcome;\n}\n\nexport {\n acknowledgeOwnerGenerationDrain,\n retireOwnedGeneration,\n retirePlannedOwnerGeneration,\n} from './owner-generation-retirement';\nexport {\n bindAttachmentLifecycleToOwner,\n createOwnerGenerationSlot,\n getOwnerGenerationAuthoritySource,\n openOwnerBoundAttachment,\n retryOwnerBoundAttachmentClose,\n};\nexport type {\n OwnerBoundAttachment,\n OwnerGeneration,\n OwnerGenerationController,\n OwnerGenerationPlanRetirement,\n OwnerGenerationRef,\n OwnerGenerationRetirement,\n OwnerGenerationSnapshot,\n} from './owner-generation-state';\n"],"names":["createOwnerGenerationSlot","options","ownerId","declarationId","sourceListeners","publicListeners","initialSourceSnapshot","FeatureError","definition","source","listener","subscribeSource","ref","readySnapshot","inactiveSnapshot","ownerGenerationRefBrand","subscribePublic","controller","created","makeGeneration","generation","current","assertCurrentGeneration","publishSourceSnapshot","ownerGenerationControllerBrand","controllerDefinitions","ownerDefinitions","ownerSources","getOwnerGenerationAuthoritySource","bindAttachmentLifecycleToOwner","owner","ownerDefinition","existing","controllerBindings","getAttachmentDefinition","attachment","ownerBoundAttachmentBrand","attachmentDefinitions","assertAttachmentCanOpen","diagnostics","physicalGenerationIsOccupied","isCommittedReady","outcome","isSettledOpenOwner","releaseSettledAttachment","isRecoveredCloseOutcome","ownerCanReleaseRecoveredAttachment","releaseRecoveredAttachment","openOwnerBoundAttachment","value","getTypedAttachmentDefinition","previousGeneration","alreadyOwned","request","error","reportDetachedError","retryOwnerBoundAttachmentClose"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CompiledModuleTemplateIR } from './module-template-ir.js';
2
+ import type { ExactInput, ModuleDefinition, ModuleDefinitionOptions, ModuleRuntimeRecord, ModuleScopeRef } from './public-module-types.js';
3
+ declare function defineModule<const Owner extends string, const Runtime extends ModuleRuntimeRecord<Owner>, const Options extends ModuleDefinitionOptions<Owner, Runtime>>(options: ExactInput<Options, ModuleDefinitionOptions<Owner, Runtime>>): ModuleDefinition<Owner, Runtime>;
4
+ declare function getModuleScopeEntries<const Id extends string, const Runtime extends ModuleRuntimeRecord<Id>>(definition: ModuleDefinition<Id, Runtime>): readonly {
5
+ readonly key: string;
6
+ readonly scope: ModuleScopeRef<unknown, Id>;
7
+ }[];
8
+ declare function getModuleTemplateIR<const Id extends string, const Runtime extends ModuleRuntimeRecord<Id>>(definition: ModuleDefinition<Id, Runtime>): CompiledModuleTemplateIR;
9
+ export { defineModule, getModuleScopeEntries, getModuleTemplateIR };
@@ -0,0 +1,2 @@
1
+ import{invalidateAttachmentCall as w,snapshotAttachmentCallOptions as y,createAttachmentCall as b,isAttachmentCallRef as E}from"./attachment-call-declaration.js";import{invalidateScopeBlueprint as T,isScopeBlueprint as m,createScopeBlueprint as M,getAttachmentDefinition as d,isLifetimeAttachmentRef as v}from"./attachment-declaration.js";import{createLocalAttachmentModuleDefinition as A,compileModuleTemplate as S}from"./compile-module-template.js";import{assertPlainModuleOptions as O,moduleDefinitions as R,requireModuleDefinition as C}from"./public-module-state.js";function D(e){return Object.entries(e).flatMap(([r,t])=>m(t)?[{key:r,scope:t}]:[])}function F(e,r,t){if(m(e)){if(!r.has(e))throw new TypeError("Feature runtime cannot adopt a scope from another transaction.");return}if(v(e)){if(!r.has(d(e).owner))throw new TypeError("Feature runtime cannot adopt an attachment from another transaction.");return}if(E(e)&&!t.has(e))throw new TypeError("Feature runtime cannot adopt a call from another transaction.")}function g(e,r,t){const o=new Set(Object.values(e));for(const a of r)if(!o.has(a))throw new TypeError("Every scope created by defineModule must be returned from runtime.");for(const a of t)if(!o.has(a))throw new TypeError("Every call created by defineModule must be returned from runtime.");for(const a of o)F(a,r,t)}function j(e){O(e);const r=e.runtime;if(typeof r!="function")throw new TypeError("defineModule runtime must be a builder callback.");let t=!0,o=!1,a=!1;const u=new Set,s=new Set,f=()=>{if(!t)throw new TypeError("Feature runtime builder is no longer active.");if(o)throw new TypeError("Nested runtime builder operations are forbidden.")},p=Object.freeze({call:(n=>{f(),o=!0;try{const i=y(n),l=d(i.within).owner;if(!s.has(l))throw new TypeError("Feature calls must bind within an attachment created by the same runtime builder.");const c=b(i);return u.add(c),c}finally{o=!1}}),scope:(()=>{f(),o=!0;try{const n=M();return s.add(n),n}finally{o=!1}})});try{const n=r(p);t=!1;const i=A({id:e.id,runtime:n});g(i.runtime,s,u);const l=S(i),c=Object.freeze({id:i.id,runtime:i.runtime}),h={plan:l,runtime:i.runtime,scopeEntries:D(i.runtime)};return R.set(c,h),a=!0,c}finally{t=!1,a||(u.forEach(n=>w(n)),s.forEach(n=>T(n)))}}function B(e){return C(e).scopeEntries}export{j as defineModule,B as getModuleScopeEntries};
2
+ //# sourceMappingURL=public-module-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-module-definition.js","sources":["../src/public-module-definition.ts"],"sourcesContent":["import {\n createAttachmentCall,\n invalidateAttachmentCall,\n isAttachmentCallRef,\n snapshotAttachmentCallOptions,\n} from './attachment-call-declaration';\nimport type {\n AttachmentCallRefIdentity,\n AttachmentCallOptions as InternalAttachmentCallOptions,\n} from './attachment-call-declaration';\nimport {\n createScopeBlueprint,\n getAttachmentDefinition,\n invalidateScopeBlueprint,\n isLifetimeAttachmentRef,\n isScopeBlueprint,\n} from './attachment-declaration';\nimport type { ScopeBlueprintIdentity } from './attachment-declaration';\nimport { compileModuleTemplate, createLocalAttachmentModuleDefinition } from './compile-module-template';\nimport type { CompiledModuleTemplateIR } from './module-template-ir';\nimport { assertPlainModuleOptions, moduleDefinitions, requireModuleDefinition } from './public-module-state';\nimport type {\n ExactInput,\n InternalModuleRuntimeRecord,\n InternalModuleRuntimeRef,\n ModuleAttachmentRefIdentity,\n ModuleCallBuilder,\n ModuleCallOptions,\n ModuleCallRef,\n ModuleDefinition,\n ModuleDefinitionOptions,\n ModuleDefinitionRecord,\n ModuleRuntimeBuilder,\n ModuleRuntimeRecord,\n ModuleScopeBuilder,\n ModuleScopeDefinitionEntry,\n ModuleScopeRef,\n} from './public-module-types';\n\nfunction runtimeScopeEntries(runtime: InternalModuleRuntimeRecord): readonly ModuleScopeDefinitionEntry[] {\n return Object.entries(runtime).flatMap(([key, value]) => (isScopeBlueprint(value) ? [{ key, scope: value }] : []));\n}\n\nfunction assertReturnedRuntimeRefOwned(\n ref: InternalModuleRuntimeRef,\n scopes: ReadonlySet<ScopeBlueprintIdentity>,\n calls: ReadonlySet<AttachmentCallRefIdentity>,\n): void {\n if (isScopeBlueprint(ref)) {\n if (!scopes.has(ref)) throw new TypeError('Feature runtime cannot adopt a scope from another transaction.');\n\n return;\n }\n\n if (isLifetimeAttachmentRef(ref)) {\n if (!scopes.has(getAttachmentDefinition(ref).owner)) {\n throw new TypeError('Feature runtime cannot adopt an attachment from another transaction.');\n }\n\n return;\n }\n\n if (isAttachmentCallRef(ref) && !calls.has(ref)) {\n throw new TypeError('Feature runtime cannot adopt a call from another transaction.');\n }\n}\n\nfunction assertTransactionRuntimeCoverage(\n runtime: InternalModuleRuntimeRecord,\n scopes: ReadonlySet<ScopeBlueprintIdentity>,\n calls: ReadonlySet<AttachmentCallRefIdentity>,\n): void {\n const returned = new Set(Object.values(runtime));\n\n for (const scope of scopes) {\n if (!returned.has(scope)) throw new TypeError('Every scope created by defineModule must be returned from runtime.');\n }\n\n for (const call of calls) {\n if (!returned.has(call)) throw new TypeError('Every call created by defineModule must be returned from runtime.');\n }\n\n for (const ref of returned) assertReturnedRuntimeRefOwned(ref, scopes, calls);\n}\n\nfunction defineModule<\n const Owner extends string,\n const Runtime extends ModuleRuntimeRecord<Owner>,\n const Options extends ModuleDefinitionOptions<Owner, Runtime>,\n>(options: ExactInput<Options, ModuleDefinitionOptions<Owner, Runtime>>): ModuleDefinition<Owner, Runtime> {\n assertPlainModuleOptions(options);\n const build = options.runtime;\n\n if (typeof build !== 'function') throw new TypeError('defineModule runtime must be a builder callback.');\n\n let active = true;\n let operationActive = false;\n let committed = false;\n const calls = new Set<AttachmentCallRefIdentity>();\n const scopes = new Set<ScopeBlueprintIdentity>();\n const assertBuilderActive = (): void => {\n if (!active) throw new TypeError('Feature runtime builder is no longer active.');\n\n if (operationActive) throw new TypeError('Nested runtime builder operations are forbidden.');\n };\n const scope = (<Value>(): ModuleScopeRef<Value, Owner> => {\n assertBuilderActive();\n operationActive = true;\n\n try {\n const created = createScopeBlueprint<Value>();\n scopes.add(created);\n\n return created as unknown as ModuleScopeRef<Value, Owner>;\n } finally {\n operationActive = false;\n }\n }) as ModuleScopeBuilder<Owner>;\n const call = (<\n Input,\n Output,\n Within extends ModuleAttachmentRefIdentity<Owner>,\n const CallOptions extends ModuleCallOptions<Input, Output, Within>,\n >(\n callOptions: ExactInput<CallOptions, ModuleCallOptions<Input, Output, Within>>,\n ): ModuleCallRef<Input, Output, Owner> => {\n assertBuilderActive();\n operationActive = true;\n\n try {\n const snapshot = snapshotAttachmentCallOptions(\n callOptions as unknown as InternalAttachmentCallOptions<Input, Output>,\n );\n const owner = getAttachmentDefinition(snapshot.within).owner;\n\n if (!scopes.has(owner)) {\n throw new TypeError('Feature calls must bind within an attachment created by the same runtime builder.');\n }\n\n const created = createAttachmentCall<Input, Output, InternalAttachmentCallOptions<Input, Output>>(snapshot);\n calls.add(created);\n\n return created as unknown as ModuleCallRef<Input, Output, Owner>;\n } finally {\n operationActive = false;\n }\n }) as ModuleCallBuilder<Owner>;\n const builder: ModuleRuntimeBuilder<Owner> = Object.freeze({ call, scope });\n\n try {\n const sourceRuntime = build(builder);\n active = false;\n const localDefinition = createLocalAttachmentModuleDefinition({\n id: options.id,\n runtime: sourceRuntime as unknown as InternalModuleRuntimeRecord,\n });\n assertTransactionRuntimeCoverage(localDefinition.runtime, scopes, calls);\n const plan = compileModuleTemplate(localDefinition);\n const definition = Object.freeze({\n id: localDefinition.id,\n runtime: localDefinition.runtime,\n }) as unknown as ModuleDefinition<Owner, Runtime>;\n const record: ModuleDefinitionRecord = {\n plan,\n runtime: localDefinition.runtime,\n scopeEntries: runtimeScopeEntries(localDefinition.runtime),\n };\n moduleDefinitions.set(definition, record);\n committed = true;\n\n return definition;\n } finally {\n active = false;\n\n if (!committed) {\n calls.forEach(created => invalidateAttachmentCall(created));\n scopes.forEach(created => invalidateScopeBlueprint(created));\n }\n }\n}\n\nfunction getModuleScopeEntries<const Id extends string, const Runtime extends ModuleRuntimeRecord<Id>>(\n definition: ModuleDefinition<Id, Runtime>,\n): readonly { readonly key: string; readonly scope: ModuleScopeRef<unknown, Id> }[] {\n return requireModuleDefinition(definition).scopeEntries as unknown as readonly {\n readonly key: string;\n readonly scope: ModuleScopeRef<unknown, Id>;\n }[];\n}\n\nfunction getModuleTemplateIR<const Id extends string, const Runtime extends ModuleRuntimeRecord<Id>>(\n definition: ModuleDefinition<Id, Runtime>,\n): CompiledModuleTemplateIR {\n return requireModuleDefinition(definition).plan;\n}\n\nexport { defineModule, getModuleScopeEntries, getModuleTemplateIR };\n"],"names":["runtimeScopeEntries","runtime","key","value","isScopeBlueprint","assertReturnedRuntimeRefOwned","ref","scopes","calls","isLifetimeAttachmentRef","getAttachmentDefinition","isAttachmentCallRef","assertTransactionRuntimeCoverage","returned","scope","call","defineModule","options","assertPlainModuleOptions","build","active","operationActive","committed","assertBuilderActive","builder","callOptions","snapshot","snapshotAttachmentCallOptions","owner","created","createAttachmentCall","createScopeBlueprint","sourceRuntime","localDefinition","createLocalAttachmentModuleDefinition","plan","compileModuleTemplate","definition","record","moduleDefinitions","invalidateAttachmentCall","invalidateScopeBlueprint","getModuleScopeEntries","requireModuleDefinition"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Call } from '@opetope/core';
2
+ import type { ExactInput, ModuleCallRef, ModuleDefinition, ModuleInstance, ModuleInstanceOptions, ModuleInstanceRef, ModuleRetirementParticipant, ModuleRuntimeRecord } from './public-module-types.js';
3
+ declare function instantiateModule<const Id extends string, const Runtime extends ModuleRuntimeRecord<Id>, const Options extends ModuleInstanceOptions = ModuleInstanceOptions>(definition: ModuleDefinition<Id, Runtime>, options?: ExactInput<Options, ModuleInstanceOptions>): ModuleInstance<Id>;
4
+ declare function resolveModuleCallTarget<Owner extends string, Input, Output>(instance: ModuleInstanceRef<Owner>, call: ModuleCallRef<Input, Output, Owner>): Call<Input, Output>;
5
+ declare function registerModuleRetirementParticipant<Owner extends string>(instance: ModuleInstanceRef<Owner>, participant: ModuleRetirementParticipant): () => void;
6
+ export { instantiateModule, registerModuleRetirementParticipant, resolveModuleCallTarget };
@@ -0,0 +1,2 @@
1
+ import{instantiateRetainedModuleTemplate as p,resolveAttachmentCallTarget as l}from"./module-instance.js";import{beginModuleRetirement as u}from"./public-module-retirement.js";import{getModuleScopeInstance as f}from"./public-module-scope.js";import{requireModuleDefinition as d,snapshotModuleInstanceOptions as m,moduleInstances as y,requireActiveLocal as b,requireModuleInstance as s}from"./public-module-state.js";function g(i,t){const e=d(i),n=m(t),a=p(e.plan,n.reporter),r={cleanupFailure:n.cleanupFailure,definition:e,local:a,nextParticipantSlot:0,operation:void 0,participants:[],reporter:n.cleanupFailure==="report"?n.reporter:void 0,retirement:void 0,scopeHandles:new Map,state:"assembly"},o=Object.freeze({retire:()=>u(r),scope:c=>f(r,c)});return y.set(o,r),o}function M(i,t){return l(b(s(i)),t)}function w(i,t){const e=s(i);if(e.state!=="assembly"||e.operation!==void 0)throw new TypeError("Retirement participants must register before the first scope open.");e.operation="registering";try{if(typeof t!="object"||t===null)throw new TypeError("Retirement participant must be an object.");const n=t.fence;if(typeof n!="function")throw new TypeError("Retirement participant requires a fence function.");const a=Object.freeze({fence:()=>n.call(t),slot:e.nextParticipantSlot});e.nextParticipantSlot+=1,e.participants.push(a);let r=!0;return()=>{if(!r)return;if(e.state!=="assembly"||e.operation!==void 0)throw new TypeError("Retirement participant registration is sealed.");r=!1;const o=e.participants.indexOf(a);o!==-1&&e.participants.splice(o,1)}}finally{e.operation=void 0}}export{g as instantiateModule,w as registerModuleRetirementParticipant,M as resolveModuleCallTarget};
2
+ //# sourceMappingURL=public-module-instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-module-instance.js","sources":["../src/public-module-instance.ts"],"sourcesContent":["import type { Call } from '@opetope/core';\n\nimport type { AttachmentCallRef } from './attachment-call-declaration';\nimport { instantiateRetainedModuleTemplate, resolveAttachmentCallTarget } from './module-instance';\nimport { beginModuleRetirement } from './public-module-retirement';\nimport { getModuleScopeInstance } from './public-module-scope';\nimport {\n moduleInstances,\n requireActiveLocal,\n requireModuleDefinition,\n requireModuleInstance,\n snapshotModuleInstanceOptions,\n} from './public-module-state';\nimport type {\n ExactInput,\n ModuleCallRef,\n ModuleDefinition,\n ModuleInstance,\n ModuleInstanceOptions,\n ModuleInstanceRecord,\n ModuleInstanceRef,\n ModuleRetirement,\n ModuleRetirementParticipant,\n ModuleRuntimeRecord,\n ModuleScopeInstance,\n ModuleScopeRef,\n} from './public-module-types';\n\nfunction instantiateModule<\n const Id extends string,\n const Runtime extends ModuleRuntimeRecord<Id>,\n const Options extends ModuleInstanceOptions = ModuleInstanceOptions,\n>(definition: ModuleDefinition<Id, Runtime>, options?: ExactInput<Options, ModuleInstanceOptions>): ModuleInstance<Id> {\n const definitionRecord = requireModuleDefinition(definition);\n const instanceOptions = snapshotModuleInstanceOptions(options);\n const local = instantiateRetainedModuleTemplate(definitionRecord.plan, instanceOptions.reporter);\n const record: ModuleInstanceRecord = {\n cleanupFailure: instanceOptions.cleanupFailure,\n definition: definitionRecord,\n local,\n nextParticipantSlot: 0,\n operation: undefined,\n participants: [],\n reporter: instanceOptions.cleanupFailure === 'report' ? instanceOptions.reporter : undefined,\n retirement: undefined,\n scopeHandles: new Map(),\n state: 'assembly',\n };\n const instance = Object.freeze({\n retire: (): ModuleRetirement => beginModuleRetirement(record),\n scope: <Value>(scope: ModuleScopeRef<Value, Id>): ModuleScopeInstance<Value> =>\n getModuleScopeInstance(record, scope),\n }) as unknown as ModuleInstance<Id>;\n moduleInstances.set(instance, record);\n\n return instance;\n}\n\nfunction resolveModuleCallTarget<Owner extends string, Input, Output>(\n instance: ModuleInstanceRef<Owner>,\n call: ModuleCallRef<Input, Output, Owner>,\n): Call<Input, Output> {\n return resolveAttachmentCallTarget(\n requireActiveLocal(requireModuleInstance(instance)),\n call as unknown as AttachmentCallRef<Input, Output>,\n );\n}\n\nfunction registerModuleRetirementParticipant<Owner extends string>(\n instance: ModuleInstanceRef<Owner>,\n participant: ModuleRetirementParticipant,\n): () => void {\n const record = requireModuleInstance(instance);\n\n if (record.state !== 'assembly' || record.operation !== undefined) {\n throw new TypeError('Retirement participants must register before the first scope open.');\n }\n\n record.operation = 'registering';\n\n try {\n if (typeof participant !== 'object' || participant === null) {\n throw new TypeError('Retirement participant must be an object.');\n }\n\n const fence = participant.fence;\n\n if (typeof fence !== 'function') throw new TypeError('Retirement participant requires a fence function.');\n\n const registered = Object.freeze({ fence: () => fence.call(participant), slot: record.nextParticipantSlot });\n record.nextParticipantSlot += 1;\n record.participants.push(registered);\n let active = true;\n\n return (): void => {\n if (!active) return;\n\n if (record.state !== 'assembly' || record.operation !== undefined) {\n throw new TypeError('Retirement participant registration is sealed.');\n }\n\n active = false;\n const index = record.participants.indexOf(registered);\n\n if (index !== -1) record.participants.splice(index, 1);\n };\n } finally {\n record.operation = undefined;\n }\n}\n\nexport { instantiateModule, registerModuleRetirementParticipant, resolveModuleCallTarget };\n"],"names":["instantiateModule","definition","options","definitionRecord","requireModuleDefinition","instanceOptions","snapshotModuleInstanceOptions","local","instantiateRetainedModuleTemplate","record","instance","beginModuleRetirement","scope","getModuleScopeInstance","moduleInstances","resolveModuleCallTarget","call","resolveAttachmentCallTarget","requireActiveLocal","requireModuleInstance","registerModuleRetirementParticipant","participant","fence","registered","active","index"],"mappings":"gaA4BA,SAASA,EAIPC,EAA2CC,EAAoD,CAC/F,MAAMC,EAAmBC,EAAwBH,CAAU,EACrDI,EAAkBC,EAA8BJ,CAAO,EACvDK,EAAQC,EAAkCL,EAAiB,KAAME,EAAgB,QAAQ,EACzFI,EAA+B,CACnC,eAAgBJ,EAAgB,eAChC,WAAYF,EACZ,MAAAI,EACA,oBAAqB,EACrB,UAAW,OACX,aAAc,CAAA,EACd,SAAUF,EAAgB,iBAAmB,SAAWA,EAAgB,SAAW,OACnF,WAAY,OACZ,aAAc,IAAI,IAClB,MAAO,YAEHK,EAAW,OAAO,OAAO,CAC7B,OAAQ,IAAwBC,EAAsBF,CAAM,EAC5D,MAAeG,GACbC,EAAuBJ,EAAQG,CAAK,CACvC,CAAA,EACD,OAAAE,EAAgB,IAAIJ,EAAUD,CAAM,EAE7BC,CACT,CAEA,SAASK,EACPL,EACAM,EAAyC,CAEzC,OAAOC,EACLC,EAAmBC,EAAsBT,CAAQ,CAAC,EAClDM,CAAmD,CAEvD,CAEA,SAASI,EACPV,EACAW,EAAwC,CAExC,MAAMZ,EAASU,EAAsBT,CAAQ,EAE7C,GAAID,EAAO,QAAU,YAAcA,EAAO,YAAc,OACtD,MAAM,IAAI,UAAU,oEAAoE,EAG1FA,EAAO,UAAY,cAEnB,GAAI,CACF,GAAI,OAAOY,GAAgB,UAAYA,IAAgB,KACrD,MAAM,IAAI,UAAU,2CAA2C,EAGjE,MAAMC,EAAQD,EAAY,MAE1B,GAAI,OAAOC,GAAU,WAAY,MAAM,IAAI,UAAU,mDAAmD,EAExG,MAAMC,EAAa,OAAO,OAAO,CAAE,MAAO,IAAMD,EAAM,KAAKD,CAAW,EAAG,KAAMZ,EAAO,mBAAmB,CAAE,EAC3GA,EAAO,qBAAuB,EAC9BA,EAAO,aAAa,KAAKc,CAAU,EACnC,IAAIC,EAAS,GAEb,MAAO,IAAW,CAChB,GAAI,CAACA,EAAQ,OAEb,GAAIf,EAAO,QAAU,YAAcA,EAAO,YAAc,OACtD,MAAM,IAAI,UAAU,gDAAgD,EAGtEe,EAAS,GACT,MAAMC,EAAQhB,EAAO,aAAa,QAAQc,CAAU,EAEhDE,IAAU,IAAIhB,EAAO,aAAa,OAAOgB,EAAO,CAAC,CACvD,CACF,SACEhB,EAAO,UAAY,MACrB,CACF"}
@@ -0,0 +1,5 @@
1
+ import type { ModuleCleanupFailureDiagnostic, ModuleInstanceRecord, ModuleInstanceRef, ModuleRetirementFailure, RetirementFrontier } from './public-module-types.js';
2
+ declare function moduleFailure(frontier: RetirementFrontier): ModuleRetirementFailure;
3
+ declare function projectModuleCleanupFailuresFromRecord(record: ModuleInstanceRecord, failures: readonly ModuleRetirementFailure[]): readonly ModuleCleanupFailureDiagnostic[];
4
+ declare function projectModuleCleanupFailures<Id extends string>(instance: ModuleInstanceRef<Id>, failures: readonly ModuleRetirementFailure[]): readonly ModuleCleanupFailureDiagnostic[];
5
+ export { moduleFailure, projectModuleCleanupFailures, projectModuleCleanupFailuresFromRecord };
@@ -0,0 +1,2 @@
1
+ import{projectScopeDrainOutcome as u}from"./public-module-scope.js";import{requireActiveDefinition as i,requireModuleInstance as d}from"./public-module-state.js";function l(e){switch(e.kind){case"participant-fence":return Object.freeze({error:e.error,kind:"participant",phase:"fence",slot:e.participant.slot});case"participant-handle":return Object.freeze({error:e.error,kind:"participant",phase:e.phase,slot:e.slot});case"scope":{const t=e.outcome;if(t===void 0)throw new TypeError("Scope retirement failure lost its quarantined outcome.");return Object.freeze({kind:"scope",outcome:u(t),scope:e.scope})}case"scope-fence":return Object.freeze({error:e.error,kind:"scope-fence",scope:e.scope})}}function s(e,t){const n=t,r=i(e).scopeEntries.find(a=>a.scope===n);if(r===void 0)throw new TypeError("Retirement failure lost its scope key.");return r.key}function c(e,t){try{const n=e[t];return typeof n=="string"?n:void 0}catch{return}}function m(e){const t=typeof e;return t==="string"?e:t==="bigint"||t==="boolean"||t==="number"?String(e):e===null?"null":`A ${t} value was thrown.`}function o(e){if(!(e instanceof Error))return Object.freeze({message:m(e),name:"ThrownValue"});const t=c(e,"message")??"Cleanup failed.",n=c(e,"name")??"Error",r=c(e,"stack");return Object.freeze(r===void 0?{message:t,name:n}:{message:t,name:n,stack:r})}function f(e){return Object.freeze(e.map(t=>Object.freeze({attachmentId:t.attachmentId,errors:Object.freeze(t.errors.map(o)),phase:t.phase})))}function p(e,t){return Object.freeze(t.map(n=>{switch(n.kind){case"participant":return Object.freeze({error:o(n.error),kind:n.kind,phase:n.phase,slot:n.slot});case"scope":return Object.freeze({failures:f(n.outcome.failures),kind:n.kind,scope:s(e,n.scope)});case"scope-fence":return Object.freeze({error:o(n.error),kind:n.kind,scope:s(e,n.scope)})}}))}function h(e,t){return p(d(e),t)}export{l as moduleFailure,h as projectModuleCleanupFailures,p as projectModuleCleanupFailuresFromRecord};
2
+ //# sourceMappingURL=public-module-retirement-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-module-retirement-diagnostics.js","sources":["../src/public-module-retirement-diagnostics.ts"],"sourcesContent":["import type { ScopeBlueprintIdentity } from './attachment-declaration';\nimport { projectScopeDrainOutcome } from './public-module-scope';\nimport { requireActiveDefinition, requireModuleInstance } from './public-module-state';\nimport type {\n ModuleAttachmentCleanupFailureDiagnostic,\n ModuleAttachmentRetirementFailure,\n ModuleCleanupErrorDiagnostic,\n ModuleCleanupFailureDiagnostic,\n ModuleInstanceRecord,\n ModuleInstanceRef,\n ModuleRetirementFailure,\n ModuleScopeDrainOutcome,\n ModuleScopeRefIdentity,\n RetirementFrontier,\n} from './public-module-types';\n\nfunction moduleFailure(frontier: RetirementFrontier): ModuleRetirementFailure {\n switch (frontier.kind) {\n case 'participant-fence':\n return Object.freeze({\n error: frontier.error,\n kind: 'participant' as const,\n phase: 'fence' as const,\n slot: frontier.participant.slot,\n });\n case 'participant-handle':\n return Object.freeze({\n error: frontier.error,\n kind: 'participant' as const,\n phase: frontier.phase,\n slot: frontier.slot,\n });\n case 'scope': {\n const outcome = frontier.outcome;\n\n if (outcome === undefined) throw new TypeError('Scope retirement failure lost its quarantined outcome.');\n\n return Object.freeze({\n kind: 'scope' as const,\n outcome: projectScopeDrainOutcome(outcome) as Extract<\n ModuleScopeDrainOutcome,\n { readonly kind: 'quarantined' }\n >,\n scope: frontier.scope as unknown as ModuleScopeRefIdentity,\n });\n }\n case 'scope-fence':\n return Object.freeze({\n error: frontier.error,\n kind: 'scope-fence' as const,\n scope: frontier.scope as unknown as ModuleScopeRefIdentity,\n });\n }\n}\n\nfunction moduleScopeKey(record: ModuleInstanceRecord, scope: ModuleScopeRefIdentity): string {\n const internalScope = scope as unknown as ScopeBlueprintIdentity;\n const entry = requireActiveDefinition(record).scopeEntries.find(candidate => candidate.scope === internalScope);\n\n if (entry === undefined) throw new TypeError('Retirement failure lost its scope key.');\n\n return entry.key;\n}\n\nfunction readCleanupErrorText(error: Error, key: 'message' | 'name' | 'stack'): string | undefined {\n try {\n const value: unknown = error[key];\n\n return typeof value === 'string' ? value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction nonErrorCleanupMessage(error: unknown): string {\n const valueType = typeof error;\n\n if (valueType === 'string') return error as string;\n\n if (valueType === 'bigint' || valueType === 'boolean' || valueType === 'number') return String(error);\n\n return error === null ? 'null' : `A ${valueType} value was thrown.`;\n}\n\nfunction projectModuleCleanupError(error: unknown): ModuleCleanupErrorDiagnostic {\n if (!(error instanceof Error)) {\n return Object.freeze({ message: nonErrorCleanupMessage(error), name: 'ThrownValue' });\n }\n\n const message = readCleanupErrorText(error, 'message') ?? 'Cleanup failed.';\n const name = readCleanupErrorText(error, 'name') ?? 'Error';\n const stack = readCleanupErrorText(error, 'stack');\n\n return Object.freeze(stack === undefined ? { message, name } : { message, name, stack });\n}\n\nfunction projectAttachmentCleanupFailures(\n failures: readonly ModuleAttachmentRetirementFailure[],\n): readonly ModuleAttachmentCleanupFailureDiagnostic[] {\n return Object.freeze(\n failures.map(failure =>\n Object.freeze({\n attachmentId: failure.attachmentId,\n errors: Object.freeze(failure.errors.map(projectModuleCleanupError)),\n phase: failure.phase,\n }),\n ),\n );\n}\n\nfunction projectModuleCleanupFailuresFromRecord(\n record: ModuleInstanceRecord,\n failures: readonly ModuleRetirementFailure[],\n): readonly ModuleCleanupFailureDiagnostic[] {\n return Object.freeze(\n failures.map(failure => {\n switch (failure.kind) {\n case 'participant':\n return Object.freeze({\n error: projectModuleCleanupError(failure.error),\n kind: failure.kind,\n phase: failure.phase,\n slot: failure.slot,\n });\n case 'scope':\n return Object.freeze({\n failures: projectAttachmentCleanupFailures(failure.outcome.failures),\n kind: failure.kind,\n scope: moduleScopeKey(record, failure.scope),\n });\n case 'scope-fence':\n return Object.freeze({\n error: projectModuleCleanupError(failure.error),\n kind: failure.kind,\n scope: moduleScopeKey(record, failure.scope),\n });\n }\n }),\n );\n}\n\nfunction projectModuleCleanupFailures<Id extends string>(\n instance: ModuleInstanceRef<Id>,\n failures: readonly ModuleRetirementFailure[],\n): readonly ModuleCleanupFailureDiagnostic[] {\n return projectModuleCleanupFailuresFromRecord(requireModuleInstance(instance), failures);\n}\n\nexport { moduleFailure, projectModuleCleanupFailures, projectModuleCleanupFailuresFromRecord };\n"],"names":["moduleFailure","frontier","outcome","projectScopeDrainOutcome","moduleScopeKey","record","scope","internalScope","entry","requireActiveDefinition","candidate","readCleanupErrorText","error","key","value","nonErrorCleanupMessage","valueType","projectModuleCleanupError","message","name","stack","projectAttachmentCleanupFailures","failures","failure","projectModuleCleanupFailuresFromRecord","projectModuleCleanupFailures","instance","requireModuleInstance"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ModuleInstanceRecord, ModuleRetirement } from './public-module-types.js';
2
+ declare function beginModuleRetirement(record: ModuleInstanceRecord): ModuleRetirement;
3
+ export { beginModuleRetirement };
@@ -0,0 +1,2 @@
1
+ import{FeatureError as k}from"@opetope/core";import{releaseLocalAttachmentErrorReporter as R,hasActiveLocalAttachmentCallback as b,retireLocalScopeIfActive as O,revokeLocalAttachmentModuleCallTargets as g}from"./module-instance.js";import{moduleFailure as F,projectModuleCleanupFailuresFromRecord as M}from"./public-module-retirement-diagnostics.js";import{requireActiveDefinition as l,requireActiveLocal as f,closedModuleDrainOutcome as a,reportModuleCleanupFailure as C}from"./public-module-state.js";function E(n){if(typeof n!="object"||n===null)throw new TypeError("Retirement participant must return undefined or a retirement handle.");const e=Reflect.get(n,"drain"),t=Reflect.get(n,"retry");if(typeof e!="function"||typeof t!="function")throw new TypeError("Retirement participant handle requires drain and retry functions.");const r=e,i=t;return Object.freeze({drain:()=>r.call(n),retry:()=>i.call(n)})}async function p(n){if(await n()!==void 0)throw new TypeError("Retirement participant operations must resolve to undefined.")}async function s(n,e){let t;n.activeCallbackOperations+=1;try{t=e()}finally{n.activeCallbackOperations-=1}return await t}function u(n,e){const t=n.local;if(((e==null?void 0:e.activeCallbackOperations)??0)!==0||t!==void 0&&b(t))throw new TypeError("Retirement cannot be re-entered from an active retirement callback.")}function m(n){try{const e=n.fence();return e===void 0?void 0:{error:void 0,handle:E(e),kind:"participant-handle",phase:"drain",slot:n.slot}}catch(e){return{error:e,kind:"participant-fence",participant:n}}}function h(n,e){try{const t=O(f(n),e);return t===void 0?void 0:{handle:t,kind:"scope",outcome:void 0,scope:e}}catch(t){return{error:t,kind:"scope-fence",scope:e}}}function y(n,e){const t=n.local;t!==void 0&&g(t);for(const r of n.scopeHandles.values())r.local=void 0,r.record=void 0;n.scopeHandles.clear(),n.definition=void 0,n.local=void 0,n.participants.length=0,n.reporter=void 0,e.drainPromise=void 0,e.frontiers=[],e.retryPromise=void 0,e.handleState.instanceRecord=void 0,e.handleState.outcome=a,e.handleState.retirement=void 0}function P(n,e){if(e.frontiers.length===0)return n.state="retired",e.outcome=a,y(n,e),a;const t=Object.freeze({failures:Object.freeze(e.frontiers.map(F)),kind:"quarantined"});if(n.cleanupFailure==="report"){const r=l(n).plan.moduleId,i=n.reporter,o=M(n,t.failures);n.state="retired",e.outcome=a,y(n,e);const c=new k("cleanup-failed",r,{failures:o});return C(c,i),a}return e.outcome=t,t}async function d(n,e){switch(e.kind){case"participant-fence":case"scope-fence":return e;case"participant-handle":try{await s(n,()=>p(e.handle.drain));return}catch(t){return e.error=t,e.phase="drain",e}case"scope":{const t=await s(n,e.handle.drain);return t.kind==="closed"?void 0:(e.outcome=t,e)}}}function v(){let n=()=>{},e=()=>{};return{promise:new Promise((r,i)=>{n=i,e=r}),reject:n,resolve:e}}function w(n,e){var r;if(((r=e.outcome)==null?void 0:r.kind)==="closed"||e.drained)return Promise.resolve(e.outcome??a);if(e.drainPromise!==void 0)return e.drainPromise;const t=v();return e.drainPromise=t.promise,Promise.resolve().then(async()=>{const i=await Promise.all(e.frontiers.map(o=>d(e,o)));return e.frontiers=i.filter(o=>o!==void 0),e.drained=!0,P(n,e)}).then(t.resolve,t.reject),t.promise}function j(n,e){return u(n,e),e.retryPromise!==void 0?e.retryPromise:w(n,e)}async function S(n,e){try{await s(n,()=>p(e.handle.retry));return}catch(t){return e.error=t,e.phase="retry",e}}async function T(n,e){const t=await s(n,e.handle.retry);if(t.kind!=="closed")return e.outcome=t,e}function A(n,e){const t=m(e.participant);return(t==null?void 0:t.kind)==="participant-handle"?d(n,t):Promise.resolve(t)}function L(n,e,t){const r=h(n,t.scope);return(r==null?void 0:r.kind)==="scope"?d(e,r):Promise.resolve(r)}function q(n,e,t){switch(t.kind){case"participant-fence":return A(e,t);case"participant-handle":return S(e,t);case"scope":return T(e,t);case"scope-fence":return L(n,e,t)}}function z(n,e){var r;if(u(n,e),((r=e.outcome)==null?void 0:r.kind)==="closed")return Promise.resolve(a);if(e.retryPromise!==void 0)return e.retryPromise;const t=v();return e.retryPromise=t.promise,Promise.resolve().then(async()=>{const i=e.drained?e.outcome:await w(n,e);if((i==null?void 0:i.kind)==="closed")return i;e.drained=!1,e.outcome=void 0;const o=await Promise.all(e.frontiers.map(c=>q(n,e,c)));return e.frontiers=o.filter(c=>c!==void 0),e.drained=!0,P(n,e)}).then(i=>{var o;e.retryPromise===t.promise&&((o=e.outcome)==null?void 0:o.kind)!=="closed"&&(e.retryPromise=void 0),t.resolve(i)},i=>{e.retryPromise===t.promise&&(e.retryPromise=void 0),t.reject(i)}),t.promise}function H(n,e){const t={instanceRecord:n,outcome:void 0,retirement:void 0},r={activeCallbackOperations:0,drained:!1,drainPromise:void 0,frontiers:e,handleState:t,outcome:void 0,retryPromise:void 0,runtime:void 0};return t.retirement=r,r.runtime=Object.freeze({drain:()=>{if(t.outcome!==void 0)return Promise.resolve(t.outcome);const i=t.instanceRecord,o=t.retirement;if(i===void 0||o===void 0)throw new TypeError("Retirement handle lost its active state.");return j(i,o)},retry:()=>{if(t.outcome!==void 0)return Promise.resolve(t.outcome);const i=t.instanceRecord,o=t.retirement;if(i===void 0||o===void 0)throw new TypeError("Retirement handle lost its active state.");return z(i,o)}}),r}function I(n){if(u(n,n.retirement),n.retirement!==void 0)return n.retirement.runtime;if(n.operation!==void 0)throw new TypeError("Feature instance has a reentrant lifecycle operation.");n.operation="retiring",n.state="retiring";const e=[];try{for(const r of n.participants){const i=m(r);i!==void 0&&e.push(i)}for(const{scope:r}of l(n).scopeEntries){const i=h(n,r);i!==void 0&&e.push(i)}R(f(n)),n.participants.length=0;const t=H(n,e);return n.retirement=t,t.runtime}finally{n.operation=void 0}}export{I as beginModuleRetirement};
2
+ //# sourceMappingURL=public-module-retirement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-module-retirement.js","sources":["../src/public-module-retirement.ts"],"sourcesContent":["import { FeatureError } from '@opetope/core';\n\nimport type { ScopeBlueprint, ScopeBlueprintIdentity } from './attachment-declaration';\nimport {\n hasActiveLocalAttachmentCallback,\n releaseLocalAttachmentErrorReporter,\n retireLocalScopeIfActive,\n revokeLocalAttachmentModuleCallTargets,\n} from './module-instance';\nimport { moduleFailure, projectModuleCleanupFailuresFromRecord } from './public-module-retirement-diagnostics';\nimport {\n closedModuleDrainOutcome,\n reportModuleCleanupFailure,\n requireActiveDefinition,\n requireActiveLocal,\n} from './public-module-state';\nimport type {\n Awaitable,\n ModuleDrainOutcome,\n ModuleInstanceRecord,\n ModuleRetirement,\n ModuleRetirementHandleState,\n ModuleRetirementParticipantHandle,\n ModuleRetirementRecord,\n ParticipantFenceFrontier,\n ParticipantHandleFrontier,\n RegisteredParticipant,\n RetirementFrontier,\n ScopeFenceFrontier,\n ScopeFrontier,\n} from './public-module-types';\n\nfunction snapshotParticipantHandle(value: unknown): ModuleRetirementParticipantHandle {\n if (typeof value !== 'object' || value === null) {\n throw new TypeError('Retirement participant must return undefined or a retirement handle.');\n }\n\n const drain = Reflect.get(value, 'drain') as unknown;\n const retry = Reflect.get(value, 'retry') as unknown;\n\n if (typeof drain !== 'function' || typeof retry !== 'function') {\n throw new TypeError('Retirement participant handle requires drain and retry functions.');\n }\n\n const drainOperation = drain as (this: object) => Awaitable<void>;\n const retryOperation = retry as (this: object) => Awaitable<void>;\n\n return Object.freeze({\n drain: () => drainOperation.call(value),\n retry: () => retryOperation.call(value),\n });\n}\n\nasync function invokeParticipantOperation(operation: () => Awaitable<void>): Promise<void> {\n const result = await operation();\n\n if (result !== undefined) throw new TypeError('Retirement participant operations must resolve to undefined.');\n}\n\nasync function invokeRetirementCallback<Result>(\n retirement: ModuleRetirementRecord,\n operation: () => Awaitable<Result>,\n): Promise<Result> {\n let result: Awaitable<Result>;\n retirement.activeCallbackOperations += 1;\n\n try {\n result = operation();\n } finally {\n retirement.activeCallbackOperations -= 1;\n }\n\n return await result;\n}\n\nfunction assertRetirementCallbackInactive(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord | undefined,\n): void {\n // Only the synchronous callback frame is distinguishable from an unrelated caller. Calling the\n // owning retirement after the callback's first await is a documented contract violation.\n const local = instanceRecord.local;\n\n if (\n (retirement?.activeCallbackOperations ?? 0) !== 0 ||\n (local !== undefined && hasActiveLocalAttachmentCallback(local))\n ) {\n throw new TypeError('Retirement cannot be re-entered from an active retirement callback.');\n }\n}\n\nfunction fenceParticipant(\n participant: RegisteredParticipant,\n): ParticipantFenceFrontier | ParticipantHandleFrontier | undefined {\n try {\n const handle = participant.fence();\n\n if (handle === undefined) return undefined;\n\n const snapshot = snapshotParticipantHandle(handle);\n\n return { error: undefined, handle: snapshot, kind: 'participant-handle', phase: 'drain', slot: participant.slot };\n } catch (error) {\n return { error, kind: 'participant-fence', participant };\n }\n}\n\nfunction fenceActiveScope(\n record: ModuleInstanceRecord,\n scope: ScopeBlueprintIdentity,\n): ScopeFenceFrontier | ScopeFrontier | undefined {\n try {\n const handle = retireLocalScopeIfActive(requireActiveLocal(record), scope as ScopeBlueprint<unknown>);\n\n return handle === undefined ? undefined : { handle, kind: 'scope', outcome: undefined, scope };\n } catch (error) {\n return { error, kind: 'scope-fence', scope };\n }\n}\n\nfunction releaseTerminalModuleState(record: ModuleInstanceRecord, retirement: ModuleRetirementRecord): void {\n const local = record.local;\n\n if (local !== undefined) revokeLocalAttachmentModuleCallTargets(local);\n\n for (const state of record.scopeHandles.values()) {\n state.local = undefined;\n state.record = undefined;\n }\n\n record.scopeHandles.clear();\n record.definition = undefined;\n record.local = undefined;\n record.participants.length = 0;\n record.reporter = undefined;\n retirement.drainPromise = undefined;\n retirement.frontiers = [];\n retirement.retryPromise = undefined;\n retirement.handleState.instanceRecord = undefined;\n retirement.handleState.outcome = closedModuleDrainOutcome;\n retirement.handleState.retirement = undefined;\n}\n\nfunction settleModuleRetirement(record: ModuleInstanceRecord, retirement: ModuleRetirementRecord): ModuleDrainOutcome {\n if (retirement.frontiers.length === 0) {\n record.state = 'retired';\n retirement.outcome = closedModuleDrainOutcome;\n releaseTerminalModuleState(record, retirement);\n\n return closedModuleDrainOutcome;\n }\n\n const outcome = Object.freeze({\n failures: Object.freeze(retirement.frontiers.map(moduleFailure)),\n kind: 'quarantined' as const,\n });\n\n if (record.cleanupFailure === 'report') {\n const moduleId = requireActiveDefinition(record).plan.moduleId;\n const reporter = record.reporter;\n const failures = projectModuleCleanupFailuresFromRecord(record, outcome.failures);\n\n record.state = 'retired';\n retirement.outcome = closedModuleDrainOutcome;\n releaseTerminalModuleState(record, retirement);\n const error = new FeatureError('cleanup-failed', moduleId, { failures });\n\n reportModuleCleanupFailure(error, reporter);\n\n return closedModuleDrainOutcome;\n }\n\n retirement.outcome = outcome;\n\n return outcome;\n}\n\nasync function drainFrontier(\n retirement: ModuleRetirementRecord,\n frontier: RetirementFrontier,\n): Promise<RetirementFrontier | undefined> {\n switch (frontier.kind) {\n case 'participant-fence':\n case 'scope-fence':\n return frontier;\n case 'participant-handle':\n try {\n await invokeRetirementCallback(retirement, () => invokeParticipantOperation(frontier.handle.drain));\n\n return undefined;\n } catch (error) {\n frontier.error = error;\n frontier.phase = 'drain';\n\n return frontier;\n }\n case 'scope': {\n const outcome = await invokeRetirementCallback(retirement, frontier.handle.drain);\n\n if (outcome.kind === 'closed') return undefined;\n\n frontier.outcome = outcome;\n\n return frontier;\n }\n }\n}\n\ntype PendingModuleRetirementOperation = {\n readonly promise: Promise<ModuleDrainOutcome>;\n readonly reject: (reason?: unknown) => void;\n readonly resolve: (outcome: ModuleDrainOutcome | PromiseLike<ModuleDrainOutcome>) => void;\n};\n\nfunction createPendingModuleRetirementOperation(): PendingModuleRetirementOperation {\n let reject: PendingModuleRetirementOperation['reject'] = () => undefined;\n let resolve: PendingModuleRetirementOperation['resolve'] = () => undefined;\n const promise = new Promise<ModuleDrainOutcome>((resolvePromise, rejectPromise) => {\n reject = rejectPromise;\n resolve = resolvePromise;\n });\n\n return { promise, reject, resolve };\n}\n\nfunction startModuleRetirementDrain(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord,\n): Promise<ModuleDrainOutcome> {\n if (retirement.outcome?.kind === 'closed' || retirement.drained) {\n return Promise.resolve(retirement.outcome ?? closedModuleDrainOutcome);\n }\n\n if (retirement.drainPromise !== undefined) return retirement.drainPromise;\n\n const pending = createPendingModuleRetirementOperation();\n retirement.drainPromise = pending.promise;\n\n void Promise.resolve()\n .then(async () => {\n const frontiers = await Promise.all(retirement.frontiers.map(frontier => drainFrontier(retirement, frontier)));\n retirement.frontiers = frontiers.filter((value): value is RetirementFrontier => value !== undefined);\n retirement.drained = true;\n\n return settleModuleRetirement(instanceRecord, retirement);\n })\n .then(pending.resolve, pending.reject);\n\n return pending.promise;\n}\n\nfunction drainModuleRetirement(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord,\n): Promise<ModuleDrainOutcome> {\n assertRetirementCallbackInactive(instanceRecord, retirement);\n\n if (retirement.retryPromise !== undefined) return retirement.retryPromise;\n\n return startModuleRetirementDrain(instanceRecord, retirement);\n}\n\nasync function retryParticipantHandle(\n retirement: ModuleRetirementRecord,\n frontier: ParticipantHandleFrontier,\n): Promise<ParticipantHandleFrontier | undefined> {\n try {\n await invokeRetirementCallback(retirement, () => invokeParticipantOperation(frontier.handle.retry));\n\n return undefined;\n } catch (error) {\n frontier.error = error;\n frontier.phase = 'retry';\n\n return frontier;\n }\n}\n\nasync function retryScopeFrontier(\n retirement: ModuleRetirementRecord,\n frontier: ScopeFrontier,\n): Promise<ScopeFrontier | undefined> {\n const outcome = await invokeRetirementCallback(retirement, frontier.handle.retry);\n\n if (outcome.kind === 'closed') return undefined;\n\n frontier.outcome = outcome;\n\n return frontier;\n}\n\nfunction retryParticipantFence(\n retirement: ModuleRetirementRecord,\n frontier: ParticipantFenceFrontier,\n): Promise<RetirementFrontier | undefined> {\n const next = fenceParticipant(frontier.participant);\n\n return next?.kind === 'participant-handle' ? drainFrontier(retirement, next) : Promise.resolve(next);\n}\n\nfunction retryScopeFence(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord,\n frontier: ScopeFenceFrontier,\n): Promise<RetirementFrontier | undefined> {\n const next = fenceActiveScope(instanceRecord, frontier.scope);\n\n return next?.kind === 'scope' ? drainFrontier(retirement, next) : Promise.resolve(next);\n}\n\nfunction retryFrontier(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord,\n frontier: RetirementFrontier,\n): Promise<RetirementFrontier | undefined> {\n switch (frontier.kind) {\n case 'participant-fence':\n return retryParticipantFence(retirement, frontier);\n case 'participant-handle':\n return retryParticipantHandle(retirement, frontier);\n case 'scope':\n return retryScopeFrontier(retirement, frontier);\n case 'scope-fence':\n return retryScopeFence(instanceRecord, retirement, frontier);\n }\n}\n\nfunction retryModuleRetirement(\n instanceRecord: ModuleInstanceRecord,\n retirement: ModuleRetirementRecord,\n): Promise<ModuleDrainOutcome> {\n assertRetirementCallbackInactive(instanceRecord, retirement);\n\n if (retirement.outcome?.kind === 'closed') return Promise.resolve(closedModuleDrainOutcome);\n\n if (retirement.retryPromise !== undefined) return retirement.retryPromise;\n\n const pending = createPendingModuleRetirementOperation();\n retirement.retryPromise = pending.promise;\n\n void Promise.resolve()\n .then(async () => {\n const outcome = retirement.drained\n ? retirement.outcome\n : await startModuleRetirementDrain(instanceRecord, retirement);\n\n if (outcome?.kind === 'closed') return outcome;\n\n retirement.drained = false;\n retirement.outcome = undefined;\n const frontiers = await Promise.all(\n retirement.frontiers.map(frontier => retryFrontier(instanceRecord, retirement, frontier)),\n );\n retirement.frontiers = frontiers.filter((value): value is RetirementFrontier => value !== undefined);\n retirement.drained = true;\n\n return settleModuleRetirement(instanceRecord, retirement);\n })\n .then(\n outcome => {\n if (retirement.retryPromise === pending.promise && retirement.outcome?.kind !== 'closed') {\n retirement.retryPromise = undefined;\n }\n\n pending.resolve(outcome);\n },\n (error: unknown) => {\n if (retirement.retryPromise === pending.promise) {\n retirement.retryPromise = undefined;\n }\n\n pending.reject(error);\n },\n );\n\n return pending.promise;\n}\n\nfunction createModuleRetirementRecord(\n instanceRecord: ModuleInstanceRecord,\n frontiers: RetirementFrontier[],\n): ModuleRetirementRecord {\n const handleState: ModuleRetirementHandleState = { instanceRecord, outcome: undefined, retirement: undefined };\n const retirement = {\n activeCallbackOperations: 0,\n drained: false,\n drainPromise: undefined,\n frontiers,\n handleState,\n outcome: undefined,\n retryPromise: undefined,\n runtime: undefined as unknown as ModuleRetirement,\n };\n handleState.retirement = retirement;\n retirement.runtime = Object.freeze({\n drain: (): Promise<ModuleDrainOutcome> => {\n if (handleState.outcome !== undefined) return Promise.resolve(handleState.outcome);\n\n const activeRecord = handleState.instanceRecord;\n const activeRetirement = handleState.retirement;\n\n if (activeRecord === undefined || activeRetirement === undefined) {\n throw new TypeError('Retirement handle lost its active state.');\n }\n\n return drainModuleRetirement(activeRecord, activeRetirement);\n },\n retry: (): Promise<ModuleDrainOutcome> => {\n if (handleState.outcome !== undefined) return Promise.resolve(handleState.outcome);\n\n const activeRecord = handleState.instanceRecord;\n const activeRetirement = handleState.retirement;\n\n if (activeRecord === undefined || activeRetirement === undefined) {\n throw new TypeError('Retirement handle lost its active state.');\n }\n\n return retryModuleRetirement(activeRecord, activeRetirement);\n },\n }) as ModuleRetirement;\n\n return retirement;\n}\n\nfunction beginModuleRetirement(record: ModuleInstanceRecord): ModuleRetirement {\n assertRetirementCallbackInactive(record, record.retirement);\n\n if (record.retirement !== undefined) {\n return record.retirement.runtime;\n }\n\n if (record.operation !== undefined) throw new TypeError('Feature instance has a reentrant lifecycle operation.');\n\n record.operation = 'retiring';\n record.state = 'retiring';\n const frontiers: RetirementFrontier[] = [];\n\n try {\n for (const participant of record.participants) {\n const frontier = fenceParticipant(participant);\n\n if (frontier !== undefined) frontiers.push(frontier);\n }\n\n for (const { scope } of requireActiveDefinition(record).scopeEntries) {\n const frontier = fenceActiveScope(record, scope);\n\n if (frontier !== undefined) frontiers.push(frontier);\n }\n\n releaseLocalAttachmentErrorReporter(requireActiveLocal(record));\n\n record.participants.length = 0;\n const retirement = createModuleRetirementRecord(record, frontiers);\n record.retirement = retirement;\n\n return retirement.runtime;\n } finally {\n record.operation = undefined;\n }\n}\n\nexport { beginModuleRetirement };\n"],"names":["snapshotParticipantHandle","value","drain","retry","drainOperation","retryOperation","invokeParticipantOperation","operation","invokeRetirementCallback","retirement","result","assertRetirementCallbackInactive","instanceRecord","local","hasActiveLocalAttachmentCallback","fenceParticipant","participant","handle","error","fenceActiveScope","record","scope","retireLocalScopeIfActive","requireActiveLocal","releaseTerminalModuleState","revokeLocalAttachmentModuleCallTargets","state","closedModuleDrainOutcome","settleModuleRetirement","outcome","moduleFailure","moduleId","requireActiveDefinition","reporter","failures","projectModuleCleanupFailuresFromRecord","FeatureError","reportModuleCleanupFailure","drainFrontier","frontier","createPendingModuleRetirementOperation","reject","resolve","resolvePromise","rejectPromise","startModuleRetirementDrain","_a","pending","frontiers","drainModuleRetirement","retryParticipantHandle","retryScopeFrontier","retryParticipantFence","next","retryScopeFence","retryFrontier","retryModuleRetirement","createModuleRetirementRecord","handleState","activeRecord","activeRetirement","beginModuleRetirement","releaseLocalAttachmentErrorReporter"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { LocalScopeDrainOutcome } from './module-instance.js';
2
+ import type { ModuleInstanceRecord, ModuleScopeDrainOutcome, ModuleScopeInstance, ModuleScopeRef } from './public-module-types.js';
3
+ declare function projectScopeDrainOutcome(outcome: LocalScopeDrainOutcome): ModuleScopeDrainOutcome;
4
+ declare function getModuleScopeInstance<Owner extends string, Value>(record: ModuleInstanceRecord, scope: ModuleScopeRef<Value, Owner>): ModuleScopeInstance<Value>;
5
+ export { getModuleScopeInstance, projectScopeDrainOutcome };
@@ -0,0 +1,2 @@
1
+ import{localScopeInstance as m}from"./module-instance.js";import{closedModuleScopeRetirement as h,assertInstanceCanOpen as j,scopeRetirements as f,readyModuleScopeOpenOutcome as O,closedModuleScopeDrainOutcome as b}from"./public-module-state.js";function k(e){if(e.kind==="failed")return e.failure.opening.error;if(e.kind!=="quarantined")return;const t=e.failure;return t.kind==="open-failed"?t.opening.error:t.cleanup.error}function z(e){const t=e.outcome;if(t.kind==="rejected")return Object.freeze({attachmentId:e.attachmentId,errors:Object.freeze([t.error]),phase:"close"});const r=t.failure;return r.kind==="close-failed"?Object.freeze({attachmentId:e.attachmentId,errors:Object.freeze(r.cleanup.failures.map(n=>n.error)),phase:r.phase}):r.kind==="open-failed"?Object.freeze({attachmentId:e.attachmentId,errors:Object.freeze([r.opening.error,...r.rollback.failures.map(n=>n.error)]),phase:"rollback"}):Object.freeze({attachmentId:e.attachmentId,errors:Object.freeze(r.cleanup.failures.map(n=>n.error)),phase:"rollback"})}function u(e){return e.kind==="closed"?b:Object.freeze({failures:Object.freeze(e.failedAttachments.map(z)),kind:"quarantined"})}function p(e){const t=f.get(e);if(t!==void 0)return t;let r,n,a,s;const o=(c,d,l)=>c===d&&l!==void 0?l:c.then(u),i=Object.freeze({drain:()=>{const c=e.drain();return n=o(c,r,n),r=c,n},retry:()=>{const c=e.retry();return a=o(c,s,a),s=c,a}});return f.set(e,i),i}function I(e){if(e.kind==="ready")return O;const t=p(e.retirement),r=u(e.drain);if(e.kind==="retired")return Object.freeze({drain:r,kind:"retired",retirement:t});const n=e.outcome.kind==="committed"?"closed":e.outcome.kind;return Object.freeze({attachmentId:e.attachmentId,cause:k(e.outcome),drain:r,kind:"not-ready",reason:n,retirement:t})}function S(e){const t=e.local,r=e.record;if(t===void 0||r===void 0)throw new TypeError("Feature scope instance is retired.");return{local:t,record:r}}function y(e,t){const r=t,n=e.scopeHandles.get(r);if(n!==void 0)return n.runtime;const a=e.local;if(a===void 0)throw new TypeError("Feature instance is retired.");const o={local:m(a,r),record:e},i=Object.freeze({open(c){const d=S(o);return j(d.record),d.local.open(c).then(I)},retire(){return o.local===void 0?h:p(o.local.retire())}});return o.runtime=i,e.scopeHandles.set(r,o),i}export{y as getModuleScopeInstance,u as projectScopeDrainOutcome};
2
+ //# sourceMappingURL=public-module-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-module-scope.js","sources":["../src/public-module-scope.ts"],"sourcesContent":["import type { AttachmentIntentOutcome } from '@opetope/core/internal';\n\nimport type { ScopeBlueprint } from './attachment-declaration';\nimport { localScopeInstance } from './module-instance';\nimport type {\n LocalAttachmentCloseFailure,\n LocalScopeDrainOutcome,\n LocalScopeOpenOutcome,\n LocalScopeRetirement,\n} from './module-instance';\nimport {\n assertInstanceCanOpen,\n closedModuleScopeDrainOutcome,\n closedModuleScopeRetirement,\n readyModuleScopeOpenOutcome,\n scopeRetirements,\n} from './public-module-state';\nimport type {\n ModuleAttachmentRetirementFailure,\n ModuleInstanceRecord,\n ModuleScopeDrainOutcome,\n ModuleScopeHandleState,\n ModuleScopeInstance,\n ModuleScopeNotReadyOutcome,\n ModuleScopeOpenOutcome,\n ModuleScopeRef,\n ModuleScopeRetirement,\n} from './public-module-types';\n\nfunction attachmentIntentCause(outcome: AttachmentIntentOutcome): unknown {\n if (outcome.kind === 'failed') return outcome.failure.opening.error;\n\n if (outcome.kind !== 'quarantined') return undefined;\n\n const failure = outcome.failure;\n\n if (failure.kind === 'open-failed') return failure.opening.error;\n\n return failure.cleanup.error;\n}\n\nfunction attachmentRetirementFailure(failure: LocalAttachmentCloseFailure): ModuleAttachmentRetirementFailure {\n const outcome = failure.outcome;\n\n if (outcome.kind === 'rejected') {\n return Object.freeze({\n attachmentId: failure.attachmentId,\n errors: Object.freeze([outcome.error]),\n phase: 'close' as const,\n });\n }\n\n const record = outcome.failure;\n\n if (record.kind === 'close-failed') {\n return Object.freeze({\n attachmentId: failure.attachmentId,\n errors: Object.freeze(record.cleanup.failures.map(item => item.error)),\n phase: record.phase,\n });\n }\n\n if (record.kind === 'open-failed') {\n return Object.freeze({\n attachmentId: failure.attachmentId,\n errors: Object.freeze([record.opening.error, ...record.rollback.failures.map(item => item.error)]),\n phase: 'rollback' as const,\n });\n }\n\n return Object.freeze({\n attachmentId: failure.attachmentId,\n errors: Object.freeze(record.cleanup.failures.map(item => item.error)),\n phase: 'rollback' as const,\n });\n}\n\nfunction projectScopeDrainOutcome(outcome: LocalScopeDrainOutcome): ModuleScopeDrainOutcome {\n if (outcome.kind === 'closed') return closedModuleScopeDrainOutcome;\n\n return Object.freeze({\n failures: Object.freeze(outcome.failedAttachments.map(attachmentRetirementFailure)),\n kind: 'quarantined' as const,\n });\n}\n\nfunction projectScopeRetirement(retirement: LocalScopeRetirement): ModuleScopeRetirement {\n const cached = scopeRetirements.get(retirement);\n\n if (cached !== undefined) return cached;\n\n let drainSource: Promise<LocalScopeDrainOutcome> | undefined;\n let projectedDrain: Promise<ModuleScopeDrainOutcome> | undefined;\n let projectedRetry: Promise<ModuleScopeDrainOutcome> | undefined;\n let retrySource: Promise<LocalScopeDrainOutcome> | undefined;\n const project = (\n source: Promise<LocalScopeDrainOutcome>,\n previousSource: Promise<LocalScopeDrainOutcome> | undefined,\n previousProjection: Promise<ModuleScopeDrainOutcome> | undefined,\n ): Promise<ModuleScopeDrainOutcome> =>\n source === previousSource && previousProjection !== undefined\n ? previousProjection\n : source.then(projectScopeDrainOutcome);\n const projected = Object.freeze({\n drain: () => {\n const source = retirement.drain();\n projectedDrain = project(source, drainSource, projectedDrain);\n drainSource = source;\n\n return projectedDrain;\n },\n retry: () => {\n const source = retirement.retry();\n projectedRetry = project(source, retrySource, projectedRetry);\n retrySource = source;\n\n return projectedRetry;\n },\n });\n scopeRetirements.set(retirement, projected);\n\n return projected;\n}\n\nfunction projectScopeOpenOutcome(outcome: LocalScopeOpenOutcome): ModuleScopeOpenOutcome {\n if (outcome.kind === 'ready') return readyModuleScopeOpenOutcome;\n\n const retirement = projectScopeRetirement(outcome.retirement);\n const drain = projectScopeDrainOutcome(outcome.drain);\n\n if (outcome.kind === 'retired') return Object.freeze({ drain, kind: 'retired' as const, retirement });\n\n const reason: ModuleScopeNotReadyOutcome['reason'] =\n outcome.outcome.kind === 'committed' ? 'closed' : outcome.outcome.kind;\n\n return Object.freeze({\n attachmentId: outcome.attachmentId,\n cause: attachmentIntentCause(outcome.outcome),\n drain,\n kind: 'not-ready' as const,\n reason,\n retirement,\n });\n}\n\ntype MutableScopeHandleState<Value> = {\n -readonly [Key in keyof ModuleScopeHandleState<Value>]: ModuleScopeHandleState<Value>[Key];\n};\n\nfunction requireScopeHandle<Value>(state: ModuleScopeHandleState<Value>): {\n readonly local: NonNullable<ModuleScopeHandleState<Value>['local']>;\n readonly record: ModuleInstanceRecord;\n} {\n const local = state.local;\n const record = state.record;\n\n if (local === undefined || record === undefined) throw new TypeError('Feature scope instance is retired.');\n\n return { local, record };\n}\n\nfunction getModuleScopeInstance<Owner extends string, Value>(\n record: ModuleInstanceRecord,\n scope: ModuleScopeRef<Value, Owner>,\n): ModuleScopeInstance<Value> {\n const internalScope = scope as unknown as ScopeBlueprint<Value>;\n const cached = record.scopeHandles.get(internalScope);\n\n if (cached !== undefined) return cached.runtime;\n\n const localRecord = record.local;\n\n if (localRecord === undefined) throw new TypeError('Feature instance is retired.');\n\n const local = localScopeInstance(localRecord, internalScope);\n\n // The facade closes over the state and the state carries the facade, so one record answers both directions.\n const state = { local, record } as MutableScopeHandleState<Value>;\n const runtime = Object.freeze({\n open(value: Value): Promise<ModuleScopeOpenOutcome> {\n const active = requireScopeHandle(state);\n assertInstanceCanOpen(active.record);\n\n return active.local.open(value).then(projectScopeOpenOutcome);\n },\n retire(): ModuleScopeRetirement {\n return state.local === undefined ? closedModuleScopeRetirement : projectScopeRetirement(state.local.retire());\n },\n }) as unknown as ModuleScopeInstance<Value>;\n state.runtime = runtime;\n record.scopeHandles.set(internalScope, state as ModuleScopeHandleState<unknown>);\n\n return runtime;\n}\n\nexport { getModuleScopeInstance, projectScopeDrainOutcome };\n"],"names":["attachmentIntentCause","outcome","failure","attachmentRetirementFailure","record","item","projectScopeDrainOutcome","closedModuleScopeDrainOutcome","projectScopeRetirement","retirement","cached","scopeRetirements","drainSource","projectedDrain","projectedRetry","retrySource","project","source","previousSource","previousProjection","projected","projectScopeOpenOutcome","readyModuleScopeOpenOutcome","drain","reason","requireScopeHandle","state","local","getModuleScopeInstance","scope","internalScope","localRecord","localScopeInstance","runtime","value","active","assertInstanceCanOpen","closedModuleScopeRetirement"],"mappings":"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"}