@voxgig/sdkgen 4.8.2 → 4.9.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 (407) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/doctor.d.ts +1 -0
  3. package/dist/action/doctor.js +50 -2
  4. package/dist/action/doctor.js.map +1 -1
  5. package/dist/helpers/naming.js +4 -2
  6. package/dist/helpers/naming.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/model/sdkgen.aon +21 -0
  9. package/package.json +1 -1
  10. package/project/.sdk/model/feature/secrets.aon +120 -18
  11. package/project/.sdk/model/target/c.aon +10 -0
  12. package/project/.sdk/model/target/clojure.aon +13 -0
  13. package/project/.sdk/model/target/cpp.aon +10 -0
  14. package/project/.sdk/model/target/csharp.aon +9 -0
  15. package/project/.sdk/model/target/dart.aon +10 -0
  16. package/project/.sdk/model/target/elixir.aon +9 -0
  17. package/project/.sdk/model/target/go.aon +13 -0
  18. package/project/.sdk/model/target/java.aon +9 -0
  19. package/project/.sdk/model/target/js.aon +7 -0
  20. package/project/.sdk/model/target/kotlin.aon +9 -0
  21. package/project/.sdk/model/target/lean.aon +17 -0
  22. package/project/.sdk/model/target/lua.aon +8 -0
  23. package/project/.sdk/model/target/ocaml.aon +9 -0
  24. package/project/.sdk/model/target/perl.aon +8 -0
  25. package/project/.sdk/model/target/php.aon +8 -0
  26. package/project/.sdk/model/target/py.aon +13 -0
  27. package/project/.sdk/model/target/rb.aon +8 -0
  28. package/project/.sdk/model/target/rust.aon +10 -0
  29. package/project/.sdk/model/target/scala.aon +21 -2
  30. package/project/.sdk/model/target/swift.aon +18 -0
  31. package/project/.sdk/model/target/ts.aon +13 -0
  32. package/project/.sdk/model/target/zig.aon +9 -0
  33. package/project/.sdk/src/cmp/clojure/Package_clojure.ts +9 -2
  34. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +3 -0
  35. package/project/.sdk/src/cmp/dart/Test_dart.ts +2 -0
  36. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +4 -1
  37. package/project/.sdk/src/cmp/go/Config_go.ts +59 -2
  38. package/project/.sdk/src/cmp/go/Main_go.ts +8 -2
  39. package/project/.sdk/src/cmp/java/Test_java.ts +6 -5
  40. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +6 -5
  41. package/project/.sdk/src/cmp/lean/Package_lean.ts +23 -0
  42. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +1 -0
  43. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +1 -0
  44. package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
  45. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +7 -3
  46. package/project/.sdk/src/cmp/py/Config_py.ts +82 -1
  47. package/project/.sdk/src/cmp/py/Main_py.ts +44 -0
  48. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +2 -0
  49. package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
  50. package/project/.sdk/src/cmp/swift/Package_swift.ts +13 -1
  51. package/project/.sdk/src/cmp/ts/Config_ts.ts +42 -17
  52. package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +13 -1
  53. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +13 -1
  54. package/project/.sdk/src/cmp/zig/Package_zig.ts +15 -11
  55. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +3 -3
  56. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +3 -3
  57. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +3 -3
  58. package/project/.sdk/src/cmp/zig/utility_zig.ts +50 -1
  59. package/project/.sdk/tm/c/Makefile +38 -3
  60. package/project/.sdk/tm/c/tests/omni_resolver.h +361 -0
  61. package/project/.sdk/tm/c/tests/omni_smoke_test.c +237 -0
  62. package/project/.sdk/tm/c/tests/primary_corpus_test.c +205 -284
  63. package/project/.sdk/tm/c/tests/struct_corpus_test.c +292 -212
  64. package/project/.sdk/tm/c/tests/vendor/omni/json.c +811 -0
  65. package/project/.sdk/tm/c/tests/vendor/omni/omni.h +240 -0
  66. package/project/.sdk/tm/c/tests/vendor/omni/runner.c +940 -0
  67. package/project/.sdk/tm/c/tests/vendor/omni/util.c +351 -0
  68. package/project/.sdk/tm/c/utility/struct/utility.c +7 -2
  69. package/project/.sdk/tm/clojure/test/sdk/test/omni.clj +401 -0
  70. package/project/.sdk/tm/clojure/test/sdk/test/omni_smoke.clj +81 -0
  71. package/project/.sdk/tm/clojure/test/sdk/test/primary.clj +92 -58
  72. package/project/.sdk/tm/clojure/test/sdk/test/struct_corpus.clj +122 -149
  73. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +8 -3
  74. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +145 -0
  75. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +445 -0
  76. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +145 -0
  77. package/project/.sdk/tm/cpp/Makefile +5 -1
  78. package/project/.sdk/tm/cpp/test/omni_resolver.hpp +473 -0
  79. package/project/.sdk/tm/cpp/test/omni_smoke_test.cpp +209 -0
  80. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +243 -184
  81. package/project/.sdk/tm/cpp/test/runner_support.hpp +68 -181
  82. package/project/.sdk/tm/cpp/test/struct_corpus_test.cpp +183 -56
  83. package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +406 -0
  84. package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +751 -0
  85. package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +256 -0
  86. package/project/.sdk/tm/cpp/utility/pipeline.hpp +7 -1
  87. package/project/.sdk/tm/csharp/test/OmniResolver.cs +491 -0
  88. package/project/.sdk/tm/csharp/test/OmniSmokeTest.cs +106 -0
  89. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +299 -316
  90. package/project/.sdk/tm/csharp/test/Runner.cs +104 -269
  91. package/project/.sdk/tm/csharp/test/StructUtilityTest.cs +535 -724
  92. package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +864 -0
  93. package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +347 -0
  94. package/project/.sdk/tm/csharp/utility/MakeSpec.cs +3 -1
  95. package/project/.sdk/tm/csharp/utility/PrepareMethod.cs +6 -1
  96. package/project/.sdk/tm/csharp/utility/struct/Struct.cs +21 -5
  97. package/project/.sdk/tm/dart/test/omni.dart +520 -0
  98. package/project/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  99. package/project/.sdk/tm/dart/test/primary_test.dart +86 -28
  100. package/project/.sdk/tm/dart/test/struct_test.dart +438 -11
  101. package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  102. package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  103. package/project/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  104. package/project/.sdk/tm/elixir/Makefile +11 -3
  105. package/project/.sdk/tm/elixir/test/omni_smoke_test.exs +117 -0
  106. package/project/.sdk/tm/elixir/test/primary_utility_test.exs +341 -16
  107. package/project/.sdk/tm/elixir/test/struct_corpus_test.exs +554 -9
  108. package/project/.sdk/tm/elixir/test/support/omni.ex +377 -0
  109. package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +122 -0
  110. package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +623 -0
  111. package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +187 -0
  112. package/project/.sdk/tm/go/core/context.go +32 -16
  113. package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +261 -0
  114. package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +78 -0
  115. package/project/.sdk/tm/go/feature/secrets/plugin/config.go +652 -0
  116. package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +250 -0
  117. package/project/.sdk/tm/go/feature/secrets/plugin/env.go +194 -0
  118. package/project/.sdk/tm/go/feature/secrets/plugin/export.go +80 -0
  119. package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +238 -0
  120. package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1575 -0
  121. package/project/.sdk/tm/go/feature/secrets/plugin/order.go +248 -0
  122. package/project/.sdk/tm/go/feature/secrets/plugin/point.go +184 -0
  123. package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +123 -0
  124. package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +79 -0
  125. package/project/.sdk/tm/go/feature/secrets/plugin/types.go +296 -0
  126. package/project/.sdk/tm/go/feature/secrets/plugin/util.go +87 -0
  127. package/project/.sdk/tm/go/feature/secrets/plugin/version.go +161 -0
  128. package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +292 -0
  129. package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +201 -0
  130. package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +187 -0
  131. package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +184 -0
  132. package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +114 -0
  133. package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +156 -0
  134. package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +208 -0
  135. package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +241 -0
  136. package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +150 -0
  137. package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +152 -0
  138. package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +143 -0
  139. package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +120 -0
  140. package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +442 -0
  141. package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +714 -0
  142. package/project/.sdk/tm/go/feature/secrets_feature.go +675 -0
  143. package/project/.sdk/tm/go/src/feature/secrets/.gitkeep +0 -0
  144. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +799 -0
  145. package/project/.sdk/tm/go/test/omni/omni.go +902 -0
  146. package/project/.sdk/tm/go/test/omni/util.go +381 -0
  147. package/project/.sdk/tm/go/test/omniresolver_test.go +748 -0
  148. package/project/.sdk/tm/go/test/omnismoke_test.go +112 -0
  149. package/project/.sdk/tm/go/test/primary_utility_test.go +123 -191
  150. package/project/.sdk/tm/go/test/struct_utility_test.go +323 -16
  151. package/project/.sdk/tm/go/test/testsupport_test.go +294 -0
  152. package/project/.sdk/tm/go/utility/make_options.go +8 -1
  153. package/project/.sdk/tm/go/utility/prepare_method.go +5 -1
  154. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +2 -2
  155. package/project/.sdk/tm/java/test/OmniResolver.java +355 -0
  156. package/project/.sdk/tm/java/test/OmniSmokeTest.java +99 -0
  157. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +254 -280
  158. package/project/.sdk/tm/java/test/RunnerSupport.java +9 -194
  159. package/project/.sdk/tm/java/test/StructCorpusTest.java +119 -42
  160. package/project/.sdk/tm/java/test/vendor/omni/Json.java +287 -0
  161. package/project/.sdk/tm/java/test/vendor/omni/Runner.java +851 -0
  162. package/project/.sdk/tm/java/test/vendor/omni/Util.java +322 -0
  163. package/project/.sdk/tm/java/utility/MakeSpec.java +3 -1
  164. package/project/.sdk/tm/java/utility/PrepareMethod.java +5 -5
  165. package/project/.sdk/tm/java/utility/struct/Struct.java +17 -4
  166. package/project/.sdk/tm/js/src/utility/StructUtility.js +3 -3
  167. package/project/.sdk/tm/js/test/omni.js +251 -0
  168. package/project/.sdk/tm/js/test/omni.test.js +105 -0
  169. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +6 -2
  170. package/project/.sdk/tm/js/test/utility/StructUtility.test.js +27 -2
  171. package/project/.sdk/tm/js/test/vendor/omni/index.js +77 -0
  172. package/project/.sdk/tm/js/test/vendor/omni/runner.js +628 -0
  173. package/project/.sdk/tm/js/test/vendor/omni/util.js +229 -0
  174. package/project/.sdk/tm/kotlin/core/Utility.kt +1 -1
  175. package/project/.sdk/tm/kotlin/test/OmniResolver.kt +343 -0
  176. package/project/.sdk/tm/kotlin/test/OmniSmokeTest.kt +100 -0
  177. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +244 -262
  178. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +9 -178
  179. package/project/.sdk/tm/kotlin/test/StructCorpusTest.kt +121 -32
  180. package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +264 -0
  181. package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +615 -0
  182. package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +139 -0
  183. package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -3
  184. package/project/.sdk/tm/kotlin/utility/Prepare.kt +6 -6
  185. package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +18 -2
  186. package/project/.sdk/tm/lean/Makefile +12 -5
  187. package/project/.sdk/tm/lean/src/SdkUtility.lean +14 -1
  188. package/project/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  189. package/project/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  190. package/project/.sdk/tm/lean/test/StructCorpus.lean +245 -574
  191. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +155 -291
  192. package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  193. package/project/.sdk/tm/lua/test/omni.lua +456 -0
  194. package/project/.sdk/tm/lua/test/omni_smoke_test.lua +103 -0
  195. package/project/.sdk/tm/lua/test/primary_utility_test.lua +250 -509
  196. package/project/.sdk/tm/lua/test/struct_utility_test.lua +161 -70
  197. package/project/.sdk/tm/lua/test/vendor/omni/json.lua +268 -0
  198. package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +385 -0
  199. package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +641 -0
  200. package/project/.sdk/tm/lua/test/vendor/omni/util.lua +282 -0
  201. package/project/.sdk/tm/lua/utility/prepare_method.lua +5 -1
  202. package/project/.sdk/tm/lua/utility/struct/regex.lua +663 -0
  203. package/project/.sdk/tm/lua/utility/struct/struct.lua +660 -420
  204. package/project/.sdk/tm/ocaml/Makefile +37 -12
  205. package/project/.sdk/tm/ocaml/test/omni_resolver.ml +284 -0
  206. package/project/.sdk/tm/ocaml/test/omni_smoke_test.ml +169 -0
  207. package/project/.sdk/tm/ocaml/test/primary_utility_test.ml +84 -100
  208. package/project/.sdk/tm/ocaml/test/struct_corpus.ml +225 -201
  209. package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +1157 -0
  210. package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +88 -12
  211. package/project/.sdk/tm/perl/t/omni.pm +647 -0
  212. package/project/.sdk/tm/perl/t/omni_smoke.t +87 -0
  213. package/project/.sdk/tm/perl/t/primary_utility.t +189 -487
  214. package/project/.sdk/tm/perl/t/struct_utility.t +455 -389
  215. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +649 -0
  216. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +253 -0
  217. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +24 -0
  218. package/project/.sdk/tm/perl/utility/prepare_method.pm +7 -2
  219. package/project/.sdk/tm/php/test/Omni.php +691 -0
  220. package/project/.sdk/tm/php/test/OmniSmokeTest.php +93 -0
  221. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +210 -571
  222. package/project/.sdk/tm/php/test/StructUtilityTest.php +320 -342
  223. package/project/.sdk/tm/php/test/vendor/omni/Runner.php +644 -0
  224. package/project/.sdk/tm/php/test/vendor/omni/Util.php +283 -0
  225. package/project/.sdk/tm/php/utility/MakeSpec.php +10 -3
  226. package/project/.sdk/tm/php/utility/PrepareBody.php +7 -1
  227. package/project/.sdk/tm/php/utility/PrepareMethod.php +6 -2
  228. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +36 -0
  229. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +141 -0
  230. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +50 -0
  231. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +333 -0
  232. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +198 -0
  233. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +147 -0
  234. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +52 -0
  235. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +139 -0
  236. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1053 -0
  237. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +171 -0
  238. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +95 -0
  239. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +116 -0
  240. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +59 -0
  241. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +87 -0
  242. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +112 -0
  243. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +76 -0
  244. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +116 -0
  245. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +192 -0
  246. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +120 -0
  247. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +140 -0
  248. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +62 -0
  249. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +101 -0
  250. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +151 -0
  251. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +115 -0
  252. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +90 -0
  253. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +101 -0
  254. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +119 -0
  255. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +125 -0
  256. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +211 -0
  257. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +475 -0
  258. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +467 -0
  259. package/project/.sdk/tm/py/pkg/utility/prepare_method.py +5 -1
  260. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/__init__.py +0 -2
  261. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +780 -529
  262. package/project/.sdk/tm/py/src/feature/secrets/.gitkeep +0 -0
  263. package/project/.sdk/tm/py/test/feature/__init__.py +0 -0
  264. package/project/.sdk/tm/py/test/feature/secrets/__init__.py +0 -0
  265. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +337 -0
  266. package/project/.sdk/tm/py/test/omni.py +415 -0
  267. package/project/.sdk/tm/py/test/test_omni_smoke.py +74 -0
  268. package/project/.sdk/tm/py/test/test_primary_utility.py +144 -668
  269. package/project/.sdk/tm/py/test/test_struct_utility.py +74 -27
  270. package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +62 -0
  271. package/project/.sdk/tm/py/test/voxgig_omni/runner.py +580 -0
  272. package/project/.sdk/tm/py/test/voxgig_omni/util.py +252 -0
  273. package/project/.sdk/tm/rb/test/omni.rb +505 -0
  274. package/project/.sdk/tm/rb/test/omni_smoke_test.rb +72 -0
  275. package/project/.sdk/tm/rb/test/primary_utility_test.rb +174 -560
  276. package/project/.sdk/tm/rb/test/struct_utility_test.rb +13 -7
  277. package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +493 -0
  278. package/project/.sdk/tm/rb/test/vendor/omni/util.rb +199 -0
  279. package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +15 -0
  280. package/project/.sdk/tm/rb/utility/prepare_method.rb +5 -1
  281. package/project/.sdk/tm/rust/tests/common/mod.rs +19 -242
  282. package/project/.sdk/tm/rust/tests/omni_resolver/mod.rs +888 -0
  283. package/project/.sdk/tm/rust/tests/omni_smoke_test.rs +286 -0
  284. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +318 -312
  285. package/project/.sdk/tm/rust/tests/struct_utility_test.rs +66 -28
  286. package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +412 -0
  287. package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +38 -0
  288. package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +392 -0
  289. package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +1001 -0
  290. package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +161 -0
  291. package/project/.sdk/tm/rust/utility/prepare_method.rs +5 -1
  292. package/project/.sdk/tm/scala/Makefile +16 -6
  293. package/project/.sdk/tm/scala/sdktest/OmniResolver.scala +497 -0
  294. package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +192 -0
  295. package/project/.sdk/tm/scala/sdktest/PrimaryCorpus.scala +47 -19
  296. package/project/.sdk/tm/scala/sdktest/StructCorpus.scala +0 -0
  297. package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +229 -0
  298. package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +552 -0
  299. package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +104 -0
  300. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Constants.swift +10 -0
  301. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Inject.swift +28 -5
  302. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Injection.swift +5 -1
  303. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Minor.swift +4 -1
  304. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Validate.swift +15 -5
  305. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +6 -1
  306. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift +474 -0
  307. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniSmokeTest.swift +107 -0
  308. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +141 -178
  309. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/Runner.swift +17 -113
  310. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/StructUtilityTest.swift +295 -446
  311. package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +364 -0
  312. package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +730 -0
  313. package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +162 -0
  314. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +7 -0
  315. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +148 -0
  316. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +55 -0
  317. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +344 -0
  318. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +205 -0
  319. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +138 -0
  320. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +46 -0
  321. package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +349 -0
  322. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +181 -0
  323. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1132 -0
  324. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +177 -0
  325. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +119 -0
  326. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +102 -0
  327. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +61 -0
  328. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +112 -0
  329. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +100 -0
  330. package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +37 -0
  331. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +163 -30
  332. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +27 -22
  333. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/aws.ts +26 -36
  334. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/azuresecrets.ts +19 -21
  335. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/boru.ts +36 -17
  336. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/doppler.ts +14 -21
  337. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/gcpsecrets.ts +27 -27
  338. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/hashicorp.ts +25 -39
  339. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +99 -0
  340. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/infisical.ts +14 -16
  341. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/onepassword.ts +15 -22
  342. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +98 -0
  343. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{Sigv4.ts → plugins/sigv4.ts} +7 -6
  344. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +97 -23
  345. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +37 -0
  346. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +4 -17
  347. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +4 -16
  348. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +11 -25
  349. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +6 -23
  350. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +106 -39
  351. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +3 -3
  352. package/project/.sdk/tm/ts/test/omni.ts +104 -32
  353. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +27 -0
  354. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +32 -5
  355. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +2 -2
  356. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +2 -2
  357. package/project/.sdk/tm/zig/Makefile +15 -1
  358. package/project/.sdk/tm/zig/build.zig +23 -5
  359. package/project/.sdk/tm/zig/core/helpers.zig +52 -11
  360. package/project/.sdk/tm/zig/core/mem.zig +17 -1
  361. package/project/.sdk/tm/zig/core/utility.zig +23 -19
  362. package/project/.sdk/tm/zig/feature/audit.zig +2 -2
  363. package/project/.sdk/tm/zig/feature/cache.zig +2 -2
  364. package/project/.sdk/tm/zig/feature/debug.zig +5 -5
  365. package/project/.sdk/tm/zig/feature/netsim.zig +2 -2
  366. package/project/.sdk/tm/zig/feature/paging.zig +2 -2
  367. package/project/.sdk/tm/zig/feature/proxy.zig +15 -8
  368. package/project/.sdk/tm/zig/feature/streaming.zig +5 -5
  369. package/project/.sdk/tm/zig/feature/support.zig +3 -3
  370. package/project/.sdk/tm/zig/feature/telemetry.zig +5 -5
  371. package/project/.sdk/tm/zig/feature/test.zig +10 -5
  372. package/project/.sdk/tm/zig/test/fh.zig +10 -10
  373. package/project/.sdk/tm/zig/test/gotcha_test.zig +5 -5
  374. package/project/.sdk/tm/zig/test/omniresolver.zig +515 -0
  375. package/project/.sdk/tm/zig/test/omnismoke_test.zig +284 -0
  376. package/project/.sdk/tm/zig/test/pipeline_test.zig +8 -8
  377. package/project/.sdk/tm/zig/test/primary_utility_test.zig +145 -155
  378. package/project/.sdk/tm/zig/test/struct_corpus.zig +264 -187
  379. package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +1314 -0
  380. package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +446 -0
  381. package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +7 -4
  382. package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +356 -157
  383. package/project/sdkgen-package.json +1 -1
  384. package/src/action/doctor.ts +66 -2
  385. package/src/helpers/naming.ts +4 -2
  386. package/project/.sdk/tm/c/tests/runner.h +0 -274
  387. package/project/.sdk/tm/cpp/test/struct_runner.hpp +0 -314
  388. package/project/.sdk/tm/csharp/test/StructRunner.cs +0 -276
  389. package/project/.sdk/tm/dart/test/runner.dart +0 -406
  390. package/project/.sdk/tm/dart/test/struct_corpus.dart +0 -531
  391. package/project/.sdk/tm/elixir/test/support/struct_corpus.ex +0 -1088
  392. package/project/.sdk/tm/go/test/runner_test.go +0 -629
  393. package/project/.sdk/tm/go/test/struct_runner_test.go +0 -1094
  394. package/project/.sdk/tm/java/test/StructRunner.java +0 -281
  395. package/project/.sdk/tm/js/test/runner.js +0 -387
  396. package/project/.sdk/tm/kotlin/test/StructRunner.kt +0 -177
  397. package/project/.sdk/tm/lua/test/struct_runner.lua +0 -602
  398. package/project/.sdk/tm/ocaml/test/corpus_runner.ml +0 -185
  399. package/project/.sdk/tm/perl/t/struct_runner.pm +0 -275
  400. package/project/.sdk/tm/php/test/StructRunner.php +0 -275
  401. package/project/.sdk/tm/py/test/struct_runner.py +0 -411
  402. package/project/.sdk/tm/rb/test/struct_runner.rb +0 -309
  403. package/project/.sdk/tm/rust/tests/struct_runner/mod.rs +0 -424
  404. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +0 -90
  405. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +0 -66
  406. package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +0 -188
  407. package/project/.sdk/tm/zig/test/struct_runner.zig +0 -464
