nervur 0.21.4 → 0.22.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 (339) hide show
  1. package/README.md +215 -158
  2. package/dist/browser.js +4 -3
  3. package/dist/cli.js +16 -0
  4. package/dist/{being → core/being}/being.js +10 -0
  5. package/dist/{being → core/being}/faculty.js +5 -2
  6. package/dist/{being → core/being}/index.d.ts +1 -1
  7. package/dist/{being → core/being}/index.js +1 -1
  8. package/dist/{being → core/being}/kind.d.ts +2 -0
  9. package/dist/{being → core/being}/kind.js +6 -0
  10. package/dist/{being → core/being}/types.js +1 -1
  11. package/dist/{browser → core/browser}/index.d.ts +6 -5
  12. package/dist/{browser → core/browser}/index.js +10 -10
  13. package/dist/{browser → core/browser}/worker.d.ts +2 -3
  14. package/dist/{browser → core/browser}/worker.js +8 -11
  15. package/dist/{cli → core/cli}/command.d.ts +4 -4
  16. package/dist/{cli → core/cli}/command.js +116 -66
  17. package/dist/{cli → core/cli}/edge.js +4 -2
  18. package/dist/core/cli/harbor.d.ts +25 -0
  19. package/dist/{cli → core/cli}/harbor.js +45 -33
  20. package/dist/{contract → core/contract}/index.d.ts +6 -5
  21. package/dist/{contract → core/contract}/index.js +8 -9
  22. package/dist/core/contract/link.d.ts +4 -0
  23. package/dist/core/contract/link.js +45 -0
  24. package/dist/{crypto → core/crypto}/ed25519.js +22 -14
  25. package/dist/core/crypto/subtle.d.ts +3 -0
  26. package/dist/core/crypto/subtle.js +11 -0
  27. package/dist/core/crypto/x25519.js +24 -0
  28. package/dist/core/edge/index.d.ts +164 -0
  29. package/dist/core/edge/index.js +739 -0
  30. package/dist/core/edge/kit.d.ts +2 -0
  31. package/dist/core/edge/kit.js +2 -0
  32. package/dist/core/git/http.d.ts +6 -0
  33. package/dist/core/git/http.js +102 -0
  34. package/dist/core/git/index.d.ts +5 -0
  35. package/dist/core/git/index.js +10 -0
  36. package/dist/core/git/object.d.ts +40 -0
  37. package/dist/core/git/object.js +103 -0
  38. package/dist/core/git/pack.d.ts +9 -0
  39. package/dist/core/git/pack.js +171 -0
  40. package/dist/core/git/store.d.ts +23 -0
  41. package/dist/core/git/store.js +120 -0
  42. package/dist/core/git/zlib.d.ts +6 -0
  43. package/dist/core/git/zlib.js +210 -0
  44. package/dist/core/harbor/carrying.d.ts +51 -0
  45. package/dist/core/harbor/carrying.js +69 -0
  46. package/dist/core/harbor/catalogue.d.ts +33 -0
  47. package/dist/core/harbor/catalogue.js +365 -0
  48. package/dist/core/harbor/dna.d.ts +13 -0
  49. package/dist/core/harbor/dna.js +120 -0
  50. package/dist/{harbor → core/harbor}/dock.d.ts +22 -13
  51. package/dist/core/harbor/dock.js +381 -0
  52. package/dist/core/harbor/harbor.d.ts +16 -0
  53. package/dist/core/harbor/harbor.js +438 -0
  54. package/dist/core/harbor/index.d.ts +11 -0
  55. package/dist/{harbor → core/harbor}/index.js +5 -5
  56. package/dist/core/harbor/memory.d.ts +10 -0
  57. package/dist/core/harbor/memory.js +25 -0
  58. package/dist/{harbor → core/harbor}/package.d.ts +0 -1
  59. package/dist/{harbor → core/harbor}/package.js +9 -9
  60. package/dist/core/harbor/probe.d.ts +22 -0
  61. package/dist/core/harbor/probe.js +15 -0
  62. package/dist/core/harbor/registry.d.ts +15 -0
  63. package/dist/{harbor → core/harbor}/registry.js +26 -10
  64. package/dist/core/harbor/root-line.d.ts +7 -0
  65. package/dist/core/harbor/root-line.js +9 -0
  66. package/dist/{harbor → core/harbor}/terrain.d.ts +9 -6
  67. package/dist/{harbor → core/harbor}/terrain.js +5 -4
  68. package/dist/core/http/index.d.ts +2 -0
  69. package/dist/{http → core/http}/index.js +3 -5
  70. package/dist/{line → core/line}/answer.d.ts +2 -2
  71. package/dist/{line → core/line}/frame.d.ts +0 -5
  72. package/dist/{line → core/line}/frame.js +0 -4
  73. package/dist/core/line/ground.js +7 -0
  74. package/dist/core/line/index.d.ts +4 -0
  75. package/dist/core/line/index.js +8 -0
  76. package/dist/core/line/web.d.ts +12 -0
  77. package/dist/{line → core/line}/web.js +13 -77
  78. package/dist/{node → core/node}/index.d.ts +2 -15
  79. package/dist/core/node/index.js +124 -0
  80. package/dist/{pointer → core/pointer}/bodies.d.ts +7 -5
  81. package/dist/core/pointer/bodies.js +118 -0
  82. package/dist/core/pointer/index.d.ts +2 -0
  83. package/dist/{pointer → core/pointer}/index.js +1 -1
  84. package/dist/{pointer → core/pointer}/world.d.ts +13 -9
  85. package/dist/{pointer → core/pointer}/world.js +31 -16
  86. package/dist/{proof → core/proof}/contracts.d.ts +6 -2
  87. package/dist/{proof → core/proof}/contracts.js +11 -10
  88. package/dist/core/proof/index.d.ts +3 -0
  89. package/dist/{proof → core/proof}/index.js +2 -2
  90. package/dist/core/proof/law.d.ts +25 -0
  91. package/dist/core/proof/law.js +715 -0
  92. package/dist/{tcp → core/tcp}/index.d.ts +7 -4
  93. package/dist/{tcp → core/tcp}/index.js +11 -62
  94. package/dist/{ward/ward.d.ts → core/ward/house.d.ts} +24 -10
  95. package/dist/core/ward/house.js +473 -0
  96. package/dist/core/ward/index.d.ts +5 -0
  97. package/dist/core/ward/index.js +7 -0
  98. package/dist/{ward → core/ward}/partition.d.ts +1 -0
  99. package/dist/{ward → core/ward}/stance.d.ts +2 -2
  100. package/dist/{ward → core/ward}/stance.js +5 -2
  101. package/dist/{ward/ward-being.d.ts → core/ward/ward.d.ts} +14 -6
  102. package/dist/core/ward/ward.js +140 -0
  103. package/dist/core.d.ts +10 -0
  104. package/dist/core.js +19 -0
  105. package/dist/defaults/dock/index.d.ts +4 -0
  106. package/dist/defaults/dock/index.js +11 -0
  107. package/dist/defaults/index.d.ts +5 -0
  108. package/dist/defaults/index.js +10 -0
  109. package/dist/defaults/memory/index.d.ts +12 -0
  110. package/dist/defaults/memory/index.js +39 -0
  111. package/dist/defaults/tcp/index.d.ts +16 -0
  112. package/dist/defaults/tcp/index.js +82 -0
  113. package/dist/defaults/ward/index.d.ts +4 -0
  114. package/dist/defaults/ward/index.js +11 -0
  115. package/dist/defaults/web/index.d.ts +15 -0
  116. package/dist/defaults/web/index.js +90 -0
  117. package/dist/edge.js +4 -3
  118. package/dist/index.d.ts +1 -8
  119. package/dist/index.js +13 -18
  120. package/dist/kit.d.ts +4 -0
  121. package/dist/kit.js +12 -0
  122. package/dist/node.js +4 -3
  123. package/package.json +23 -18
  124. package/src/browser.ts +4 -3
  125. package/src/cli.ts +15 -0
  126. package/src/{being → core/being}/being.ts +4 -0
  127. package/src/{being → core/being}/faculty.ts +5 -2
  128. package/src/{being → core/being}/index.ts +1 -1
  129. package/src/{being → core/being}/kind.ts +7 -0
  130. package/src/{being → core/being}/types.ts +1 -1
  131. package/src/{browser → core/browser}/index.ts +16 -13
  132. package/src/{browser → core/browser}/worker.ts +11 -14
  133. package/src/{cli → core/cli}/command.ts +113 -66
  134. package/src/{cli → core/cli}/edge.ts +4 -2
  135. package/src/{cli → core/cli}/harbor.ts +48 -31
  136. package/src/{contract → core/contract}/index.ts +14 -14
  137. package/src/core/contract/link.ts +58 -0
  138. package/src/{crypto → core/crypto}/ed25519.ts +22 -14
  139. package/src/core/crypto/subtle.ts +13 -0
  140. package/src/core/crypto/x25519.ts +23 -0
  141. package/src/core/edge/index.ts +865 -0
  142. package/src/core/git/http.ts +103 -0
  143. package/src/core/git/index.ts +10 -0
  144. package/src/core/git/object.ts +116 -0
  145. package/src/core/git/pack.ts +147 -0
  146. package/src/core/git/store.ts +122 -0
  147. package/src/core/git/zlib.ts +197 -0
  148. package/src/core/harbor/carrying.ts +124 -0
  149. package/src/core/harbor/catalogue.ts +386 -0
  150. package/src/core/harbor/dna.ts +116 -0
  151. package/src/core/harbor/dock.ts +420 -0
  152. package/src/core/harbor/harbor.ts +433 -0
  153. package/src/core/harbor/index.ts +14 -0
  154. package/src/core/harbor/memory.ts +31 -0
  155. package/src/{harbor → core/harbor}/package.ts +15 -15
  156. package/src/core/harbor/probe.ts +39 -0
  157. package/src/{harbor → core/harbor}/registry.ts +28 -11
  158. package/src/core/harbor/root-line.ts +19 -0
  159. package/src/{harbor → core/harbor}/terrain.ts +14 -7
  160. package/src/{http → core/http}/index.ts +5 -8
  161. package/src/{line → core/line}/answer.ts +3 -2
  162. package/src/{line → core/line}/frame.ts +0 -5
  163. package/src/core/line/ground.ts +18 -0
  164. package/src/core/line/index.ts +8 -0
  165. package/src/{line → core/line}/web.ts +1 -105
  166. package/src/core/node/index.ts +139 -0
  167. package/src/core/pointer/bodies.ts +122 -0
  168. package/src/core/pointer/index.ts +4 -0
  169. package/src/{pointer → core/pointer}/world.ts +45 -21
  170. package/src/{proof → core/proof}/contracts.ts +18 -13
  171. package/src/{proof → core/proof}/index.ts +3 -3
  172. package/src/core/proof/law.ts +742 -0
  173. package/src/{stand → core/stand}/stand.ts +2 -2
  174. package/src/{tcp → core/tcp}/index.ts +17 -74
  175. package/src/core/ward/house.ts +524 -0
  176. package/src/core/ward/index.ts +7 -0
  177. package/src/{ward → core/ward}/partition.ts +5 -1
  178. package/src/{ward → core/ward}/stance.ts +5 -2
  179. package/src/core/ward/ward.ts +166 -0
  180. package/src/core.ts +55 -0
  181. package/src/defaults/dock/index.ts +12 -0
  182. package/src/defaults/index.ts +10 -0
  183. package/src/defaults/memory/index.ts +50 -0
  184. package/src/defaults/tcp/index.ts +89 -0
  185. package/src/defaults/ward/index.ts +12 -0
  186. package/src/defaults/web/index.ts +97 -0
  187. package/src/edge.ts +4 -3
  188. package/src/index.ts +13 -50
  189. package/src/kit.ts +15 -0
  190. package/src/node.ts +4 -3
  191. package/dist/cli/harbor.d.ts +0 -16
  192. package/dist/cli/main.js +0 -14
  193. package/dist/crypto/subtle.d.ts +0 -10
  194. package/dist/crypto/subtle.js +0 -29
  195. package/dist/crypto/x25519.js +0 -21
  196. package/dist/edge/index.d.ts +0 -81
  197. package/dist/edge/index.js +0 -400
  198. package/dist/harbor/carrying.d.ts +0 -17
  199. package/dist/harbor/carrying.js +0 -38
  200. package/dist/harbor/catalogue.d.ts +0 -28
  201. package/dist/harbor/catalogue.js +0 -109
  202. package/dist/harbor/dock.js +0 -236
  203. package/dist/harbor/harbor.d.ts +0 -45
  204. package/dist/harbor/harbor.js +0 -347
  205. package/dist/harbor/index.d.ts +0 -11
  206. package/dist/harbor/probe.d.ts +0 -18
  207. package/dist/harbor/probe.js +0 -15
  208. package/dist/harbor/registry.d.ts +0 -10
  209. package/dist/harbor/relay.d.ts +0 -15
  210. package/dist/harbor/relay.js +0 -406
  211. package/dist/harbor/root-line.d.ts +0 -9
  212. package/dist/harbor/root-line.js +0 -38
  213. package/dist/harbor/store.d.ts +0 -13
  214. package/dist/harbor/store.js +0 -53
  215. package/dist/http/index.d.ts +0 -4
  216. package/dist/line/ground.js +0 -9
  217. package/dist/line/index.d.ts +0 -5
  218. package/dist/line/index.js +0 -9
  219. package/dist/line/push.d.ts +0 -7
  220. package/dist/line/push.js +0 -92
  221. package/dist/line/web.d.ts +0 -30
  222. package/dist/node/index.js +0 -236
  223. package/dist/pointer/bodies.js +0 -80
  224. package/dist/pointer/index.d.ts +0 -2
  225. package/dist/proof/index.d.ts +0 -3
  226. package/dist/proof/law.d.ts +0 -90
  227. package/dist/proof/law.js +0 -591
  228. package/dist/tcp/frame.d.ts +0 -25
  229. package/dist/tcp/frame.js +0 -64
  230. package/dist/ward/index.d.ts +0 -6
  231. package/dist/ward/index.js +0 -8
  232. package/dist/ward/pilot.d.ts +0 -8
  233. package/dist/ward/pilot.js +0 -50
  234. package/dist/ward/ward-being.js +0 -82
  235. package/dist/ward/ward.js +0 -290
  236. package/src/cli/main.ts +0 -13
  237. package/src/crypto/subtle.ts +0 -33
  238. package/src/crypto/x25519.ts +0 -21
  239. package/src/edge/index.ts +0 -490
  240. package/src/harbor/carrying.ts +0 -56
  241. package/src/harbor/catalogue.ts +0 -134
  242. package/src/harbor/dock.ts +0 -265
  243. package/src/harbor/harbor.ts +0 -381
  244. package/src/harbor/index.ts +0 -14
  245. package/src/harbor/probe.ts +0 -34
  246. package/src/harbor/relay.ts +0 -418
  247. package/src/harbor/root-line.ts +0 -39
  248. package/src/harbor/store.ts +0 -69
  249. package/src/line/ground.ts +0 -19
  250. package/src/line/index.ts +0 -9
  251. package/src/line/push.ts +0 -112
  252. package/src/node/index.ts +0 -241
  253. package/src/pointer/bodies.ts +0 -82
  254. package/src/pointer/index.ts +0 -4
  255. package/src/proof/law.ts +0 -591
  256. package/src/ward/index.ts +0 -8
  257. package/src/ward/pilot.ts +0 -50
  258. package/src/ward/ward-being.ts +0 -103
  259. package/src/ward/ward.ts +0 -328
  260. /package/dist/{cli/main.d.ts → cli.d.ts} +0 -0
  261. /package/dist/{being → core/being}/being.d.ts +0 -0
  262. /package/dist/{being → core/being}/digest.d.ts +0 -0
  263. /package/dist/{being → core/being}/digest.js +0 -0
  264. /package/dist/{being → core/being}/faculty.d.ts +0 -0
  265. /package/dist/{being → core/being}/types.d.ts +0 -0
  266. /package/dist/{being → core/being}/words.d.ts +0 -0
  267. /package/dist/{being → core/being}/words.js +0 -0
  268. /package/dist/{cli → core/cli}/edge.d.ts +0 -0
  269. /package/dist/{crypto → core/crypto}/aes.d.ts +0 -0
  270. /package/dist/{crypto → core/crypto}/aes.js +0 -0
  271. /package/dist/{crypto → core/crypto}/bytes.d.ts +0 -0
  272. /package/dist/{crypto → core/crypto}/bytes.js +0 -0
  273. /package/dist/{crypto → core/crypto}/ed25519.d.ts +0 -0
  274. /package/dist/{crypto → core/crypto}/hash.d.ts +0 -0
  275. /package/dist/{crypto → core/crypto}/hash.js +0 -0
  276. /package/dist/{crypto → core/crypto}/index.d.ts +0 -0
  277. /package/dist/{crypto → core/crypto}/index.js +0 -0
  278. /package/dist/{crypto → core/crypto}/json.d.ts +0 -0
  279. /package/dist/{crypto → core/crypto}/json.js +0 -0
  280. /package/dist/{crypto → core/crypto}/mlkem.d.ts +0 -0
  281. /package/dist/{crypto → core/crypto}/mlkem.js +0 -0
  282. /package/dist/{crypto → core/crypto}/x25519.d.ts +0 -0
  283. /package/dist/{folder → core/folder}/index.d.ts +0 -0
  284. /package/dist/{folder → core/folder}/index.js +0 -0
  285. /package/dist/{http → core/http}/websocket.d.ts +0 -0
  286. /package/dist/{http → core/http}/websocket.js +0 -0
  287. /package/dist/{line → core/line}/answer.js +0 -0
  288. /package/dist/{line → core/line}/ground.d.ts +0 -0
  289. /package/dist/{proof → core/proof}/expect.d.ts +0 -0
  290. /package/dist/{proof → core/proof}/expect.js +0 -0
  291. /package/dist/{quo → core/quo}/address.d.ts +0 -0
  292. /package/dist/{quo → core/quo}/address.js +0 -0
  293. /package/dist/{quo → core/quo}/door.d.ts +0 -0
  294. /package/dist/{quo → core/quo}/door.js +0 -0
  295. /package/dist/{quo → core/quo}/index.d.ts +0 -0
  296. /package/dist/{quo → core/quo}/index.js +0 -0
  297. /package/dist/{quo → core/quo}/invitation.d.ts +0 -0
  298. /package/dist/{quo → core/quo}/invitation.js +0 -0
  299. /package/dist/{quo → core/quo}/keys.d.ts +0 -0
  300. /package/dist/{quo → core/quo}/keys.js +0 -0
  301. /package/dist/{quo → core/quo}/payload.d.ts +0 -0
  302. /package/dist/{quo → core/quo}/payload.js +0 -0
  303. /package/dist/{quo → core/quo}/relations.d.ts +0 -0
  304. /package/dist/{quo → core/quo}/relations.js +0 -0
  305. /package/dist/{quo → core/quo}/reply.d.ts +0 -0
  306. /package/dist/{quo → core/quo}/reply.js +0 -0
  307. /package/dist/{quo → core/quo}/seal.d.ts +0 -0
  308. /package/dist/{quo → core/quo}/seal.js +0 -0
  309. /package/dist/{quo → core/quo}/standing.d.ts +0 -0
  310. /package/dist/{quo → core/quo}/standing.js +0 -0
  311. /package/dist/{ward → core/ward}/allowance.d.ts +0 -0
  312. /package/dist/{ward → core/ward}/allowance.js +0 -0
  313. /package/dist/{ward → core/ward}/cells.d.ts +0 -0
  314. /package/dist/{ward → core/ward}/cells.js +0 -0
  315. /package/dist/{ward → core/ward}/partition.js +0 -0
  316. /package/src/{being → core/being}/digest.ts +0 -0
  317. /package/src/{being → core/being}/words.ts +0 -0
  318. /package/src/{crypto → core/crypto}/aes.ts +0 -0
  319. /package/src/{crypto → core/crypto}/bytes.ts +0 -0
  320. /package/src/{crypto → core/crypto}/hash.ts +0 -0
  321. /package/src/{crypto → core/crypto}/index.ts +0 -0
  322. /package/src/{crypto → core/crypto}/json.ts +0 -0
  323. /package/src/{crypto → core/crypto}/mlkem.ts +0 -0
  324. /package/src/{folder → core/folder}/index.ts +0 -0
  325. /package/src/{http → core/http}/websocket.ts +0 -0
  326. /package/src/{proof → core/proof}/expect.ts +0 -0
  327. /package/src/{quo → core/quo}/address.ts +0 -0
  328. /package/src/{quo → core/quo}/door.ts +0 -0
  329. /package/src/{quo → core/quo}/index.ts +0 -0
  330. /package/src/{quo → core/quo}/invitation.ts +0 -0
  331. /package/src/{quo → core/quo}/keys.ts +0 -0
  332. /package/src/{quo → core/quo}/payload.ts +0 -0
  333. /package/src/{quo → core/quo}/relations.ts +0 -0
  334. /package/src/{quo → core/quo}/reply.ts +0 -0
  335. /package/src/{quo → core/quo}/seal.ts +0 -0
  336. /package/src/{quo → core/quo}/standing.ts +0 -0
  337. /package/src/{stand → core/stand}/main.ts +0 -0
  338. /package/src/{ward → core/ward}/allowance.ts +0 -0
  339. /package/src/{ward → core/ward}/cells.ts +0 -0