@@ -0,0 +1,1132 @@
1
+ // VENDORED: @voxgig/plugin 0.1.6 (typescript/src/Host.ts)
2
+ // Source: https://github.com/voxgig/plugin @ b48ae643eb0eb56c5ebe3198da98cecdf6a7f7fc [tag: sdk-20260907-0029-0]
3
+ // License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ /* The host: the lifecycle state machine (§5), extension points (§6),
5
+ * and resource capture (§8).
6
+ *
7
+ * TWO RULES SHAPE EVERY METHOD BELOW.
8
+ *
9
+ * Transitions are SEQUENTIAL (§5.2). One at a time, in call order,
10
+ * never interleaved; a transition triggered from inside a lifecycle
11
+ * callback is `plugin_reentrant`. A hard rule, because it is the only
12
+ * way the semantics can be identical in Go, in Ruby and in
13
+ * single-threaded JavaScript.
14
+ *
15
+ * Reconciliation is EAGER (§18's portability budget). A transition
16
+ * settles by running the state machine to a fixed point, not by
17
+ * suspending on a promise. Every port must be able to do the same, and
18
+ * fourteen of them will not have JavaScript's event loop. */
19
+
20
+ import { Status, Instance, OrderBlock, fail } from './Types'
21
+ import { canonref, tryref, parseref, formatref } from './Ref'
22
+ import { Catalog, Definition, makecatalog } from './Catalog'
23
+ import { resolveorder, Binding, Pin } from './Order'
24
+ import { Spec, Bound, Mode, emit as fanout, compose, provider as pickone } from './Point'
25
+ import { Exported, resolveexport } from './Export'
26
+ import { Provided, Required, Candidate, resolvecapability } from './Capability'
27
+ import { normalizeconfig, resolveoptions } from './Config'
28
+ import {
29
+ Node, checkcycle, gatesactivation, requirements, restartsonloss,
30
+ } from './Depend'
31
+
32
+ export type PointSpec = Spec
33
+
34
+ export type HostOptions = {
35
+ catalog?: Catalog
36
+ reserved?: string[]
37
+ keys?: { instance?: string, default?: string }
38
+ defaults?: { [name: string]: any }
39
+ profile?: string
40
+ points?: { [point: string]: PointSpec }
41
+ /** §11.3. `restart` (the default) treats provider replacement as an
42
+ * ordinary runtime operation: deactivate the old store, activate the
43
+ * new one, and everything that depended on it rides through, having
44
+ * released the old one's resources in between.
45
+ *
46
+ * `hold` is the strict reading — deactivating a required instance is
47
+ * `plugin_dependency_held`, naming the holders. NOT the default,
48
+ * because a station that cannot swap a provider without a restart
49
+ * has lost the argument for having a plugin system. */
50
+ dependency?: 'restart' | 'hold'
51
+ }
52
+
53
+ type Live = {
54
+ ref: string
55
+ def: Definition
56
+ status: Status
57
+ pos: number
58
+ seq: number
59
+ options: any
60
+ state: any
61
+ order?: OrderBlock
62
+ /** §11.4's ALWAYS-RELUCTANT rebinding, made concrete: the provider
63
+ * ref this instance's activation actually selected, per requirement
64
+ * name. "A satisfied requirement is not re-bound while it stays
65
+ * satisfied" is a statement about a REMEMBERED choice — recomputing
66
+ * `providersof(r)[0]` on every question silently re-points a live
67
+ * consumer at any better-ranked newcomer, and then losing the
68
+ * provider it was really using does not restart it. Captured at
69
+ * activate, cleared on the way out. */
70
+ selected: { [name: string]: string }
71
+ /** §9.6's `active: false` — "declares it and bars it: it appears in
72
+ * `host.list()`, and `activate` and `ready` on it fail rather than
73
+ * quietly doing nothing". THE BAR OUTLIVES THE APPLY THAT SET IT: a
74
+ * flag consulted only while `apply` ran let a later direct `ready`
75
+ * bring the instance live, which is the config-switch it exists to
76
+ * be silently ignored. */
77
+ barred?: boolean
78
+ /** Requirements this instance declared but has not been given. */
79
+ unmet: string[]
80
+ /** Resources the instance scope holds, newest last — unwound in
81
+ * REVERSE, because that is the only order in which teardown mirrors
82
+ * setup (§8.3). */
83
+ scope: (() => void)[]
84
+ /** Declared in `define`, inserted only when activation SUCCEEDS
85
+ * (§8.1). Holding them until then is what makes a failed activate
86
+ * leave nothing behind. */
87
+ bindings: Bound[]
88
+ /** Set when this instance is itself a host (§6.5). */
89
+ inner?: any
90
+ /** Declared in `define`, and VISIBLE while merely `loaded` (§11):
91
+ * they are data, and hiding them would make the loaded state useless
92
+ * for introspection. */
93
+ exports: { [key: string]: any }
94
+ provides: Provided[]
95
+ }
96
+
97
+ export type Host = ReturnType<typeof makehost>
98
+
99
+ export function makehost(options?: HostOptions) {
100
+ const dependency = (options && options.dependency) || 'restart'
101
+ /** Set for the duration of a bulk teardown, so `held` knows this is a
102
+ * coordinated operation rather than an ad-hoc deactivation. */
103
+ let coordinated = false
104
+
105
+ const opts = options || {}
106
+ const catalog = opts.catalog || makecatalog()
107
+ const reserved = opts.reserved || []
108
+ const points = opts.points || {}
109
+
110
+ const inst: { [ref: string]: Live } = {}
111
+ const log: string[] = []
112
+ /** §14: the lifecycle event record. `seq` distinguishes ONE
113
+ * INCARNATION of stripe$test from the next, which is the whole reason
114
+ * it is not `pos` (§4 rule 4). */
115
+ const events: { ref: string, event: string, seq: number, status: Status }[] = []
116
+ let seqn = 0
117
+ let open = 0
118
+ let intransition = false
119
+ /** WHICH callback is running, not merely that one is. §8.1 puts
120
+ * resource capture in `activate` and §8.3 says `inst.release` outside
121
+ * `activate` is `plugin_release_scope` — and `intransition` alone
122
+ * cannot tell `activate` from `define`, so it admitted an acquire in
123
+ * `define` whose scope `unload` would never unwind. */
124
+ let phase: string | null = null
125
+
126
+ // --- observation -------------------------------------------------
127
+
128
+ /** Introspection NEVER advances the state (§5.2). A status page must
129
+ * not be a way to accidentally import twenty packages. */
130
+ const list = (): { [ref: string]: Status } => {
131
+ const out: { [ref: string]: Status } = {}
132
+ for (const r of Object.keys(inst).sort()) out[r] = inst[r].status
133
+ return out
134
+ }
135
+
136
+ const instance = (ref: string): Live | undefined => inst[canonref(ref)]
137
+
138
+ const observable = (result?: any) => ({
139
+ status: list(),
140
+ open,
141
+ log: log.slice(),
142
+ result: undefined === result ? null : result,
143
+ })
144
+
145
+ // --- the state machine -------------------------------------------
146
+
147
+ function guard(): void {
148
+ if (intransition) {
149
+ fail('plugin_reentrant', 'transition attempted from inside a lifecycle callback')
150
+ }
151
+ }
152
+
153
+ function need(ref: string): Live {
154
+ const r = canonref(ref)
155
+ const e = inst[r]
156
+ if (!e) fail('plugin_not_loaded', 'no such instance: ' + r, { ref: r })
157
+ return e
158
+ }
159
+
160
+ function checkreserved(ref: string): void {
161
+ if (0 === reserved.length) return
162
+ if (-1 !== reserved.indexOf(parseref(ref).name)) {
163
+ fail('plugin_ref_reserved', 'ref is reserved by the host: ' + ref, { ref })
164
+ }
165
+ }
166
+
167
+ function run(e: Live, cb: keyof Definition, at: string): void {
168
+ const fn = e.def[cb] as any
169
+ log.push(e.ref + ':' + at)
170
+ events.push({ ref: e.ref, event: at, seq: e.seq, status: e.status })
171
+ if ('function' !== typeof fn) return
172
+ intransition = true
173
+ phase = at
174
+ try {
175
+ fn(api(e))
176
+ }
177
+ catch (err: any) {
178
+ // §12: `plugin_define_failed` and its three siblings are "a
179
+ // callback raised; wraps the cause". AN ERROR THAT ALREADY
180
+ // CARRIES A CODE KEEPS IT — the code is the error's identity, and
181
+ // a plugin that raised `store_unreachable` must not have it
182
+ // rewritten. Only a code-less error is wrapped, which is the
183
+ // ordinary case for a callback that let a library error escape.
184
+ if (err && err.code) throw err
185
+ fail('plugin_' + at + '_failed',
186
+ e.ref + ' raised in ' + at + ': ' + (err && err.message),
187
+ { ref: e.ref, cause: err && err.message })
188
+ }
189
+ finally {
190
+ intransition = false
191
+ phase = null
192
+ }
193
+ }
194
+
195
+ /** What a definition's callbacks see. Deliberately not the internal
196
+ * record: a plugin that could reach `status` could also write it. */
197
+ function api(e: Live) {
198
+ return {
199
+ ref: e.ref,
200
+ name: parseref(e.ref).name,
201
+ tag: parseref(e.ref).tag,
202
+ options: e.options,
203
+ state: e.state,
204
+ /** Foreign resources the host did not hand out are registered
205
+ * explicitly (§8.3); host calls are recorded automatically. */
206
+ release: (fn: () => void) => {
207
+ // §8.3: "`inst.release` outside `activate` is
208
+ // `plugin_release_scope`". `intransition` is true in `define`
209
+ // too, and a scope entry registered there is never unwound —
210
+ // `unload` on a merely `loaded` instance does not call `unwind`,
211
+ // because a loaded instance is not supposed to hold anything.
212
+ if ('activate' !== phase) {
213
+ fail('plugin_release_scope', 'release called outside activate')
214
+ }
215
+ // SYMMETRIC WITH `acquire`, and it has to be: `open` counts the
216
+ // resources CURRENTLY HELD, so an entry that is registered and
217
+ // then unwound must leave the count where it found it.
218
+ // Incrementing on registration and never decrementing made
219
+ // every `release` a permanent leak in the counter — invisible
220
+ // only because no corpus entry used `release` at all, which is
221
+ // the gap `resource/scope#release-counts` now closes.
222
+ let done = false
223
+ e.scope.push(() => { if (!done) { done = true; open -= 1; fn() } })
224
+ open += 1
225
+ },
226
+ /** The synthetic counter the driver owns, so "what is open" is
227
+ * data rather than an assertion each port words differently.
228
+ *
229
+ * Returns its own release, so a plugin can hand one back early.
230
+ * The scope still holds the entry and unwinding it twice is a
231
+ * no-op — releasing early must not make teardown wrong. */
232
+ acquire: (): (() => void) => {
233
+ // §8.1: resources are "acquired during `activate` — the scope's
234
+ // actual job". Same reason as `release` above.
235
+ if ('activate' !== phase) {
236
+ fail('plugin_release_scope', 'acquire called outside activate')
237
+ }
238
+ let done = false
239
+ const rel = () => { if (!done) { done = true; open -= 1 } }
240
+ e.scope.push(rel)
241
+ open += 1
242
+ return rel
243
+ },
244
+ host: () => self,
245
+
246
+ /** Bind into a host point. Declared in `define`; the host inserts
247
+ * it only after `activate` returns successfully (§8.1), which is
248
+ * why a failing activate leaves no live binding behind. */
249
+ bind: (point: string, fn: any, band?: number) => {
250
+ // §12's `plugin_bind_scope`: "binding declared outside
251
+ // `define`". §8.1 puts binding declaration in `define` and
252
+ // insertion at a SUCCESSFUL activate, and the guard was the
253
+ // half that never got written — so a binding added from
254
+ // `activate` went live without being part of the loaded
255
+ // definition, and a deactivate/activate cycle appended it
256
+ // again. The code was in the table before anything raised it.
257
+ if ('define' !== phase) {
258
+ fail('plugin_bind_scope', 'bind called outside define: ' + point,
259
+ { ref: e.ref, point })
260
+ }
261
+ if (undefined === points[point]) {
262
+ fail('plugin_point_unknown', 'no such point: ' + point, { point })
263
+ }
264
+ e.bindings.push({ ref: e.ref, point, fn, band: band || 0 })
265
+ },
266
+
267
+ /** Published for other plugins and for the application (§11). */
268
+ export: (key: string, value: any) => { e.exports[key] = value },
269
+
270
+ /** What this instance can do for others (§11.1). */
271
+ provides: (p: Provided) => { e.provides.push(p) },
272
+
273
+ /** Where this binding landed (§6.6) — the plugin-side counterpart
274
+ * to a host pin. Station found that a plugin can need to KNOW it
275
+ * is in the right place: its middleware must sit immediately
276
+ * outside the base transport or its "wire truth" events are
277
+ * fiction.
278
+ *
279
+ * THE HOST DOES NOT POLICE THIS; it just makes the fact
280
+ * available. A plugin that requires a position it did not get
281
+ * fails loudly rather than reporting nonsense — and that is the
282
+ * plugin's call, because only it knows what its position means.
283
+ * Verification tells a plugin it was misplaced; a pin (§7) stops
284
+ * the misplacement from being expressible at all. The two are not
285
+ * substitutes. */
286
+ position: (point: string) => {
287
+ const ranked = order(point)
288
+ const index = ranked.indexOf(e.ref)
289
+ return {
290
+ index,
291
+ count: ranked.length,
292
+ // §6.2 composes b1(b2(b3(base))) with the FIRST binding
293
+ // OUTERMOST, so these are not index 0 and index count-1 the
294
+ // other way round. Getting this backwards is the exact error
295
+ // the positional pin vocabulary exists to prevent.
296
+ outermost: 0 === index,
297
+ innermost: index === ranked.length - 1,
298
+ }
299
+ },
300
+
301
+ /** AN INSTANCE MAY ITSELF BE A HOST (§6.5), and THE OUTER ONE
302
+ * OWNS THE INNER ONE'S LIFETIME. Registering the teardown in the
303
+ * instance scope is what makes that true rather than aspirational:
304
+ * the inner host closes when the outer instance deactivates, in
305
+ * the same reverse unwind as every other resource. */
306
+ nest: (nestopts?: HostOptions) => {
307
+ if (!intransition) {
308
+ fail('plugin_release_scope', 'nest called outside a lifecycle callback')
309
+ }
310
+ const inner = makehost(nestopts)
311
+ e.scope.push(() => inner.close())
312
+ e.inner = inner
313
+ return inner
314
+ },
315
+ }
316
+ }
317
+
318
+ /** AUTO-TAGGING IS EXPLICIT (§4 rule 3). `declare('stripe', {tag:
319
+ * '?'})` assigns the LOWEST UNUSED POSITIVE INTEGER tag and returns
320
+ * the assigned pair. Without `'?'`, a collision is an error.
321
+ *
322
+ * It needs a host because it must know what is already declared,
323
+ * which is why it cannot live in the pure `ref` section — the
324
+ * correction P1.7 made to §15.3. */
325
+ function autotag(name: string): string {
326
+ for (let n = 1; ; n++) {
327
+ const cand = formatref(name, String(n))
328
+ if (undefined === inst[cand]) return cand
329
+ }
330
+ }
331
+
332
+ type DeclareSpec = {
333
+ definition?: string, options?: any, order?: OrderBlock,
334
+ pos?: number, tag?: string,
335
+ /** §9.1: "The host declares those instances itself, after the user
336
+ * merge, and always wins." Set ONLY by `hostdeclare`. */
337
+ hostowned?: boolean,
338
+ }
339
+
340
+ function declare(ref: string, spec?: DeclareSpec): Live {
341
+ if (spec && '?' === spec.tag) {
342
+ ref = autotag(parseref(canonref(ref)).name)
343
+ }
344
+ const r = canonref(ref)
345
+ if (!(spec && spec.hostowned)) checkreserved(r)
346
+ const s = spec || {}
347
+ const defname = s.definition || parseref(r).name
348
+ const def = catalog.get(defname)
349
+ if (!def) {
350
+ fail('plugin_unknown_definition', 'not in catalog: ' + defname, { name: defname })
351
+ }
352
+
353
+ const existing = inst[r]
354
+ if (existing) {
355
+ // §4 rule 1: a pair addresses at most one instance. Re-declaring
356
+ // the SAME definition is the idempotent case; a different one is
357
+ // a duplicate, not a silent overwrite (seneca) and not an
358
+ // impossibility (sdkgen).
359
+ if (existing.def.name !== def.name) {
360
+ fail('plugin_ref_duplicate', 'instance already declared: ' + r, { ref: r })
361
+ }
362
+ return existing
363
+ }
364
+
365
+ const e: Live = {
366
+ ref: r, def, status: 'declared',
367
+ pos: undefined === s.pos ? Object.keys(inst).length : s.pos,
368
+ seq: seqn++,
369
+ options: s.options || {},
370
+ state: {}, order: s.order, unmet: [], scope: [],
371
+ bindings: [], exports: {}, provides: [], selected: {},
372
+ }
373
+ inst[r] = e
374
+ return e
375
+ }
376
+
377
+ function load(ref: string, spec?: any): Live {
378
+ guard()
379
+ const e = declare(ref, spec)
380
+ if ('declared' !== e.status) return e // idempotent in the trivial direction
381
+ if (spec && spec.options) e.options = spec.options
382
+ try {
383
+ run(e, 'define', 'define')
384
+ }
385
+ catch (err: any) {
386
+ e.status = 'failed'
387
+ throw err
388
+ }
389
+ e.status = 'loaded'
390
+
391
+ // AT LOAD, and before anything runs: a cycle through
392
+ // restart-causing requirements does not settle, and the only safe
393
+ // time to report a non-terminating reconcile is before it starts
394
+ // (§11.3). `provides` is populated by `define`, which has just run,
395
+ // so this is the first moment the graph is complete.
396
+ try { checkcycle(graphnodes()) }
397
+ catch (err: any) {
398
+ e.status = 'failed'
399
+ throw err
400
+ }
401
+ return e
402
+ }
403
+
404
+ /** The requirement graph as plain data, for the pure detector. */
405
+ function graphnodes(): Node[] {
406
+ return Object.keys(inst).sort().map((r) => ({
407
+ ref: r,
408
+ provides: inst[r].provides.map((p) => p.name),
409
+ requires: requirements(inst[r].options),
410
+ }))
411
+ }
412
+
413
+ function activate(ref: string): Live {
414
+ guard()
415
+ const e = need(ref)
416
+ if ('live' === e.status) return e // no-op returning success
417
+ if ('failed' === e.status) {
418
+ fail('plugin_bad_state', 'instance has failed: ' + e.ref, { ref: e.ref })
419
+ }
420
+ // §9.6: `active: false` bars the instance from running, and the bar
421
+ // is on the INSTANCE rather than on the apply that set it. `ready`
422
+ // reaches this through `activate`, which is why one guard covers
423
+ // both verbs the design names.
424
+ if (e.barred) {
425
+ fail('plugin_inactive', 'instance is barred by active: false: ' + e.ref,
426
+ { ref: e.ref })
427
+ }
428
+ if ('declared' === e.status) load(e.ref)
429
+
430
+ // A declared requirement that is not live means `pending`:
431
+ // activation is a STANDING REQUEST, not a one-shot event.
432
+ if (0 < unmetof(e).length) {
433
+ e.unmet = unmetof(e)
434
+ e.status = 'pending'
435
+ return e
436
+ }
437
+
438
+ try {
439
+ run(e, 'activate', 'activate')
440
+ }
441
+ catch (err: any) {
442
+ // Unwind whatever the partial activation captured, in reverse.
443
+ unwind(e)
444
+ e.status = 'failed'
445
+ throw err
446
+ }
447
+ // §11.4: THE SELECTION IS MADE HERE, once, and remembered. Every
448
+ // later question — the cascade, `hold`, `unmet` — reads it back
449
+ // rather than re-ranking, which is what "always-reluctant" means.
450
+ for (const r of requirements(e.options)) chosen(e, r, true)
451
+ e.status = 'live'
452
+ reconcile()
453
+ return e
454
+ }
455
+
456
+ function deactivate(ref: string): Live {
457
+ guard()
458
+ const e = need(ref)
459
+ if ('loaded' === e.status || 'declared' === e.status) return e
460
+
461
+ // §5.2: `unload` is THE ONLY TRANSITION OUT OF `failed`. Falling
462
+ // through here ran the definition's `deactivate` on an instance that
463
+ // never completed activation and, if that callback happened to
464
+ // succeed, returned it to `loaded` — from where it could be
465
+ // activated again, which is precisely what `failed` exists to
466
+ // prevent.
467
+ if ('failed' === e.status) {
468
+ fail('plugin_bad_state', 'instance has failed: ' + e.ref, { ref: e.ref })
469
+ }
470
+
471
+ if ('pending' === e.status) {
472
+ // DEACTIVATING A PENDING INSTANCE RUNS NO CALLBACK (§5.2). It
473
+ // never reached activate, so it holds no scope and no live
474
+ // bindings; running the definition's deactivate there would be
475
+ // teardown without matching setup, which plugins are not written
476
+ // to survive and which could fail an instance that had done
477
+ // nothing wrong. It cannot fail.
478
+ e.status = 'loaded'
479
+ e.unmet = []
480
+ return e
481
+ }
482
+
483
+ held(e)
484
+ cascade(e)
485
+
486
+ try {
487
+ run(e, 'deactivate', 'deactivate')
488
+ }
489
+ catch (err: any) {
490
+ unwind(e)
491
+ e.status = 'failed'
492
+ throw err
493
+ }
494
+ releasecheck(e, unwind(e))
495
+ e.status = 'loaded'
496
+ reconcile()
497
+ return e
498
+ }
499
+
500
+ function unload(ref: string): void {
501
+ guard()
502
+ const e = need(ref)
503
+ if ('live' === e.status || 'pending' === e.status) {
504
+ if ('live' === e.status) {
505
+ held(e)
506
+ cascade(e)
507
+ try {
508
+ run(e, 'deactivate', 'deactivate')
509
+ }
510
+ catch (err: any) {
511
+ // §5.2: ANY failure during a transition lands the instance in
512
+ // `failed`, with the scope STILL FULLY UNWOUND. An earlier
513
+ // draft let the raise propagate straight out of `unload`,
514
+ // which left the instance `live` and its scope untouched —
515
+ // reporting a failure while leaking exactly the resources the
516
+ // failure was about, and leaving an instance whose bindings
517
+ // were never removed still participating in every point.
518
+ unwind(e)
519
+ e.status = 'failed'
520
+ throw err
521
+ }
522
+ releasecheck(e, unwind(e))
523
+ }
524
+ e.status = 'loaded'
525
+ }
526
+ if ('loaded' === e.status || 'failed' === e.status) {
527
+ try { run(e, 'close', 'close') }
528
+ finally { delete inst[e.ref] }
529
+ return
530
+ }
531
+ delete inst[e.ref]
532
+ }
533
+
534
+ function ready(ref: string): Live {
535
+ // Runs the whole forward path in one call (§5.1). §15.2's verb list
536
+ // omits this; §5.1 defines it and §15.3's `declare` row requires the
537
+ // corpus to pin it, so the list was incomplete rather than
538
+ // excluding it (DOCS.md §4.2).
539
+ guard()
540
+ const r = canonref(ref)
541
+ if (!inst[r]) declare(r)
542
+ if ('declared' === inst[r].status) load(r)
543
+ return activate(r)
544
+ }
545
+
546
+ /** Bindings go live only when activation succeeds (§8.1), so the
547
+ * teardown is the exact inverse: reverse order, always.
548
+ *
549
+ * Returns the errors the scope raised. §8.3: "A failing release does
550
+ * not stop the rest. Every entry runs, in reverse order, whatever any
551
+ * of them does; the errors are collected and raised as one
552
+ * `plugin_release_failed`." An earlier draft swallowed them, which
553
+ * left the host reporting a clean `loaded` for an instance that may
554
+ * still be holding what it failed to give back. */
555
+ /** A selection belongs to ONE activation (§11.4). Leaving `live` by
556
+ * any door drops it, so the next activation ranks afresh — keeping it
557
+ * would make a consumer prefer a provider it never actually ran
558
+ * against. */
559
+ function unwind(e: Live): any[] {
560
+ e.selected = {}
561
+ const errors: any[] = []
562
+ for (let i = e.scope.length - 1; 0 <= i; i--) {
563
+ try { e.scope[i]() } catch (err) { errors.push(err) }
564
+ }
565
+ e.scope = []
566
+ return errors
567
+ }
568
+
569
+ /** §8.3: "A failed release ends the instance in `failed`, exactly as a
570
+ * failed callback does (§5.2) — a release that raised may have leaked,
571
+ * and an instance that may be holding resources it cannot account for
572
+ * must not be reactivated." */
573
+ function releasecheck(e: Live, errors: any[]): void {
574
+ if (0 === errors.length) return
575
+ e.status = 'failed'
576
+ const causes = errors.map((x) => (x && x.message) || String(x))
577
+ fail('plugin_release_failed',
578
+ 'release failed for ' + e.ref + ': ' + causes.join('; '),
579
+ { ref: e.ref, cause: causes })
580
+ }
581
+
582
+ /** A REQUIREMENT IS ON A CAPABILITY, not on a ref (§11.1) — it is a
583
+ * dependency on something that can do the job, and which instance is
584
+ * doing it is exactly the configuration detail a plugin must not care
585
+ * about. A bare string is shorthand for `{name}`.
586
+ *
587
+ * A ref satisfies too, because a host that genuinely needs a specific
588
+ * instance should not have to invent a capability for it. */
589
+ function unmetof(e: Live): string[] {
590
+ return requirements(e.options)
591
+ .filter(gatesactivation)
592
+ .filter((r) => 0 === providersof(r).length)
593
+ .map((r) => r.name)
594
+ }
595
+
596
+ /** §11.4's always-reluctant selection, and the ONE place a provider
597
+ * is chosen for a live instance.
598
+ *
599
+ * "A satisfied requirement is not re-bound while it stays satisfied."
600
+ * So: if this instance already selected a provider for `req` and that
601
+ * provider is STILL among the candidates, it keeps it — a
602
+ * better-ranked newcomer does not take it. Otherwise the rank
603
+ * decides, and the choice is remembered.
604
+ *
605
+ * `remember` is false for the questions asked ABOUT an instance
606
+ * rather than BY it — introspection must not create a binding. */
607
+ function chosen(e: Live, req: Required, remember: boolean): string | undefined {
608
+ const cands = providersof(req)
609
+ if (0 === cands.length) return undefined
610
+ const held = e.selected[req.name]
611
+ if (undefined !== held && cands.some((c) => c.ref === held)) return held
612
+ if (remember) e.selected[req.name] = cands[0].ref
613
+ return cands[0].ref
614
+ }
615
+
616
+ /** The instance currently SELECTED for each of this one's
617
+ * restart-causing requirements. A BINDING IS TO AN INSTANCE, not to a
618
+ * capability (§11.1), and that is what decides behaviour when the
619
+ * bound provider leaves while another match remains: the selected one
620
+ * going away restarts a `static` consumer even though a survivor is
621
+ * available. It is not silently re-pointed — `static` is the plugin
622
+ * saying in writing that it cannot survive a provider swap, and a
623
+ * survivor being available does not make the swap survivable. */
624
+ function boundproviders(e: Live): string[] {
625
+ const out: string[] = []
626
+ for (const r of requirements(e.options)) {
627
+ if (!restartsonloss(r)) continue
628
+ const ref = chosen(e, r, false)
629
+ if (undefined !== ref && -1 === out.indexOf(ref)) out.push(ref)
630
+ }
631
+ return out
632
+ }
633
+
634
+ /** Live instances whose selected provider is `ref` and which would be
635
+ * restarted by losing it. */
636
+ function consumersof(ref: string): string[] {
637
+ return Object.keys(inst).sort().filter((r) => {
638
+ const c = inst[r]
639
+ return r !== ref && 'live' === c.status &&
640
+ -1 !== boundproviders(c).indexOf(ref)
641
+ })
642
+ }
643
+
644
+ /** §11.3's `hold` asks a DIFFERENT question from the cascade, and
645
+ * reading it off `consumersof` answered the cascade's.
646
+ *
647
+ * The cascade wants the edges that RESTART — mandatory-static and
648
+ * optional-static — because that is what it has to walk. `hold` says
649
+ * "deactivating a REQUIRED instance is `plugin_dependency_held`", and
650
+ * `required` is cardinality: `gatesactivation`, not
651
+ * `restartsonloss`. The two sets differ in both directions and each
652
+ * difference was a real bug.
653
+ *
654
+ * A MANDATORY-DYNAMIC consumer was excluded, so the strictest policy
655
+ * let a provider go that a live consumer could not do without —
656
+ * `dynamic` promises the consumer survives a SWAP, and under `hold`
657
+ * there is no swap, so it goes back to `pending`, which is precisely
658
+ * what `hold` exists to prevent.
659
+ *
660
+ * An OPTIONAL-STATIC consumer was included, so `hold` refused a
661
+ * deactivation on behalf of an instance that had said in writing it
662
+ * does not need the thing. Disruptive, yes — it restarts — but the
663
+ * policy's word is `required`, and an optional requirement is the
664
+ * plugin declaring the provider is not. */
665
+ function holdersof(ref: string): string[] {
666
+ return Object.keys(inst).sort().filter((r) => {
667
+ const c = inst[r]
668
+ if (r === ref || 'live' !== c.status) return false
669
+ for (const req of requirements(c.options)) {
670
+ if (!gatesactivation(req)) continue
671
+ if (chosen(c, req, false) === ref) return true
672
+ }
673
+ return false
674
+ })
675
+ }
676
+
677
+ function providersof(req: Required): Candidate[] {
678
+ const cands: Candidate[] = []
679
+ // ASK WHETHER THE NAME IS A REF, do not assume it. A requirement
680
+ // name is a CAPABILITY name first (§11.1) and capability names are
681
+ // free-form, so `2fa` and `my cap` are legal ones that no ref could
682
+ // be called — and `canonref` RAISES on those, which made a perfectly
683
+ // legal document kill the host right here. `tryref` answers
684
+ // `undefined` instead, and still canonicalizes when it is a ref
685
+ // (§4 rule 5), which is what lets `dep$` find `dep`.
686
+ const asref = tryref(req.name)
687
+ for (const ref of Object.keys(inst).sort()) {
688
+ const t = inst[ref]
689
+ if ('live' !== t.status) continue
690
+ // A ref satisfies directly.
691
+ if (ref === asref) {
692
+ cands.push({ ref, pos: t.pos, provides: { name: req.name } })
693
+ continue
694
+ }
695
+ for (const p of t.provides) {
696
+ if (p.name === req.name) cands.push({ ref, pos: t.pos, provides: p })
697
+ }
698
+ }
699
+ return resolvecapability(req, cands)
700
+ }
701
+
702
+ /** CONSUMERS GO DOWN FIRST, NOT AFTERWARDS (§11.3).
703
+ *
704
+ * The cascade is part of the provider's own deactivation and runs
705
+ * BEFORE the provider's `deactivate` callback and scope unwind, so a
706
+ * consumer's teardown can still call the thing it depends on —
707
+ * flushing a buffer to the store it is about to lose is exactly what
708
+ * a `deactivate` callback is for, and a cascade that fired after the
709
+ * provider was already gone would make that impossible.
710
+ *
711
+ * Order: consumers deepest-first, then the provider. `unload` and
712
+ * `close` inherit it, UNDER EITHER DEPENDENCY POLICY, which is what
713
+ * makes apply's reverse-load-order teardown safe even when a document
714
+ * happens to list a consumer before its provider. */
715
+ function cascade(provider: Live, seen?: { [ref: string]: true }): void {
716
+ const done = seen || {}
717
+ if (done[provider.ref]) return
718
+ done[provider.ref] = true
719
+
720
+ for (const r of consumersof(provider.ref)) {
721
+ const c = inst[r]
722
+ if ('live' !== c.status) continue
723
+ cascade(c, done) // deepest-first
724
+ let bad = false
725
+ try { run(c, 'deactivate', 'deactivate') } catch (err) { bad = true }
726
+ const errors = unwind(c)
727
+ if (bad || 0 < errors.length) {
728
+ // §5.2: ANY failure during a transition lands the instance in
729
+ // `failed`, and a cascaded consumer is not an exception.
730
+ // Marking it `pending` instead handed it straight back to
731
+ // `reconcile`, which would activate it again the moment the
732
+ // provider returned — the one thing `failed` exists to stop.
733
+ c.status = 'failed'
734
+ continue
735
+ }
736
+ c.status = 'pending'
737
+ c.unmet = unmetof(c)
738
+ }
739
+ }
740
+
741
+ /** The hold check is A GUARD ON AD-HOC DEACTIVATION, NOT ON
742
+ * COORDINATED TEARDOWN. In a bulk operation that is removing the
743
+ * holders too — `close()`, or an `apply` plan whose own steps
744
+ * deactivate them — it is suspended for exactly those holders, and
745
+ * the teardown still runs consumers before providers.
746
+ *
747
+ * Otherwise `close()` under `hold` would raise on the first provider
748
+ * it reached whenever a document happened to list a consumer after
749
+ * it, which is the policy refusing to allow the one teardown it has
750
+ * no reason to object to. */
751
+ function held(e: Live): void {
752
+ if ('hold' !== dependency) return
753
+ if (coordinated) return
754
+ const holders = holdersof(e.ref)
755
+ if (0 === holders.length) return
756
+ fail('plugin_dependency_held',
757
+ 'instance is required by live consumers: ' + e.ref,
758
+ { ref: e.ref, holders })
759
+ }
760
+
761
+ /** EAGER reconciliation: run to a fixed point rather than scheduling.
762
+ *
763
+ * Two directions, and both are the reason `pending` exists.
764
+ * Activation is a STANDING REQUEST, not a one-shot event: a pending
765
+ * instance whose requirement arrives activates without being asked
766
+ * again, and a LIVE instance whose requirement is lost goes back to
767
+ * pending — recursively, through its own consumers. */
768
+ function reconcile(): void {
769
+ let moved = true
770
+ let rounds = 0
771
+ while (moved) {
772
+ moved = false
773
+ if (1000 < ++rounds) break
774
+
775
+ // Losses first, so a cascade settles in one pass rather than
776
+ // alternating with re-activations.
777
+ for (const r of Object.keys(inst).sort()) {
778
+ const e = inst[r]
779
+ if ('live' !== e.status) continue
780
+ const lost = requirements(e.options)
781
+ .filter(gatesactivation)
782
+ .filter((q) => 0 === providersof(q).length)
783
+ if (0 === lost.length) continue
784
+ // POLICY IS PER REQUIREMENT, not per instance (§11.3): only the
785
+ // definition that has the requirement knows what it can cope
786
+ // with, and one instance may hold both a `static` and a
787
+ // `dynamic` one. A `dynamic` requirement whose provider is gone
788
+ // leaves the consumer LIVE and notified; it is a statement
789
+ // about surviving a swap, so it does not restart here.
790
+ if (lost.every((q) => !restartsonloss(q))) continue
791
+ let bad = false
792
+ try { run(e, 'deactivate', 'deactivate') } catch (err) { bad = true }
793
+ const errors = unwind(e)
794
+ if (bad || 0 < errors.length) {
795
+ e.status = 'failed'
796
+ moved = true
797
+ continue
798
+ }
799
+ e.status = 'pending'
800
+ e.unmet = unmetof(e)
801
+ moved = true
802
+ }
803
+
804
+ for (const r of Object.keys(inst).sort()) {
805
+ const e = inst[r]
806
+ if ('pending' !== e.status) continue
807
+ if (0 < unmetof(e).length) continue
808
+ try {
809
+ run(e, 'activate', 'activate')
810
+ e.status = 'live'
811
+ e.unmet = []
812
+ moved = true
813
+ }
814
+ catch (err) {
815
+ unwind(e)
816
+ e.status = 'failed'
817
+ moved = true
818
+ }
819
+ }
820
+ }
821
+ }
822
+
823
+ // --- ordering ----------------------------------------------------
824
+
825
+ function order(point?: string): string[] {
826
+ // Sorted by declaration SEQUENCE, which is what makes the §7 sort's
827
+ // fall-through deterministic in a language whose maps have no
828
+ // insertion order. §7 breaks ties by `pos`; two instances CAN share
829
+ // one — `declare` defaults `pos` to the registry size, so an unload
830
+ // followed by a fresh declare reuses a surviving instance's — and
831
+ // past that the canonical was falling through to `Object.keys`.
832
+ // `seq` is that order, made explicit. Found by review of the go
833
+ // port.
834
+ const bindings: Binding[] = Object.keys(inst)
835
+ .filter((r) => 'live' === inst[r].status)
836
+ .sort((a, b) => inst[a].seq - inst[b].seq)
837
+ .map((r) => ({ ref: r, pos: inst[r].pos, order: inst[r].order }))
838
+ const spec = point ? points[point] : undefined
839
+ return resolveorder(bindings, spec && spec.pin)
840
+ }
841
+
842
+ // --- points ------------------------------------------------------
843
+
844
+ /** Live bindings on a point, in resolved order. Recomputed on any
845
+ * change to the live set (§7) rather than cached at startup — the bug
846
+ * a host discovers only when something deactivates in production. */
847
+ function bound(point: string): Bound[] {
848
+ const ranked = order(point)
849
+ const out: Bound[] = []
850
+ for (const ref of ranked) {
851
+ const e = inst[ref]
852
+ // The band is the INSTANCE's ordering block (§7), stamped by the
853
+ // host. A plugin passing its own would be ranking itself above
854
+ // the order its document declared.
855
+ const band = (e.order && 'number' === typeof e.order.band) ? e.order.band : 0
856
+ for (const b of e.bindings) {
857
+ if (b.point === point) out.push({ ...b, band })
858
+ }
859
+ }
860
+ return out
861
+ }
862
+
863
+ function emit(point: string, arg?: any): any {
864
+ const spec = points[point]
865
+ if (undefined === spec) fail('plugin_point_unknown', 'no such point: ' + point, { point })
866
+ if (spec.kind && 'hook' !== spec.kind) {
867
+ fail('plugin_point_kind', 'point is not a hook: ' + point, { point, kind: spec.kind })
868
+ }
869
+ return fanout(bound(point), (spec.mode || 'emit') as Mode, arg)
870
+ }
871
+
872
+ function call(point: string, ...args: any[]): any {
873
+ const spec = points[point]
874
+ if (undefined === spec) fail('plugin_point_unknown', 'no such point: ' + point, { point })
875
+ if ('chain' !== spec.kind) {
876
+ fail('plugin_point_kind', 'point is not a chain: ' + point, { point, kind: spec.kind })
877
+ }
878
+ const base = spec.base || ((x: any) => x)
879
+ return compose(bound(point), base)(...args)
880
+ }
881
+
882
+ function provide(point: string, ...args: any[]): any {
883
+ const spec = points[point]
884
+ if (undefined === spec) fail('plugin_point_unknown', 'no such point: ' + point, { point })
885
+ if ('provider' !== spec.kind) {
886
+ fail('plugin_point_kind', 'point is not a provider: ' + point, { point, kind: spec.kind })
887
+ }
888
+ const pick = pickone(bound(point), spec)
889
+ if (!pick.winner) return spec.default
890
+ return pick.winner.fn(...args)
891
+ }
892
+
893
+ /** The losers are VISIBLE rather than silently ignored (§6.3). */
894
+ function shadowed(point: string): string[] {
895
+ const spec = points[point]
896
+ if (undefined === spec) return []
897
+ return pickone(bound(point), spec).shadowed
898
+ }
899
+
900
+ function exports(spec: string): any {
901
+ const all: Exported[] = []
902
+ for (const ref of Object.keys(inst).sort()) {
903
+ const e = inst[ref]
904
+ // Exports of a `loaded` (not live) instance are VISIBLE (§11).
905
+ if ('declared' === e.status || 'failed' === e.status) continue
906
+ for (const k of Object.keys(e.exports)) all.push({ ref, key: k, value: e.exports[k] })
907
+ }
908
+ return resolveexport(spec, all)
909
+ }
910
+
911
+ /** The live providers of a capability, best-first (§11.1). */
912
+ function capability(name: string): string[] {
913
+ const cands: Candidate[] = []
914
+ for (const ref of Object.keys(inst).sort()) {
915
+ const e = inst[ref]
916
+ if ('live' !== e.status) continue
917
+ for (const p of e.provides) {
918
+ if (p.name === name) cands.push({ ref, pos: e.pos, provides: p })
919
+ }
920
+ }
921
+ return resolvecapability({ name }, cands).map((c) => c.ref)
922
+ }
923
+
924
+ // --- documents ---------------------------------------------------
925
+
926
+ /** §9.6: "load what is missing, UNLOAD WHAT IS GONE, patch what
927
+ * changed, and move activation state to match", with the stated
928
+ * ordering — "deactivations and unloads first (reverse load order),
929
+ * then loads, then activations in load order".
930
+ *
931
+ * THREE PHASES, NOT ONE INTERLEAVED LOOP, and both halves matter. An
932
+ * earlier draft walked the document once, unloading and activating per
933
+ * ref, which (a) never looked at instances the new document had
934
+ * DROPPED, so an integration removed from a config reload stayed live
935
+ * with its bindings and resources — the case this method exists for —
936
+ * and (b) activated the first instance before the second was declared,
937
+ * which is not the order §9.6 states. */
938
+ function apply(doc: any, profile?: string): void {
939
+ guard()
940
+ const norm = normalizeconfig({
941
+ doc, profile: profile || opts.profile,
942
+ keys: opts.keys, reserved,
943
+ })
944
+
945
+ const want = norm.order
946
+ const optionsof: { [ref: string]: any } = {}
947
+ for (const ref of want) {
948
+ optionsof[ref] = resolveoptions({
949
+ ref, doc, profile: profile || opts.profile,
950
+ shape: shapeof(ref),
951
+ hostdefaults: opts.defaults && opts.defaults[parseref(ref).name],
952
+ })
953
+ }
954
+
955
+ /** Should this ref be LIVE after the apply? False for a ref the
956
+ * document declares lazy or inactive AND for one it does not name at
957
+ * all — which is what makes "unload what is gone" and "unload what
958
+ * was toggled off" one rule rather than two. */
959
+ const wantlive = (ref: string): boolean => {
960
+ const ent = norm.instance[ref]
961
+ return undefined !== ent && ent.active && 'eager' === ent.start
962
+ }
963
+
964
+ // --- phase 1: deactivations and unloads, in REVERSE load order ---
965
+ //
966
+ // Two populations, and the second is the one that was missing: refs
967
+ // the document no longer names at all, and refs it now names as lazy
968
+ // or inactive. Toggling back to lazy or inactive returns an instance
969
+ // to `declared` BY UNLOADING IT (§9.6) — there is no loaded->declared
970
+ // transition and there should not be one, because an instance that
971
+ // has run `define` has state and bindings that only `close` can
972
+ // properly undo.
973
+ const drop: string[] = []
974
+ for (const ref of Object.keys(inst)) {
975
+ if ('declared' === inst[ref].status) continue
976
+ if (!wantlive(ref)) drop.push(ref)
977
+ }
978
+ // Reverse load order: highest `pos` first, ref-descending for a tie,
979
+ // so a consumer declared after its provider goes down first.
980
+ drop.sort((a, b) => (inst[b].pos - inst[a].pos) || (a < b ? 1 : a > b ? -1 : 0))
981
+ for (const ref of drop) unload(ref)
982
+
983
+ // --- phase 2: declare and patch EVERYTHING, in load order --------
984
+ for (const ref of want) {
985
+ const ent: Instance = norm.instance[ref]
986
+ // NO OPTIONS HERE, and the omission is the fix rather than an
987
+ // oversight. `declare` ADOPTS the options map it is handed as the
988
+ // instance's own, so passing the resolved map made target and
989
+ // source THE SAME MAP in the refill three lines below — which
990
+ // cleared its own source and left a first-time instance with no
991
+ // options at all. A second apply of the same document filled them
992
+ // in, because by then `declare` returned the existing entry and
993
+ // the two maps were distinct. `declare` makes its own empty map
994
+ // and the refill fills it, so both paths are now one path.
995
+ declare(ref, { order: ent.order, pos: ent.pos })
996
+ // The bar is REASSERTED ON EVERY APPLY, in both directions — a
997
+ // document that turns the instance back on clears it, which is
998
+ // the whole point of a config switch.
999
+ inst[ref].barred = !ent.active
1000
+ // REFILL rather than REBIND. A definition's callbacks close over
1001
+ // the options map they were handed at `define`; replacing the
1002
+ // reference here would leave every binding reading the values the
1003
+ // first apply gave it, and a re-applied document would silently do
1004
+ // nothing. Clearing and refilling the same map is portable to every
1005
+ // language, unlike a getter or an interception hook — which the
1006
+ // §18 portability budget forbids anyway.
1007
+ refill(inst[ref].options, optionsof[ref])
1008
+ inst[ref].order = ent.order
1009
+ inst[ref].pos = ent.pos
1010
+ }
1011
+
1012
+ // --- phase 3: loads, in load order -------------------------------
1013
+ //
1014
+ // ONLY THE EAGER, ACTIVE ONES. §9.6: "`apply` declares everything
1015
+ // and activates only what asked for it… A document of twenty lazy
1016
+ // instances is therefore twenty map entries and no executed code."
1017
+ for (const ref of want) {
1018
+ if (wantlive(ref)) load(ref)
1019
+ }
1020
+
1021
+ // --- phase 4: activations, in load order -------------------------
1022
+ //
1023
+ // Separate from the loads because §9.6 names them separately, and
1024
+ // the difference is observable: every `define` runs before the first
1025
+ // `activate`, so a plugin cannot see a half-built registry.
1026
+ //
1027
+ // Activation order does not have to be dependency-sorted (§9.6):
1028
+ // under §11 activation is a standing request, so a consumer
1029
+ // activated before its provider sits in `pending` until the provider
1030
+ // arrives a few lines later in the same plan.
1031
+ for (const ref of want) {
1032
+ if (wantlive(ref)) activate(ref)
1033
+ }
1034
+ }
1035
+
1036
+ function shapeof(ref: string): any {
1037
+ const def = catalog.get(parseref(ref).name)
1038
+ return def && def.shape
1039
+ }
1040
+
1041
+ function setoptions(ref: string, patch: any): void {
1042
+ guard()
1043
+ const e = need(ref)
1044
+ const previous = { ...e.options }
1045
+ refill(e.options, resolveoptions({
1046
+ ref: e.ref, shape: shapeof(e.ref), doc: {}, patch: merge(previous, patch),
1047
+ }))
1048
+ if ('live' === e.status) {
1049
+ if ('function' === typeof e.def.reconfigure) {
1050
+ intransition = true
1051
+ try { e.def.reconfigure(api(e), e.options, previous) }
1052
+ finally { intransition = false }
1053
+ }
1054
+ else {
1055
+ // Always correct and sometimes expensive; `reconfigure` exists
1056
+ // to make the common case cheap (§9.4).
1057
+ deactivate(e.ref)
1058
+ activate(e.ref)
1059
+ }
1060
+ }
1061
+ }
1062
+
1063
+ /** Empty the target and refill it, so callers holding the reference
1064
+ * see the new values. */
1065
+ function refill(target: any, source: any): void {
1066
+ for (const k of Object.keys(target)) delete target[k]
1067
+ for (const k of Object.keys(source || {})) target[k] = source[k]
1068
+ }
1069
+
1070
+ function merge(a: any, b: any): any {
1071
+ const out: any = {}
1072
+ for (const k of Object.keys(a || {})) out[k] = a[k]
1073
+ for (const k of Object.keys(b || {})) out[k] = b[k]
1074
+ return out
1075
+ }
1076
+
1077
+ function close(): void {
1078
+ // A bulk teardown removing the holders too, so `hold` is suspended
1079
+ // for exactly those holders (§11.3) - while the consumers-first
1080
+ // cascade still runs, which is the half that matters.
1081
+ coordinated = true
1082
+ try { for (const r of Object.keys(inst).sort().reverse()) unload(r) }
1083
+ finally { coordinated = false }
1084
+ }
1085
+
1086
+ /** The same record §6.6 gives a plugin about itself, reachable from
1087
+ * outside for the corpus. A plugin asks via `inst.position(point)`. */
1088
+ function positionof(ref: string, point: string): any {
1089
+ const e = inst[canonref(ref)]
1090
+ if (!e) fail('plugin_not_loaded', 'no such instance: ' + ref, { ref })
1091
+ const ranked = order(point)
1092
+ const index = ranked.indexOf(e.ref)
1093
+ return {
1094
+ index, count: ranked.length,
1095
+ outermost: 0 === index,
1096
+ innermost: index === ranked.length - 1,
1097
+ }
1098
+ }
1099
+
1100
+ /** §9.1: a host that reserves a name MUST still be able to declare
1101
+ * the instance it reserved — "The host declares those instances
1102
+ * itself, after the user merge, and always wins."
1103
+ *
1104
+ * Without this, `reserved` was a feature that made its own purpose
1105
+ * impossible: every path to `declare` was barred, including the
1106
+ * embedding host's, so reserving `station` meant station could never
1107
+ * install the adapter it had reserved the name for.
1108
+ *
1109
+ * THE BOUNDARY IS BY METHOD, NOT BY CALLER, and that is a real limit
1110
+ * rather than an oversight. No language here can tell the embedding
1111
+ * host from a plugin holding the same host object — and a plugin that
1112
+ * holds it can already call `close()`. What reservation protects is
1113
+ * CONFIGURATION: documents, profile overlays, `VOXGIG_PLUGIN_*`,
1114
+ * construction options and ordinary `declare`/`load`/`options` calls.
1115
+ * That is what §9.1 lists, and all of it still goes through the
1116
+ * check. */
1117
+ function hostdeclare(ref: string, spec?: DeclareSpec): Live {
1118
+ guard()
1119
+ return declare(ref, { ...(spec || {}), hostowned: true })
1120
+ }
1121
+
1122
+ const self = {
1123
+ catalog, list, instance, order, observable, hostdeclare,
1124
+ trace: () => events.slice(),
1125
+ autotag, positionof,
1126
+ emit, call, provider: provide, shadowed, exports, capability,
1127
+ declare, load, activate, deactivate, unload, ready, apply, close,
1128
+ options: setoptions,
1129
+ define: (def: Definition) => catalog.add(def),
1130
+ }
1131
+ return self
1132
+ }