@@ -0,0 +1,438 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // The harbor: the onion, unpacked from a terrain alone, in three levels.
3
+ // Each level stands the next and leaves it alone.
4
+ //
5
+ // L1, the boot, the harbor's own, the core alone
6
+ // the seed and the package the harbor's one secret, from custody,
7
+ // opens its sealed memory, the vault
8
+ // the box ward unpacked as every ward is, under the
9
+ // harbor's seed, no being standing yet
10
+ // the catalogue the core's registry, stood from the core
11
+ // on empty memory and from her row after;
12
+ // every module the commit `live` names is
13
+ // run through the terrain's loader
14
+ // the registries every box faculty the catalogue resolves
15
+ // to a registry, where her row names the
16
+ // catalogue as hers
17
+ // the dock the box ward's ward, of the class her row
18
+ // names through its registry, the default
19
+ // dock where it does not stand; the door is
20
+ // hers from here, and `open` returns
21
+ // L2, the dock's her `stand` ask: every other faculty, the
22
+ // routes, and every hosted ward, each ward
23
+ // standing on the class, the registry and
24
+ // the memory the dock keeps for it
25
+ // L3, each ward's beings born from her rows for the asks that
26
+ // reach them, and dropped after; nothing
27
+ // stands them
28
+ //
29
+ // L1 is one call and no ask can make it. After it the harbor takes asks
30
+ // alone. Whoever holds a harbor has five things of it and no other:
31
+ //
32
+ // Harbor.open(terrain?) the boot
33
+ // ask(request) the root line, a ward asked as its root
34
+ // arrive(pk, box) a Quo box at one of its doors
35
+ // holds(pk) whether one of its doors is that ward's
36
+ // close() every carrier asleep, and the ground let go
37
+ //
38
+ // What stands inside it, the wards, the dock, the catalogue and the
39
+ // carriers, is reached by an ask and never by a hand. The box ward's
40
+ // stance carries the harbor's `ground`, the one thing the dock, the
41
+ // catalogue and every faculty of the box are handed.
42
+ //
43
+ // The harbor fails only where the seed or the box ward's own place cannot
44
+ // be read, or the catalogue does not stand. A module, a registry, a
45
+ // faculty, a route, a hosted ward or a being that cannot stand fails
46
+ // alone, and the census names it.
47
+ //
48
+ // Genesis and wake are one path: on empty memory the box ward holds no
49
+ // catalogue, and the harbor writes her from the core; the root's asks
50
+ // write the rest, and nothing enters unasked.
51
+ import { isSilence, isWord, told } from '../being/index.js';
52
+ import { hex, isHex, unhex } from '../crypto/index.js';
53
+ import { unspecified, WardKey } from '../quo/index.js';
54
+ import { DOCK, House } from '../ward/index.js';
55
+ import { Catalogue, CATALOGUE } from './catalogue.js';
56
+ import { CarrierFaculty, UNDIALED } from './carrying.js';
57
+ import { BOX, Dock, hostable } from './dock.js';
58
+ import { Dna } from './dna.js';
59
+ import { Package } from './package.js';
60
+ import { MemoryFaculty } from './memory.js';
61
+ import { registers, RegistryFaculty } from './registry.js';
62
+ import { probeGround } from './probe.js';
63
+ import { readRootRequest } from './root-line.js';
64
+ import { Terrain } from './terrain.js';
65
+ // The box ward's ward is a dock, the terrain's default at genesis and
66
+ // while her row's kind does not resolve.
67
+ const boxWard = ({ dock }) => ({ genesis: dock.kind, contract: 'dock', fits: (C) => Dock.fulfils(C), fallback: dock });
68
+ // A hosted ward's ward is a ward and no dock, of the kind `host` named or
69
+ // the terrain's default at genesis.
70
+ const hostedWard = ({ ward }, kind = ward.kind) => ({ genesis: kind, contract: 'hosted ward', fits: hostable });
71
+ export class Harbor {
72
+ #terrain;
73
+ #package;
74
+ #wards = new Map();
75
+ #failed = { wards: {}, routes: {} };
76
+ #ground;
77
+ // Every ward speaks through the harbor: a pk of one of its doors goes to
78
+ // that door, any other along its route or to the terrain's carrier.
79
+ #carrier = { carry: (pk, bytes) => this.#carry(pk, bytes) };
80
+ // Every class a row names, through the registry faculty of the box the
81
+ // row names, or the catalogue.
82
+ #classes = { classOf: (kind, registry) => this.#classOf(kind, registry) };
83
+ constructor(terrain, pack) {
84
+ const { dock, ward, classes } = terrain.defaults;
85
+ if (!Dock.fulfils(dock))
86
+ throw new Error('the default dock is no dock');
87
+ if (!hostable(ward))
88
+ throw new Error('the default ward is no hosted ward');
89
+ this.#terrain = terrain;
90
+ this.#package = pack;
91
+ const dna = new Dna(terrain.memory, pack);
92
+ // The kit's classes the catalogue resolves: her own, the core's alone,
93
+ // then the defaults the terrain hands in.
94
+ const kit = [Catalogue, dock, ward, ...classes];
95
+ this.#ground = {
96
+ terrain,
97
+ dna,
98
+ kit,
99
+ foreground: terrain.foreground,
100
+ arrive: (pk, bytes) => this.arrive(pk, bytes),
101
+ host: (name, invitation, seed, memory, kind, registry) => this.#host(name, invitation, seed, memory, kind, registry),
102
+ stand: (hosted) => this.#stand(hosted),
103
+ move: (name, seed, from, to) => this.#move(name, seed, from, to),
104
+ release: async (name, memory) => this.#keeper(memory).forget(await this.#package.place(name)),
105
+ route: (pk, at) => this.#route(pk, at),
106
+ reached: (pk, at) => {
107
+ if (!this.#dialable(at))
108
+ this.#failed.routes[pk] = 'no carrier dials it';
109
+ },
110
+ keep: () => this.#box.partition.kept(),
111
+ failures: () => this.#failures(),
112
+ sweep: () => this.#sweep(),
113
+ awaken: async (key) => {
114
+ const being = this.#box.being(key);
115
+ if (being instanceof CarrierFaculty)
116
+ await being.awake();
117
+ },
118
+ rouse: async (key) => {
119
+ if (terrain.wakes)
120
+ await this.#ground.awaken(key);
121
+ },
122
+ lull: async (key) => {
123
+ const being = this.#box.being(key);
124
+ if (being instanceof CarrierFaculty)
125
+ await being.sleep();
126
+ },
127
+ listening: () => this.#carriers.flatMap((carrier) => carrier.listening()),
128
+ heard: async () => {
129
+ await Promise.all(this.#carriers.map((carrier) => carrier.heard()));
130
+ },
131
+ ran: () => {
132
+ for (const house of this.#wards.values())
133
+ house.renew();
134
+ return Promise.resolve();
135
+ },
136
+ stands: (kinds) => [...this.#wards.values()].some((house) => Object.values(house.partition.beings).some((row) => kinds.includes(row.class))),
137
+ kept: () => [...new Set([...this.#wards.values()].flatMap((house) => Object.values(house.partition.beings).map((row) => row.class)))],
138
+ };
139
+ }
140
+ // A harbor on the terrain handed in, or, with none, on the ground the
141
+ // probe finds here. A ground another run holds refuses, and what the
142
+ // ground serves beside the harbor stands once it is whole.
143
+ static async open(from = {}) {
144
+ const terrain = from instanceof Terrain ? from : probeGround(from).terrain;
145
+ await terrain.claim();
146
+ let harbor;
147
+ try {
148
+ harbor = await Harbor.#boot(terrain);
149
+ }
150
+ catch (e) {
151
+ await terrain.release();
152
+ throw e;
153
+ }
154
+ try {
155
+ await terrain.stand(harbor);
156
+ }
157
+ catch (e) {
158
+ await harbor.close();
159
+ throw e;
160
+ }
161
+ return harbor;
162
+ }
163
+ // L1, the one call no ask makes, ending with the door handed to the dock.
164
+ // What stands beyond it stands because someone asked `stand`.
165
+ static async #boot(terrain) {
166
+ const seed = await terrain.custody.seed();
167
+ const harbor = new Harbor(terrain, await Package.open(terrain.memory, terrain.entropy, seed));
168
+ const box = await harbor.#unpack(BOX, seed, { ward: boxWard(terrain.defaults), carries: { ground: harbor.#ground }, classes: harbor.#classes, stands: true });
169
+ if (box.partition.being(CATALOGUE))
170
+ box.stand(CATALOGUE);
171
+ else if ((await box.make(CATALOGUE, Catalogue.kind)) !== 'booted' || !(await box.partition.kept()))
172
+ throw new Error('the catalogue did not stand');
173
+ const catalogue = box.being(CATALOGUE);
174
+ if (!(catalogue instanceof Catalogue))
175
+ throw new Error('the catalogue did not stand');
176
+ await catalogue.wake();
177
+ for (const [key, row] of Object.entries(box.partition.beings)) {
178
+ if (row.registry === undefined && registers(catalogue.classOf(row.class)))
179
+ box.stand(key);
180
+ }
181
+ await box.standWard();
182
+ return harbor;
183
+ }
184
+ // The root line: one request, `{ ward?, method?, args? }`, asked of the
185
+ // box ward or the hosted ward named as its root, and one plain JSON
186
+ // answer, whatever front carried it.
187
+ //
188
+ // { answer } what the ward said
189
+ // { silence: true } she said nothing
190
+ // { word } a kit word: unreached, late, ...
191
+ // { error } the request was none, or names no ward that
192
+ // stands, with the reason one did not
193
+ async ask(value) {
194
+ const request = readRootRequest(value);
195
+ if (request === null)
196
+ return { error: 'not a root request' };
197
+ const ward = request.ward === undefined ? this.#box : this.#wards.get(request.ward);
198
+ if (ward === undefined) {
199
+ const failed = this.#failures().wards[request.ward];
200
+ return failed === undefined ? { error: 'no such ward' } : { error: 'the ward did not stand', reason: failed };
201
+ }
202
+ const out = await ward.root(request.method, request.args);
203
+ if (isSilence(out))
204
+ return { silence: true };
205
+ if (isWord(out))
206
+ return { word: told(out) };
207
+ return { answer: out };
208
+ }
209
+ // Bytes for one of this harbor's doors, or for a ward a relay of this
210
+ // harbor answers for, or nothing.
211
+ async arrive(pk, bytes) {
212
+ const ward = this.#door(pk);
213
+ if (ward)
214
+ return (await ward.door.arrive(bytes)).bytes;
215
+ return (await this.#relaying(pk)?.relay(pk, bytes)) ?? null;
216
+ }
217
+ // Whether one of this harbor's doors is that ward's.
218
+ holds(pk) {
219
+ return this.#door(pk) !== undefined;
220
+ }
221
+ // Every carrier asleep, the last opened first: nothing listens and no
222
+ // line stays open.
223
+ async close() {
224
+ for (const carrier of this.#carriers.reverse())
225
+ await carrier.sleep();
226
+ await this.#terrain.release();
227
+ }
228
+ get #box() {
229
+ return this.#wards.get(BOX);
230
+ }
231
+ get #dock() {
232
+ return this.#box.ward;
233
+ }
234
+ // A kind, through the registry faculty of the box named, or the
235
+ // catalogue. The catalogue's own kind is the core's, and resolves before
236
+ // any registry stands.
237
+ #classOf(kind, registry = CATALOGUE) {
238
+ if (kind === Catalogue.kind)
239
+ return Catalogue;
240
+ const found = this.#wards.get(BOX)?.being(registry);
241
+ return found instanceof RegistryFaculty ? found.classOf(kind) : undefined;
242
+ }
243
+ // The classes of a hosted ward, every one through the registry the dock
244
+ // keeps for it.
245
+ #through(registry) {
246
+ return { classOf: (kind) => this.#classOf(kind, registry) };
247
+ }
248
+ // A hosted ward standing, as the dock's cells name it.
249
+ async #stand(hosted) {
250
+ const fresh = !this.#wards.has(hosted.ward);
251
+ try {
252
+ if (fresh)
253
+ await this.#unpack(hosted.ward, unhex(hosted.seed), { ward: hostedWard(this.#terrain.defaults), classes: this.#through(hosted.registry) }, this.#keeper(hosted.memory));
254
+ await this.#wards.get(hosted.ward).standWard();
255
+ delete this.#failed.wards[hosted.ward];
256
+ return fresh;
257
+ }
258
+ catch (e) {
259
+ this.#wards.delete(hosted.ward);
260
+ this.#failed.wards[hosted.ward] = e instanceof Error ? e.message : String(e);
261
+ return false;
262
+ }
263
+ }
264
+ // Every place of the root memory and of each memory faculty that the
265
+ // dock does not name there, gone. A crash inside `host` or `move` leaves
266
+ // such a place, sealed under a seed nothing kept or kept elsewhere, and
267
+ // nothing else writes one. A place a memory faculty keeps in the root
268
+ // memory is the memory faculty's.
269
+ async #sweep() {
270
+ const named = async (memory) => {
271
+ const wards = this.#dock.hosted.filter((h) => h.memory === memory).map((h) => h.ward);
272
+ return new Set(await Promise.all((memory === undefined ? [BOX, ...wards] : wards).map((name) => this.#package.place(name))));
273
+ };
274
+ const memories = this.#memories();
275
+ const swept = [];
276
+ const root = await named(undefined);
277
+ for (const place of await this.#terrain.memory.places()) {
278
+ if (root.has(place) || Dna.occupies(place) || memories.some(([, s]) => s.occupies(place)))
279
+ continue;
280
+ await this.#terrain.memory.forget(place);
281
+ swept.push(place);
282
+ }
283
+ for (const [key, memory] of memories) {
284
+ const mine = await named(key);
285
+ for (const place of await memory.places()) {
286
+ if (mine.has(place))
287
+ continue;
288
+ await memory.forget(place);
289
+ swept.push(place);
290
+ }
291
+ }
292
+ return swept;
293
+ }
294
+ // A standing ward, carried whole to another keeper. The ward leaves the
295
+ // harbor's doors while it moves, so no arrival lands on the keeper it
296
+ // leaves.
297
+ async #move(name, seed, from, to) {
298
+ const ward = this.#wards.get(name);
299
+ if (!ward)
300
+ return 'the ward does not stand';
301
+ const source = this.#keeper(from);
302
+ const target = this.#keeper(to);
303
+ this.#wards.delete(name);
304
+ try {
305
+ if (!(await ward.partition.kept()))
306
+ throw new Error('the ward was not kept');
307
+ const place = await this.#package.place(name);
308
+ const entries = new Map(await source.read(place));
309
+ for (const entry of (await target.read(place)).keys())
310
+ if (!entries.has(entry))
311
+ entries.set(entry, null);
312
+ await target.write(place, entries);
313
+ const registry = this.#dock.hosted.find((h) => h.ward === name)?.registry;
314
+ const moved = await this.#unpack(name, unhex(seed), { ward: hostedWard(this.#terrain.defaults), classes: this.#through(registry) }, target);
315
+ await moved.standWard();
316
+ return null;
317
+ }
318
+ catch (e) {
319
+ this.#wards.set(name, ward);
320
+ return e instanceof Error ? e.message : String(e);
321
+ }
322
+ }
323
+ // The root memory, or the memory faculty standing under the key named.
324
+ #keeper(memory) {
325
+ if (memory === undefined)
326
+ return this.#terrain.memory;
327
+ const being = this.#box.being(memory);
328
+ if (being instanceof MemoryFaculty)
329
+ return being;
330
+ throw new Error(`the memory faculty ${memory} does not stand`);
331
+ }
332
+ #memories() {
333
+ return Object.keys(this.#box.partition.beings).flatMap((key) => {
334
+ const being = this.#box.being(key);
335
+ return being instanceof MemoryFaculty ? [[key, being]] : [];
336
+ });
337
+ }
338
+ // What did not stand when the harbor opened, each alone, and why the box
339
+ // ward stands the default dock where her row names another.
340
+ #failures() {
341
+ const fault = this.#box.fault;
342
+ return { wards: { ...this.#failed.wards, ...(fault === null ? {} : { [BOX]: fault }) }, routes: { ...this.#failed.routes } };
343
+ }
344
+ // This harbor's own doors and relays first, then a route's addresses in
345
+ // order, each to the carrier that dials it, and with no route the
346
+ // terrain's carrier.
347
+ async #carry(pk, bytes) {
348
+ if (this.holds(pk) || this.#relaying(pk))
349
+ return this.arrive(pk, bytes);
350
+ const at = this.#dock.routes[pk];
351
+ if (at === undefined)
352
+ return this.#terrain.carrier.carry(pk, bytes);
353
+ for (const address of at) {
354
+ const carrier = this.#carriers.find((c) => c.accepts(address));
355
+ const out = carrier ? await carrier.dial(address, pk, bytes) : UNDIALED;
356
+ if (out !== UNDIALED)
357
+ return out;
358
+ }
359
+ return null;
360
+ }
361
+ // A ward the dock hosts stands now, under the seed named or a drawn one,
362
+ // and the seed it stands under comes back. A ward whose key another ward
363
+ // of this harbor already has does not stand.
364
+ async #host(name, invitation, seed, memory, kind, registry) {
365
+ if (this.#wards.has(name))
366
+ return null;
367
+ const bytes = seed === undefined ? this.#terrain.entropy.draw(32) : isHex(seed, 32) ? unhex(seed) : null;
368
+ if (bytes === null || this.holds((await WardKey.from(bytes)).pk))
369
+ return null;
370
+ let house;
371
+ try {
372
+ house = await this.#unpack(name, bytes, { dock: invitation, ward: hostedWard(this.#terrain.defaults, kind), classes: this.#through(registry) }, this.#keeper(memory));
373
+ await house.standWard();
374
+ }
375
+ catch {
376
+ this.#wards.delete(name);
377
+ return null;
378
+ }
379
+ if (!house.ward.stance.standings.get(DOCK)) {
380
+ this.#wards.delete(name);
381
+ return null;
382
+ }
383
+ return hex(bytes);
384
+ }
385
+ // A route is taken where a carrier of this harbor dials one of its
386
+ // addresses; forgetting one always is.
387
+ #route(pk, at) {
388
+ const taken = isHex(pk, 64) && (at === null || this.#dialable(at));
389
+ if (taken)
390
+ delete this.#failed.routes[pk];
391
+ return taken;
392
+ }
393
+ // The carrier faculties standing in the box ward.
394
+ get #carriers() {
395
+ return Object.keys(this.#box.partition.beings)
396
+ .map((key) => this.#box.being(key))
397
+ .filter((being) => being instanceof CarrierFaculty);
398
+ }
399
+ #relaying(pk) {
400
+ return this.#carriers.find((carrier) => carrier.relays(pk));
401
+ }
402
+ #dialable(at) {
403
+ return at.some((address) => this.#carriers.some((carrier) => carrier.accepts(address)));
404
+ }
405
+ async #unpack(name, seed, own, keeper) {
406
+ const { entropy, clock } = this.#terrain;
407
+ const ward = await House.unpack({
408
+ seed,
409
+ memory: await this.#package.rows(name, keeper),
410
+ entropy,
411
+ clock,
412
+ carrier: this.#carrier,
413
+ routes: this.#routes,
414
+ ...own,
415
+ });
416
+ this.#wards.set(name, ward);
417
+ return ward;
418
+ }
419
+ // Every ward is reached where the harbor is: where the root's `reach`
420
+ // says, and where it said nothing, where its carriers listen, save the
421
+ // unspecified host. What a ward learns from an invitation's `at` is the
422
+ // dock's to keep. A ward of this harbor needs no route.
423
+ #routes = {
424
+ reach: () => {
425
+ if (!this.#wards.has(BOX))
426
+ return [];
427
+ const set = this.#dock.addresses;
428
+ return set.length > 0 ? set : this.#carriers.flatMap((carrier) => carrier.listening()).filter((address) => !unspecified(address));
429
+ },
430
+ learn: (ward, at) => (this.holds(ward) ? Promise.resolve() : this.#dock.learn(ward, at)),
431
+ };
432
+ #door(pk) {
433
+ for (const ward of this.#wards.values())
434
+ if (ward.pk === pk)
435
+ return ward;
436
+ return undefined;
437
+ }
438
+ }
@@ -0,0 +1,11 @@
1
+ export { Catalogue, CATALOGUE, type Cataloguing } from './catalogue.ts';
2
+ export { Dna } from './dna.ts';
3
+ export { BOX, Dock, type DockStance, type Failures, type Hosted, type Hosting } from './dock.ts';
4
+ export { CarrierFaculty, carrierIn, groundOf, UNDIALED, type Arrivals, type Dialed, type Ground, type Sockets, type TcpListening, type WebListen, type WebListener, type WebServe } from './carrying.ts';
5
+ export { Harbor } from './harbor.ts';
6
+ export { carryPlaces, copyPackage, landPlaces, Package, readCarried, type Carried } from './package.ts';
7
+ export { readRootRequest, type RootRequest } from './root-line.ts';
8
+ export { addGround, grounds, probeGround, type GroundProbe, type KnownGround, type Probing } from './probe.ts';
9
+ export { registers, Registry, REGISTRY, RegistryFaculty } from './registry.ts';
10
+ export { MEMORY, MemoryFaculty } from './memory.ts';
11
+ export { Terrain, type Defaults } from './terrain.ts';
@@ -2,13 +2,13 @@
2
2
  // The onion: a terrain, the package, the dock, the catalogue and its
3
3
  // registry, and the harbor.
4
4
  export { Catalogue, CATALOGUE } from './catalogue.js';
5
+ export { Dna } from './dna.js';
5
6
  export { BOX, Dock } from './dock.js';
6
- export { CarrierFaculty, UNDIALED } from './carrying.js';
7
+ export { CarrierFaculty, carrierIn, groundOf, UNDIALED } from './carrying.js';
7
8
  export { Harbor } from './harbor.js';
8
9
  export { carryPlaces, copyPackage, landPlaces, Package, readCarried } from './package.js';
9
- export { readRootRequest, rootLine } from './root-line.js';
10
+ export { readRootRequest } from './root-line.js';
10
11
  export { addGround, grounds, probeGround } from './probe.js';
11
- export { Registry } from './registry.js';
12
- export { Push, PUSH, RELAY, RELAY_CLIENT, RELAY_HOLD, RELAY_REST, RELAY_WAIT, RELAYED } from './relay.js';
13
- export { GROUND_STORE, groundStore, Store, STORE } from './store.js';
12
+ export { registers, Registry, REGISTRY, RegistryFaculty } from './registry.js';
13
+ export { MEMORY, MemoryFaculty } from './memory.js';
14
14
  export { Terrain } from './terrain.js';
@@ -0,0 +1,10 @@
1
+ import { Faculty } from '../being/index.ts';
2
+ export declare const MEMORY = "org.nervur.memory";
3
+ export declare abstract class MemoryFaculty extends Faculty {
4
+ static readonly kind: string;
5
+ abstract read(place: string): Promise<Map<string, Uint8Array>>;
6
+ abstract write(place: string, entries: ReadonlyMap<string, Uint8Array | null>): Promise<void>;
7
+ abstract places(): Promise<string[]>;
8
+ abstract forget(place: string): Promise<void>;
9
+ occupies(_place: string): boolean;
10
+ }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // The memory faculty: a faculty that keeps a hosted ward's place, where the
3
+ // root memory does not. It makes the same promise the Memory body makes,
4
+ // lent once the dock stands: sealed entries in places, each keep whole or
5
+ // not at all. The box ward never moves off the root memory, since the
6
+ // memory faculty itself stands from the box ward's cells.
7
+ //
8
+ // A ward is the unit a memory faculty holds: its head, its ward and every
9
+ // being of it are one place and one keep, so an answer's cells and the
10
+ // door's keys move together, whichever memory faculty keeps them. A memory
11
+ // faculty of a disk, a cloud, a database or a ledger is a class fulfilling
12
+ // `org.nervur.memory`.
13
+ import { Faculty, ships } from '../being/index.js';
14
+ export const MEMORY = 'org.nervur.memory';
15
+ export class MemoryFaculty extends Faculty {
16
+ static kind = MEMORY;
17
+ static {
18
+ ships(this);
19
+ }
20
+ // Whether a place of the root memory is this memory faculty's own, so the root's
21
+ // sweep leaves it.
22
+ occupies(_place) {
23
+ return false;
24
+ }
25
+ }
@@ -3,7 +3,6 @@ export declare const copyPackage: (from: Memory, to: Memory) => Promise<string[]
3
3
  export type Carried = {
4
4
  seed?: string;
5
5
  places: Record<string, Record<string, string>>;
6
- modules?: Record<string, string>;
7
6
  };
8
7
  export declare const readCarried: (value: unknown) => Carried | null;
9
8
  export declare const carryPlaces: (memory: Memory) => Promise<Carried['places']>;
@@ -30,12 +30,9 @@ export const copyPackage = async (from, to) => {
30
30
  export const readCarried = (value) => {
31
31
  if (typeof value !== 'object' || value === null)
32
32
  return null;
33
- const { seed, places, modules } = value;
33
+ const { seed, places } = value;
34
34
  if (seed !== undefined && !isHex(seed, 32))
35
35
  return null;
36
- const hints = modules === undefined || (typeof modules === 'object' && modules !== null && !Array.isArray(modules) && Object.values(modules).every((m) => typeof m === 'string'));
37
- if (!hints)
38
- return null;
39
36
  if (typeof places !== 'object' || places === null || Array.isArray(places))
40
37
  return null;
41
38
  for (const entries of Object.values(places)) {
@@ -45,7 +42,7 @@ export const readCarried = (value) => {
45
42
  if (!isHex(bytes))
46
43
  return null;
47
44
  }
48
- return { ...(seed === undefined ? {} : { seed }), places: places, ...(modules === undefined ? {} : { modules: modules }) };
45
+ return { ...(seed === undefined ? {} : { seed }), places: places };
49
46
  };
50
47
  // Every place of a memory, as a carried harbor holds it.
51
48
  export const carryPlaces = async (memory) => {
@@ -77,7 +74,8 @@ class PackageRows {
77
74
  this.#told.add(row);
78
75
  }
79
76
  // Every row told since the last keep, sealed and written as one keep, one
80
- // keep at a time.
77
+ // keep at a time. Where nothing was told, nothing is written, so an ask
78
+ // that only reads keeps even where the keeper refuses every write.
81
79
  kept() {
82
80
  const rows = [...this.#told];
83
81
  this.#told.clear();
@@ -85,6 +83,8 @@ class PackageRows {
85
83
  return this.#line;
86
84
  }
87
85
  async #write(told) {
86
+ if (told.length === 0)
87
+ return true;
88
88
  const beings = (this.rows.beings ?? {});
89
89
  const entries = new Map();
90
90
  for (const row of told) {
@@ -95,7 +95,7 @@ class PackageRows {
95
95
  return true;
96
96
  }
97
97
  }
98
- class Ward {
98
+ class WardPlace {
99
99
  #pack;
100
100
  #name;
101
101
  #seal;
@@ -151,9 +151,9 @@ export class Package {
151
151
  return this.derive(['place', name], 16).then(hex);
152
152
  }
153
153
  // One ward's rows, as its keeper kept them: the root memory unless a
154
- // store is named.
154
+ // memory faculty is named.
155
155
  async rows(name, keeper = this.memory) {
156
- const ward = new Ward(this, name, await this.derive(['seal', name], 32), await this.place(name), keeper);
156
+ const ward = new WardPlace(this, name, await this.derive(['seal', name], 32), await this.place(name), keeper);
157
157
  const rows = {};
158
158
  const beings = {};
159
159
  let any = false;
@@ -0,0 +1,22 @@
1
+ import type { Bundled } from '../contract/index.ts';
2
+ import type { Defaults, Terrain } from './terrain.ts';
3
+ export type Probing = {
4
+ readonly where?: string;
5
+ readonly given?: unknown;
6
+ readonly bundle?: readonly Bundled[];
7
+ };
8
+ export type GroundProbe = {
9
+ readonly name: string;
10
+ fits(probing: Probing): boolean;
11
+ terrain(probing: Probing, defaults: Defaults): Terrain;
12
+ };
13
+ export type KnownGround = {
14
+ readonly probe: GroundProbe;
15
+ readonly defaults: Defaults;
16
+ };
17
+ export declare const addGround: (probe: GroundProbe, defaults: Defaults) => void;
18
+ export declare const grounds: () => string[];
19
+ export declare const probeGround: (probing: Probing, among?: readonly KnownGround[]) => {
20
+ ground: string;
21
+ terrain: Terrain;
22
+ };
@@ -0,0 +1,15 @@
1
+ const known = [];
2
+ // A ground this process can stand on, known once by its name.
3
+ export const addGround = (probe, defaults) => {
4
+ if (!known.some((k) => k.probe.name === probe.name))
5
+ known.push({ probe, defaults });
6
+ };
7
+ // The grounds known, in the order they are tried.
8
+ export const grounds = () => known.map((k) => k.probe.name).reverse();
9
+ // The terrain of the first ground that fits, and its name.
10
+ export const probeGround = (probing, among = known) => {
11
+ for (const { probe, defaults } of [...among].reverse())
12
+ if (probe.fits(probing))
13
+ return { ground: probe.name, terrain: probe.terrain(probing, defaults) };
14
+ throw new Error('no ground fits here');
15
+ };
@@ -0,0 +1,15 @@
1
+ import { Faculty, type BeingClass } from '../being/index.ts';
2
+ import type { Module } from '../contract/index.ts';
3
+ export declare const REGISTRY = "org.nervur.registry";
4
+ export declare abstract class RegistryFaculty extends Faculty {
5
+ static readonly kind: string;
6
+ abstract classOf(kind: string): BeingClass | undefined;
7
+ }
8
+ export declare const registers: (C: unknown) => C is typeof RegistryFaculty;
9
+ export declare class Registry {
10
+ #private;
11
+ constructor(kit: readonly BeingClass[], modules: readonly Module[]);
12
+ static refusal(kit: readonly BeingClass[], modules: readonly Module[]): string | null;
13
+ classOf(kind: string): BeingClass | undefined;
14
+ kindsOf(module: string): string[];
15
+ }