nervur 0.22.0 → 0.22.2-3

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 (398) hide show
  1. package/AUTHORING.md +741 -0
  2. package/KIT-SPEC.md +286 -0
  3. package/LICENSE +1 -1
  4. package/NOTICE +6 -2
  5. package/README.md +97 -424
  6. package/dist/app/app-ground.d.ts +18 -0
  7. package/dist/app/app-ground.js +25 -0
  8. package/dist/app/index.d.ts +2 -0
  9. package/dist/app/index.js +5 -0
  10. package/dist/app/native.d.ts +46 -0
  11. package/dist/app/native.js +101 -0
  12. package/dist/being/being.d.ts +229 -0
  13. package/dist/being/being.js +20 -0
  14. package/dist/being/covers.d.ts +9 -0
  15. package/dist/being/covers.js +21 -0
  16. package/dist/being/index.d.ts +3 -0
  17. package/dist/being/index.js +5 -0
  18. package/dist/being/need.d.ts +49 -0
  19. package/dist/being/need.js +33 -0
  20. package/dist/being/schema.d.ts +100 -0
  21. package/dist/being/schema.js +132 -0
  22. package/dist/being/table.d.ts +42 -0
  23. package/dist/being/table.js +288 -0
  24. package/dist/bench/bench-ground.d.ts +55 -0
  25. package/dist/bench/bench-ground.js +101 -0
  26. package/dist/bench/bench.d.ts +87 -0
  27. package/dist/bench/bench.js +260 -0
  28. package/dist/bench/fake-carry.d.ts +32 -0
  29. package/dist/bench/fake-carry.js +56 -0
  30. package/dist/bench/fake-clock.d.ts +17 -0
  31. package/dist/bench/fake-clock.js +34 -0
  32. package/dist/bench/fake-custody.d.ts +9 -0
  33. package/dist/bench/fake-custody.js +10 -0
  34. package/dist/bench/fake-faculty.d.ts +25 -0
  35. package/dist/bench/fake-faculty.js +48 -0
  36. package/dist/bench/fake-keys.d.ts +5 -0
  37. package/dist/bench/fake-keys.js +9 -0
  38. package/dist/bench/fake-memory.d.ts +14 -0
  39. package/dist/bench/fake-memory.js +46 -0
  40. package/dist/bench/fake-network.d.ts +57 -0
  41. package/dist/bench/fake-network.js +169 -0
  42. package/dist/bench/index.d.ts +11 -0
  43. package/dist/bench/index.js +13 -0
  44. package/dist/bench/seeded.d.ts +11 -0
  45. package/dist/bench/seeded.js +37 -0
  46. package/dist/bench/settle.d.ts +2 -0
  47. package/dist/bench/settle.js +49 -0
  48. package/dist/bench/stewards.d.ts +17 -0
  49. package/dist/bench/stewards.js +20 -0
  50. package/dist/bodies/class-list.d.ts +14 -0
  51. package/dist/bodies/class-list.js +33 -0
  52. package/dist/bodies/joined-carry.d.ts +23 -0
  53. package/dist/bodies/joined-carry.js +42 -0
  54. package/dist/bodies/noble-crypto.d.ts +22 -0
  55. package/dist/bodies/noble-crypto.js +88 -0
  56. package/dist/bodies/seed-keys.d.ts +10 -0
  57. package/dist/bodies/seed-keys.js +42 -0
  58. package/dist/bodies/strict-tools.d.ts +10 -0
  59. package/dist/bodies/strict-tools.js +306 -0
  60. package/dist/bodies/web-carry.d.ts +65 -0
  61. package/dist/bodies/web-carry.js +224 -0
  62. package/dist/bodies/web-clock.d.ts +12 -0
  63. package/dist/bodies/web-clock.js +33 -0
  64. package/dist/browser/browser-ground.d.ts +69 -0
  65. package/dist/browser/browser-ground.js +219 -0
  66. package/dist/browser/index.d.ts +4 -0
  67. package/dist/browser/index.js +7 -0
  68. package/dist/browser/indexeddb-memory.d.ts +17 -0
  69. package/dist/browser/indexeddb-memory.js +97 -0
  70. package/dist/browser/locked-custody.d.ts +25 -0
  71. package/dist/browser/locked-custody.js +89 -0
  72. package/dist/browser/origin-classes.d.ts +7 -0
  73. package/dist/browser/origin-classes.js +31 -0
  74. package/dist/foundation.d.ts +150 -0
  75. package/dist/foundation.js +4 -0
  76. package/dist/ground/ground.d.ts +177 -0
  77. package/dist/ground/ground.js +363 -0
  78. package/dist/house/crossing.d.ts +37 -0
  79. package/dist/house/crossing.js +131 -0
  80. package/dist/house/house.d.ts +80 -0
  81. package/dist/house/house.js +1753 -0
  82. package/dist/house/rows-shape.d.ts +103 -0
  83. package/dist/house/rows-shape.js +12 -0
  84. package/dist/house/rows.d.ts +27 -0
  85. package/dist/house/rows.js +168 -0
  86. package/dist/index.d.ts +29 -1
  87. package/dist/index.js +25 -14
  88. package/dist/node/bridge.d.ts +17 -0
  89. package/dist/node/bridge.js +188 -0
  90. package/dist/node/cli.js +170 -0
  91. package/dist/node/custody.d.ts +20 -0
  92. package/dist/node/custody.js +34 -0
  93. package/dist/node/file-keys.d.ts +7 -0
  94. package/dist/node/file-keys.js +30 -0
  95. package/dist/node/file-memory.d.ts +13 -0
  96. package/dist/node/file-memory.js +91 -0
  97. package/dist/node/folder-classes.d.ts +5 -0
  98. package/dist/node/folder-classes.js +40 -0
  99. package/dist/node/gone.d.ts +2 -0
  100. package/dist/node/gone.js +7 -0
  101. package/dist/node/hand.d.ts +29 -0
  102. package/dist/node/hand.js +85 -0
  103. package/dist/node/held-keys.d.ts +14 -0
  104. package/dist/node/held-keys.js +36 -0
  105. package/dist/node/http.d.ts +11 -0
  106. package/dist/node/http.js +90 -0
  107. package/dist/node/index.d.ts +13 -0
  108. package/dist/node/index.js +15 -0
  109. package/dist/node/keychain-keys.d.ts +10 -0
  110. package/dist/node/keychain-keys.js +51 -0
  111. package/dist/node/ledger-memory.d.ts +17 -0
  112. package/dist/node/ledger-memory.js +151 -0
  113. package/dist/node/lock.d.ts +10 -0
  114. package/dist/node/lock.js +78 -0
  115. package/dist/node/node-ground.d.ts +33 -0
  116. package/dist/node/node-ground.js +147 -0
  117. package/dist/node/notify.d.ts +1 -0
  118. package/dist/node/notify.js +18 -0
  119. package/dist/node/tcp-carry.d.ts +39 -0
  120. package/dist/node/tcp-carry.js +216 -0
  121. package/dist/node/websocket.d.ts +6 -0
  122. package/dist/node/websocket.js +118 -0
  123. package/dist/quo/frame.d.ts +20 -0
  124. package/dist/quo/frame.js +48 -0
  125. package/dist/quo/room.d.ts +154 -0
  126. package/dist/quo/room.js +362 -0
  127. package/dist/serve/index.d.ts +27 -0
  128. package/dist/serve/index.js +55 -0
  129. package/package.json +49 -47
  130. package/dist/browser.d.ts +0 -1
  131. package/dist/browser.js +0 -8
  132. package/dist/cli.js +0 -16
  133. package/dist/core/being/being.d.ts +0 -17
  134. package/dist/core/being/being.js +0 -72
  135. package/dist/core/being/digest.d.ts +0 -3
  136. package/dist/core/being/digest.js +0 -17
  137. package/dist/core/being/faculty.d.ts +0 -10
  138. package/dist/core/being/faculty.js +0 -77
  139. package/dist/core/being/index.d.ts +0 -6
  140. package/dist/core/being/index.js +0 -8
  141. package/dist/core/being/kind.d.ts +0 -6
  142. package/dist/core/being/kind.js +0 -34
  143. package/dist/core/being/types.d.ts +0 -61
  144. package/dist/core/being/types.js +0 -4
  145. package/dist/core/being/words.d.ts +0 -13
  146. package/dist/core/being/words.js +0 -14
  147. package/dist/core/browser/index.d.ts +0 -37
  148. package/dist/core/browser/index.js +0 -196
  149. package/dist/core/browser/worker.d.ts +0 -11
  150. package/dist/core/browser/worker.js +0 -37
  151. package/dist/core/cli/command.d.ts +0 -13
  152. package/dist/core/cli/command.js +0 -330
  153. package/dist/core/cli/edge.d.ts +0 -7
  154. package/dist/core/cli/edge.js +0 -79
  155. package/dist/core/cli/harbor.d.ts +0 -25
  156. package/dist/core/cli/harbor.js +0 -115
  157. package/dist/core/contract/index.d.ts +0 -42
  158. package/dist/core/contract/index.js +0 -34
  159. package/dist/core/contract/link.d.ts +0 -4
  160. package/dist/core/contract/link.js +0 -45
  161. package/dist/core/crypto/aes.d.ts +0 -3
  162. package/dist/core/crypto/aes.js +0 -24
  163. package/dist/core/crypto/bytes.d.ts +0 -6
  164. package/dist/core/crypto/bytes.js +0 -33
  165. package/dist/core/crypto/ed25519.d.ts +0 -3
  166. package/dist/core/crypto/ed25519.js +0 -93
  167. package/dist/core/crypto/hash.d.ts +0 -2
  168. package/dist/core/crypto/hash.js +0 -11
  169. package/dist/core/crypto/index.d.ts +0 -7
  170. package/dist/core/crypto/index.js +0 -10
  171. package/dist/core/crypto/json.d.ts +0 -8
  172. package/dist/core/crypto/json.js +0 -250
  173. package/dist/core/crypto/mlkem.d.ts +0 -12
  174. package/dist/core/crypto/mlkem.js +0 -36
  175. package/dist/core/crypto/subtle.d.ts +0 -3
  176. package/dist/core/crypto/subtle.js +0 -11
  177. package/dist/core/crypto/x25519.d.ts +0 -2
  178. package/dist/core/crypto/x25519.js +0 -24
  179. package/dist/core/edge/index.d.ts +0 -164
  180. package/dist/core/edge/index.js +0 -739
  181. package/dist/core/edge/kit.d.ts +0 -2
  182. package/dist/core/edge/kit.js +0 -2
  183. package/dist/core/folder/index.d.ts +0 -18
  184. package/dist/core/folder/index.js +0 -130
  185. package/dist/core/git/http.d.ts +0 -6
  186. package/dist/core/git/http.js +0 -102
  187. package/dist/core/git/index.d.ts +0 -5
  188. package/dist/core/git/index.js +0 -10
  189. package/dist/core/git/object.d.ts +0 -40
  190. package/dist/core/git/object.js +0 -103
  191. package/dist/core/git/pack.d.ts +0 -9
  192. package/dist/core/git/pack.js +0 -171
  193. package/dist/core/git/store.d.ts +0 -23
  194. package/dist/core/git/store.js +0 -120
  195. package/dist/core/git/zlib.d.ts +0 -6
  196. package/dist/core/git/zlib.js +0 -210
  197. package/dist/core/harbor/carrying.d.ts +0 -51
  198. package/dist/core/harbor/carrying.js +0 -69
  199. package/dist/core/harbor/catalogue.d.ts +0 -33
  200. package/dist/core/harbor/catalogue.js +0 -365
  201. package/dist/core/harbor/dna.d.ts +0 -13
  202. package/dist/core/harbor/dna.js +0 -120
  203. package/dist/core/harbor/dock.d.ts +0 -62
  204. package/dist/core/harbor/dock.js +0 -381
  205. package/dist/core/harbor/harbor.d.ts +0 -16
  206. package/dist/core/harbor/harbor.js +0 -438
  207. package/dist/core/harbor/index.d.ts +0 -11
  208. package/dist/core/harbor/index.js +0 -14
  209. package/dist/core/harbor/memory.d.ts +0 -10
  210. package/dist/core/harbor/memory.js +0 -25
  211. package/dist/core/harbor/package.d.ts +0 -20
  212. package/dist/core/harbor/package.js +0 -172
  213. package/dist/core/harbor/probe.d.ts +0 -22
  214. package/dist/core/harbor/probe.js +0 -15
  215. package/dist/core/harbor/registry.d.ts +0 -15
  216. package/dist/core/harbor/registry.js +0 -110
  217. package/dist/core/harbor/root-line.d.ts +0 -7
  218. package/dist/core/harbor/root-line.js +0 -9
  219. package/dist/core/harbor/terrain.d.ts +0 -25
  220. package/dist/core/harbor/terrain.js +0 -28
  221. package/dist/core/http/index.d.ts +0 -2
  222. package/dist/core/http/index.js +0 -154
  223. package/dist/core/http/websocket.d.ts +0 -29
  224. package/dist/core/http/websocket.js +0 -133
  225. package/dist/core/line/answer.d.ts +0 -8
  226. package/dist/core/line/answer.js +0 -60
  227. package/dist/core/line/frame.d.ts +0 -29
  228. package/dist/core/line/frame.js +0 -77
  229. package/dist/core/line/ground.d.ts +0 -3
  230. package/dist/core/line/ground.js +0 -7
  231. package/dist/core/line/index.d.ts +0 -4
  232. package/dist/core/line/index.js +0 -8
  233. package/dist/core/line/web.d.ts +0 -12
  234. package/dist/core/line/web.js +0 -117
  235. package/dist/core/node/index.d.ts +0 -23
  236. package/dist/core/node/index.js +0 -124
  237. package/dist/core/pointer/bodies.d.ts +0 -31
  238. package/dist/core/pointer/bodies.js +0 -118
  239. package/dist/core/pointer/index.d.ts +0 -2
  240. package/dist/core/pointer/index.js +0 -4
  241. package/dist/core/pointer/world.d.ts +0 -45
  242. package/dist/core/pointer/world.js +0 -106
  243. package/dist/core/proof/contracts.d.ts +0 -19
  244. package/dist/core/proof/contracts.js +0 -116
  245. package/dist/core/proof/expect.d.ts +0 -6
  246. package/dist/core/proof/expect.js +0 -18
  247. package/dist/core/proof/index.d.ts +0 -3
  248. package/dist/core/proof/index.js +0 -14
  249. package/dist/core/proof/law.d.ts +0 -25
  250. package/dist/core/proof/law.js +0 -715
  251. package/dist/core/quo/address.d.ts +0 -19
  252. package/dist/core/quo/address.js +0 -84
  253. package/dist/core/quo/door.d.ts +0 -34
  254. package/dist/core/quo/door.js +0 -174
  255. package/dist/core/quo/index.d.ts +0 -9
  256. package/dist/core/quo/index.js +0 -12
  257. package/dist/core/quo/invitation.d.ts +0 -8
  258. package/dist/core/quo/invitation.js +0 -19
  259. package/dist/core/quo/keys.d.ts +0 -40
  260. package/dist/core/quo/keys.js +0 -79
  261. package/dist/core/quo/payload.d.ts +0 -15
  262. package/dist/core/quo/payload.js +0 -55
  263. package/dist/core/quo/relations.d.ts +0 -40
  264. package/dist/core/quo/relations.js +0 -33
  265. package/dist/core/quo/reply.d.ts +0 -13
  266. package/dist/core/quo/reply.js +0 -35
  267. package/dist/core/quo/seal.d.ts +0 -42
  268. package/dist/core/quo/seal.js +0 -78
  269. package/dist/core/quo/standing.d.ts +0 -39
  270. package/dist/core/quo/standing.js +0 -90
  271. package/dist/core/tcp/index.d.ts +0 -27
  272. package/dist/core/tcp/index.js +0 -209
  273. package/dist/core/ward/allowance.d.ts +0 -14
  274. package/dist/core/ward/allowance.js +0 -32
  275. package/dist/core/ward/cells.d.ts +0 -7
  276. package/dist/core/ward/cells.js +0 -74
  277. package/dist/core/ward/house.d.ts +0 -67
  278. package/dist/core/ward/house.js +0 -473
  279. package/dist/core/ward/index.d.ts +0 -5
  280. package/dist/core/ward/index.js +0 -7
  281. package/dist/core/ward/partition.d.ts +0 -50
  282. package/dist/core/ward/partition.js +0 -66
  283. package/dist/core/ward/stance.d.ts +0 -29
  284. package/dist/core/ward/stance.js +0 -186
  285. package/dist/core/ward/ward.d.ts +0 -44
  286. package/dist/core/ward/ward.js +0 -140
  287. package/dist/core.d.ts +0 -10
  288. package/dist/core.js +0 -19
  289. package/dist/defaults/dock/index.d.ts +0 -4
  290. package/dist/defaults/dock/index.js +0 -11
  291. package/dist/defaults/index.d.ts +0 -5
  292. package/dist/defaults/index.js +0 -10
  293. package/dist/defaults/memory/index.d.ts +0 -12
  294. package/dist/defaults/memory/index.js +0 -39
  295. package/dist/defaults/tcp/index.d.ts +0 -16
  296. package/dist/defaults/tcp/index.js +0 -82
  297. package/dist/defaults/ward/index.d.ts +0 -4
  298. package/dist/defaults/ward/index.js +0 -11
  299. package/dist/defaults/web/index.d.ts +0 -15
  300. package/dist/defaults/web/index.js +0 -90
  301. package/dist/edge.d.ts +0 -1
  302. package/dist/edge.js +0 -9
  303. package/dist/kit.d.ts +0 -4
  304. package/dist/kit.js +0 -12
  305. package/dist/node.d.ts +0 -1
  306. package/dist/node.js +0 -8
  307. package/src/browser.ts +0 -10
  308. package/src/cli.ts +0 -15
  309. package/src/core/being/being.ts +0 -84
  310. package/src/core/being/digest.ts +0 -18
  311. package/src/core/being/faculty.ts +0 -76
  312. package/src/core/being/index.ts +0 -8
  313. package/src/core/being/kind.ts +0 -37
  314. package/src/core/being/types.ts +0 -74
  315. package/src/core/being/words.ts +0 -31
  316. package/src/core/browser/index.ts +0 -219
  317. package/src/core/browser/worker.ts +0 -63
  318. package/src/core/cli/command.ts +0 -311
  319. package/src/core/cli/edge.ts +0 -86
  320. package/src/core/cli/harbor.ts +0 -120
  321. package/src/core/contract/index.ts +0 -82
  322. package/src/core/contract/link.ts +0 -58
  323. package/src/core/crypto/aes.ts +0 -26
  324. package/src/core/crypto/bytes.ts +0 -37
  325. package/src/core/crypto/ed25519.ts +0 -92
  326. package/src/core/crypto/hash.ts +0 -14
  327. package/src/core/crypto/index.ts +0 -10
  328. package/src/core/crypto/json.ts +0 -241
  329. package/src/core/crypto/mlkem.ts +0 -38
  330. package/src/core/crypto/subtle.ts +0 -13
  331. package/src/core/crypto/x25519.ts +0 -23
  332. package/src/core/edge/index.ts +0 -865
  333. package/src/core/folder/index.ts +0 -137
  334. package/src/core/git/http.ts +0 -103
  335. package/src/core/git/index.ts +0 -10
  336. package/src/core/git/object.ts +0 -116
  337. package/src/core/git/pack.ts +0 -147
  338. package/src/core/git/store.ts +0 -122
  339. package/src/core/git/zlib.ts +0 -197
  340. package/src/core/harbor/carrying.ts +0 -124
  341. package/src/core/harbor/catalogue.ts +0 -386
  342. package/src/core/harbor/dna.ts +0 -116
  343. package/src/core/harbor/dock.ts +0 -420
  344. package/src/core/harbor/harbor.ts +0 -433
  345. package/src/core/harbor/index.ts +0 -14
  346. package/src/core/harbor/memory.ts +0 -31
  347. package/src/core/harbor/package.ts +0 -195
  348. package/src/core/harbor/probe.ts +0 -39
  349. package/src/core/harbor/registry.ts +0 -107
  350. package/src/core/harbor/root-line.ts +0 -19
  351. package/src/core/harbor/terrain.ts +0 -54
  352. package/src/core/http/index.ts +0 -147
  353. package/src/core/http/websocket.ts +0 -124
  354. package/src/core/line/answer.ts +0 -60
  355. package/src/core/line/frame.ts +0 -83
  356. package/src/core/line/ground.ts +0 -18
  357. package/src/core/line/index.ts +0 -8
  358. package/src/core/line/web.ts +0 -123
  359. package/src/core/node/index.ts +0 -139
  360. package/src/core/pointer/bodies.ts +0 -122
  361. package/src/core/pointer/index.ts +0 -4
  362. package/src/core/pointer/world.ts +0 -134
  363. package/src/core/proof/contracts.ts +0 -134
  364. package/src/core/proof/expect.ts +0 -25
  365. package/src/core/proof/index.ts +0 -14
  366. package/src/core/proof/law.ts +0 -742
  367. package/src/core/quo/address.ts +0 -87
  368. package/src/core/quo/door.ts +0 -180
  369. package/src/core/quo/index.ts +0 -12
  370. package/src/core/quo/invitation.ts +0 -19
  371. package/src/core/quo/keys.ts +0 -91
  372. package/src/core/quo/payload.ts +0 -61
  373. package/src/core/quo/relations.ts +0 -62
  374. package/src/core/quo/reply.ts +0 -38
  375. package/src/core/quo/seal.ts +0 -101
  376. package/src/core/quo/standing.ts +0 -111
  377. package/src/core/stand/main.ts +0 -20
  378. package/src/core/stand/stand.ts +0 -259
  379. package/src/core/tcp/index.ts +0 -227
  380. package/src/core/ward/allowance.ts +0 -47
  381. package/src/core/ward/cells.ts +0 -77
  382. package/src/core/ward/house.ts +0 -524
  383. package/src/core/ward/index.ts +0 -7
  384. package/src/core/ward/partition.ts +0 -117
  385. package/src/core/ward/stance.ts +0 -207
  386. package/src/core/ward/ward.ts +0 -166
  387. package/src/core.ts +0 -55
  388. package/src/defaults/dock/index.ts +0 -12
  389. package/src/defaults/index.ts +0 -10
  390. package/src/defaults/memory/index.ts +0 -50
  391. package/src/defaults/tcp/index.ts +0 -89
  392. package/src/defaults/ward/index.ts +0 -12
  393. package/src/defaults/web/index.ts +0 -97
  394. package/src/edge.ts +0 -11
  395. package/src/index.ts +0 -18
  396. package/src/kit.ts +0 -15
  397. package/src/node.ts +0 -10
  398. /package/dist/{cli.d.ts → node/cli.d.ts} +0 -0
@@ -1,386 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // The catalogue: the core's registry, the harbor's DNA. She keeps its
3
- // code as a git repository, from genesis, its objects in the root memory
4
- // under her own places and never in a cell. Her cells keep `live`, the
5
- // commit that stands, `origin`, where she fetches from, and `refs`, what
6
- // she fetched last. A commit holds one file per module,
7
- // `modules/<module id>.js`, and nothing else is read from it.
8
- //
9
- // add { source, name? } the module's source committed on `live`,
10
- // and `live` moved to it
11
- // remove { module } its file committed away, and `live` moved,
12
- // refused while a being stands on its kinds
13
- // live { commit? } `live` moved to a commit or a fetched ref,
14
- // or, with none, the commit that stands
15
- // log { commit? } the commits from `live` back, first
16
- // parents alone
17
- // origin { url } where `fetch` reads, or null
18
- // fetch every ref of `origin` and all it reaches,
19
- // kept, and the refs
20
- // gc every object that neither `live` nor a
21
- // fetched ref reaches, forgotten
22
- // modules what `live` runs, and why a module does not
23
- // sources `live`, and the source of each module
24
- // file it holds, by its blob
25
- //
26
- // She resolves a kind to a class from the kit and the modules `live`
27
- // runs, and nothing else does it for her: the harbor stands her before any
28
- // registry, from the core alone. Moving `live` checks the commit's modules
29
- // out, hands each to the terrain's loader and indexes them all: a set that
30
- // does not run together is refused with its reason, and `live` stays. Once
31
- // it runs, every being a new class resolves is born again on her stance,
32
- // and what stands on what now resolves stands. A
33
- // wake stands `live` again from the objects kept, with no network, and
34
- // there a module that does not load, or splits a kind with one before it,
35
- // stays out alone with its reason, and the beings of its kinds stand
36
- // absent. At genesis `live` is an empty commit.
37
- //
38
- // What `add` and `remove` commit is staged aside and written to the DNA
39
- // only once the commit checks, so a refused one leaves no object. `gc`
40
- // takes its turn with every ask that writes the DNA, keeps her cells
41
- // first, and forgets only what the kept `live` and refs do not reach, so
42
- // a cut mid-collection loses nothing a restart stands.
43
- //
44
- // She is the core's, of kind `org.nervur.catalogue`, answers the root and an
45
- // owner alone, and is born of her stance alone, whose `ground` is her
46
- // harbor.
47
- import { ships, type AskSpec, type BeingClass, type JsonObject, type Stance } from '../being/index.ts';
48
- import type { Module } from '../contract/index.ts';
49
- import { blob, fetchPack, files, havesFrom, isId, listRefs, reachable, readCommit, StagedObjects, text, tree, writeCommit, writeTree, type ObjectStore, type Signature } from '../git/index.ts';
50
- import { ownerAsk } from '../ward/index.ts';
51
- import { Registry, RegistryFaculty } from './registry.ts';
52
- import type { Terrain } from './terrain.ts';
53
-
54
- export const CATALOGUE = 'catalogue';
55
-
56
- const DIR = 'modules/';
57
- const SUFFIX = '.js';
58
- const pathOf = (module: string): string => `${DIR}${module}${SUFFIX}`;
59
- const WHO = { name: 'nervur', email: 'catalogue@nervur.org' };
60
-
61
- // What the catalogue asks of her harbor.
62
- export interface Cataloguing {
63
- readonly terrain: Terrain;
64
- readonly dna: ObjectStore & {
65
- // Every object but those named forgotten, and how many were.
66
- collect(keep: Iterable<string>): Promise<number>;
67
- };
68
- // The kit's own classes, which alone may be of its kinds.
69
- readonly kit: readonly BeingClass[];
70
- // Once `live` moved and runs: every being whose class moved is born
71
- // again, and what stands on what now resolves stands.
72
- ran(): Promise<void>;
73
- // Whether a being of any ward stands on one of these kinds.
74
- stands(kinds: readonly string[]): boolean;
75
- // Every kind a row of any ward keeps.
76
- kept(): string[];
77
- keep(): Promise<boolean>;
78
- }
79
-
80
- type Running = { module: Module; blob: string };
81
-
82
- const isText = (v: unknown): v is string => typeof v === 'string';
83
- const domainOf = (name: string): string => `${name.split('.').slice(0, 2).join('.')}.`;
84
- const failure = (e: unknown): string => (e instanceof Error ? e.message : String(e));
85
-
86
- export class Catalogue extends RegistryFaculty {
87
- static override readonly kind: string = 'org.nervur.catalogue';
88
- static {
89
- ships(this);
90
- }
91
- static override asks: Record<string, AskSpec> = {
92
- add: ownerAsk('a module committed on live, and live moved to it', { required: ['source'] }),
93
- remove: ownerAsk('a module committed away, and live moved', { required: ['module'] }),
94
- live: ownerAsk('live moved to a commit, or the commit that stands'),
95
- log: ownerAsk('the commits from live back'),
96
- origin: ownerAsk('where fetch reads', { required: ['url'] }),
97
- fetch: ownerAsk('every ref of origin and all it reaches, kept'),
98
- modules: ownerAsk('the modules live runs'),
99
- sources: ownerAsk('the source of each module file live holds, by its blob'),
100
- gc: ownerAsk('every object neither live nor a fetched ref reaches, forgotten'),
101
- };
102
-
103
- readonly #harbor: Cataloguing;
104
- // Every kind the kit and what `live` runs bring.
105
- #registry: Registry;
106
- // What `live` runs, by module, and why a module it holds does not.
107
- #running = new Map<string, Running>();
108
- #failed = new Map<string, { blob: string; reason: string }>();
109
- // Why `live` itself did not check out at wake, where it did not.
110
- #fault: string | null = null;
111
- // The asks that write the DNA, one after another.
112
- #turn: Promise<unknown> = Promise.resolve();
113
-
114
- constructor(stance: Stance) {
115
- super(stance);
116
- const { ground } = stance as Stance & { ground?: Cataloguing };
117
- if (!ground) throw new Error('the catalogue stands in the box ward alone');
118
- this.#harbor = ground;
119
- this.#registry = new Registry(ground.kit, []);
120
- }
121
-
122
- classOf(kind: string): BeingClass | undefined {
123
- return this.#registry.classOf(kind);
124
- }
125
-
126
- // Why these modules cannot run together, or null.
127
- #check(modules: readonly Module[]): string | null {
128
- return Registry.refusal(this.#harbor.kit, modules);
129
- }
130
-
131
- get #live(): string | undefined {
132
- return isId(this.cells.live) ? this.cells.live : undefined;
133
- }
134
-
135
- get #refs(): Record<string, string> {
136
- return (this.cells.refs ?? {}) as Record<string, string>;
137
- }
138
-
139
- #signature(): Signature {
140
- return { ...WHO, seconds: Math.floor(this.#harbor.terrain.clock.now() / 1000), zone: '+0000' };
141
- }
142
-
143
- // One ask that writes the DNA at a time, in the order asked.
144
- #serial<T>(work: () => Promise<T>): Promise<T> {
145
- const done = this.#turn.then(work, work);
146
- this.#turn = done.catch(() => undefined);
147
- return done;
148
- }
149
-
150
- async #commit(dna: ObjectStore, paths: ReadonlyMap<string, string>, message: string): Promise<string> {
151
- const root = paths.size === 0 ? (await dna.put([tree([])]))[0]! : await writeTree(dna, paths);
152
- const who = this.#signature();
153
- return writeCommit(dna, { tree: root, parents: this.#live ? [this.#live] : [], author: who, committer: who, message: `${message}\n` });
154
- }
155
-
156
- // Each module file of a commit, in the tree's order, its source loaded.
157
- async #checkout(commit: string, dna: ObjectStore = this.#harbor.dna): Promise<{ name: string; blob: string; loaded: Module | Error }[]> {
158
- const out: { name: string; blob: string; loaded: Module | Error }[] = [];
159
- for (const [path, id] of await files(dna, commit)) {
160
- if (!path.startsWith(DIR) || !path.endsWith(SUFFIX) || path.slice(DIR.length).includes('/')) continue;
161
- const name = path.slice(DIR.length, -SUFFIX.length);
162
- let loaded: Module | Error;
163
- try {
164
- const o = await dna.get(id);
165
- if (!o) throw new Error(`blob ${id} is not kept`);
166
- loaded = await this.#harbor.terrain.loader.load(text(o.body), id);
167
- if (loaded.module !== name) throw new Error(`${path} declares module ${loaded.module}`);
168
- } catch (e) {
169
- loaded = e instanceof Error ? e : new Error(String(e));
170
- }
171
- out.push({ name, blob: id, loaded });
172
- }
173
- return out;
174
- }
175
-
176
- // `live` stood again, as a wake finds it: a genesis commit on empty
177
- // memory, and every module that loads and splits no kind with those
178
- // before it run; the rest stay out, each with its reason.
179
- async wake(): Promise<void> {
180
- if (!this.#live) {
181
- this.cells.live = await this.#commit(this.#harbor.dna, new Map(), 'genesis');
182
- await this.#harbor.keep();
183
- }
184
- const running = new Map<string, Running>();
185
- try {
186
- for (const { name, blob: id, loaded } of await this.#checkout(this.#live!)) {
187
- const refused = loaded instanceof Error ? loaded.message : this.#check([...[...running.values()].map((r) => r.module), loaded]);
188
- if (refused === null) running.set(name, { module: loaded as Module, blob: id });
189
- else this.#failed.set(name, { blob: id, reason: refused });
190
- }
191
- } catch (e) {
192
- this.#fault = failure(e);
193
- }
194
- this.#running = running;
195
- this.#registry = new Registry(this.#harbor.kit, [...running.values()].map((r) => r.module));
196
- }
197
-
198
- // `live` moved to a commit whose every module loads and runs with the
199
- // rest, or the reason it stays. A commit staged is written to the DNA
200
- // once it checks, before it runs and before `live` names it.
201
- async #move(commit: string, staged?: StagedObjects): Promise<string | null> {
202
- let checked: { name: string; blob: string; loaded: Module | Error }[];
203
- try {
204
- checked = await this.#checkout(commit, staged);
205
- } catch (e) {
206
- return failure(e);
207
- }
208
- const bad = checked.find((c) => c.loaded instanceof Error);
209
- if (bad) return `${bad.name}: ${(bad.loaded as Error).message}`;
210
- const modules = checked.map((c) => c.loaded as Module);
211
- const unfit = this.#check(modules);
212
- if (unfit !== null) return unfit;
213
- await staged?.flush();
214
- this.#registry = new Registry(this.#harbor.kit, modules);
215
- this.#running = new Map(checked.map((c) => [c.name, { module: c.loaded as Module, blob: c.blob }]));
216
- this.#failed = new Map();
217
- this.#fault = null;
218
- this.cells.live = commit;
219
- await this.#harbor.ran();
220
- return null;
221
- }
222
-
223
- async #paths(): Promise<Map<string, string>> {
224
- return this.#live ? files(this.#harbor.dna, this.#live) : new Map();
225
- }
226
-
227
- add(args: JsonObject): Promise<JsonObject> {
228
- return this.#serial(() => this.#add(args));
229
- }
230
-
231
- async #add(args: JsonObject): Promise<JsonObject> {
232
- if (!isText(args.source)) return { error: 'source is text' };
233
- if (args.name !== undefined && !isText(args.name)) return { error: 'name is text' };
234
- const staged = new StagedObjects(this.#harbor.dna);
235
- const [id] = await staged.put([blob(args.source)]);
236
- let loaded: Module;
237
- try {
238
- loaded = await this.#harbor.terrain.loader.load(args.source, id!);
239
- } catch (e) {
240
- return { error: failure(e) };
241
- }
242
- if (args.name !== undefined && args.name !== loaded.module) return { error: `the source is module ${loaded.module}, not ${args.name}` };
243
- const paths = await this.#paths();
244
- paths.set(pathOf(loaded.module), id!);
245
- const commit = await this.#commit(staged, paths, `add ${loaded.module} ${loaded.version}`);
246
- const refused = await this.#move(commit, staged);
247
- if (refused !== null) return { error: refused };
248
- return { added: loaded.module, version: loaded.version, live: commit };
249
- }
250
-
251
- remove(args: JsonObject): Promise<JsonObject> {
252
- return this.#serial(() => this.#remove(args));
253
- }
254
-
255
- async #remove(args: JsonObject): Promise<JsonObject> {
256
- const module = args.module;
257
- const paths = await this.#paths();
258
- if (!isText(module) || !paths.has(pathOf(module))) return { error: 'no such module' };
259
- if (this.#harbor.stands(this.#kindsOf(module))) return { error: 'a being stands on this module' };
260
- paths.delete(pathOf(module));
261
- const staged = new StagedObjects(this.#harbor.dna);
262
- const commit = await this.#commit(staged, paths, `remove ${module}`);
263
- const refused = await this.#move(commit, staged);
264
- if (refused !== null) return { error: refused };
265
- return { removed: module, live: commit };
266
- }
267
-
268
- // The kinds a module stands: the registry's, where it runs, and where it
269
- // does not, every kind a row keeps in its domain that nothing resolves.
270
- #kindsOf(module: string): string[] {
271
- if (this.#running.has(module)) return this.#registry.kindsOf(module);
272
- const domain = domainOf(module);
273
- return this.#harbor.kept().filter((kind) => kind.startsWith(domain) && this.#registry.classOf(kind) === undefined);
274
- }
275
-
276
- live(args: JsonObject): Promise<JsonObject> {
277
- if (args.commit === undefined) return Promise.resolve({ live: this.#live ?? null });
278
- return this.#serial(() => this.#goLive(args));
279
- }
280
-
281
- async #goLive(args: JsonObject): Promise<JsonObject> {
282
- const named = args.commit;
283
- const commit = isText(named) && Object.hasOwn(this.#refs, named) ? this.#refs[named]! : named;
284
- if (!isId(commit)) return { error: 'commit is a commit id or a fetched ref' };
285
- const refused = await this.#move(commit);
286
- return refused === null ? { live: commit } : { error: refused };
287
- }
288
-
289
- async log(args: JsonObject): Promise<JsonObject> {
290
- const from = args.commit ?? this.#live;
291
- if (!isId(from)) return { error: 'commit is a commit id' };
292
- const log: JsonObject[] = [];
293
- try {
294
- for (let at: string | undefined = from; at !== undefined; ) {
295
- const o = await this.#harbor.dna.get(at);
296
- if (!o) break;
297
- const c = readCommit(o);
298
- log.push({ commit: at, parents: [...c.parents], message: c.message.replace(/\n$/, ''), seconds: c.committer.seconds });
299
- at = c.parents[0];
300
- }
301
- } catch (e) {
302
- return { error: failure(e) };
303
- }
304
- return { log };
305
- }
306
-
307
- origin(args: JsonObject): JsonObject {
308
- const url = args.url;
309
- if (url === null) {
310
- delete this.cells.origin;
311
- return { origin: null };
312
- }
313
- if (!isText(url) || !/^https?:\/\/[^/\s]+/.test(url)) return { error: 'url is an http or https URL, or null' };
314
- this.cells.origin = url;
315
- return { origin: url };
316
- }
317
-
318
- // Read-only on the remote: its refs, and a pack of what they reach that
319
- // is not kept here, each object kept. The commits `live` and the refs
320
- // reach are its haves, so the pack carries only what is new.
321
- fetch(): Promise<JsonObject> {
322
- return this.#serial(() => this.#fetch());
323
- }
324
-
325
- async #fetch(): Promise<JsonObject> {
326
- const url = this.cells.origin;
327
- if (!isText(url)) return { error: 'no origin is set' };
328
- try {
329
- const refs = await listRefs(url);
330
- const held = (id: string): ReturnType<ObjectStore['get']> => this.#harbor.dna.get(id);
331
- const objects = await fetchPack(url, Object.values(refs), held, await havesFrom(this.#roots(), held));
332
- await this.#harbor.dna.put([...objects.values()]);
333
- this.cells.refs = refs;
334
- return { refs, objects: objects.size };
335
- } catch (e) {
336
- return { error: failure(e) };
337
- }
338
- }
339
-
340
- // What the DNA keeps history from: `live` and every fetched ref.
341
- #roots(): string[] {
342
- return [...new Set([...(this.#live ? [this.#live] : []), ...Object.values(this.#refs)])];
343
- }
344
-
345
- // What `live` and every fetched ref reach stays, and the rest of the
346
- // DNA is forgotten. Her cells are kept first, so she collects against
347
- // what a restart stands; the whole reachable set is known before any
348
- // object goes, and an object missing from it stops the collection.
349
- gc(): Promise<JsonObject> {
350
- return this.#serial(async (): Promise<JsonObject> => {
351
- if (!(await this.#harbor.keep())) throw new Error('her cells were not kept');
352
- const dna = this.#harbor.dna;
353
- const keep = new Set<string>();
354
- for (const root of this.#roots()) {
355
- // An annotated tag is kept, and the commit it names walked; a
356
- // missing object throws here, before anything is forgotten.
357
- let at = root;
358
- for (let o = await dna.get(at); o?.type === 'tag'; o = await dna.get(at)) {
359
- keep.add(at);
360
- at = /^object ([0-9a-f]{40})$/m.exec(text(o.body))?.[1] ?? '';
361
- }
362
- for (const id of await reachable(dna, at)) keep.add(id);
363
- }
364
- return { collected: await dna.collect(keep), kept: keep.size };
365
- });
366
- }
367
-
368
- // Each module file `live` holds, by its blob's id, with its source: what
369
- // an edge's next child carries.
370
- async sources(): Promise<JsonObject> {
371
- const sources: JsonObject[] = [];
372
- for (const [path, id] of await this.#paths()) {
373
- if (!path.startsWith(DIR) || !path.endsWith(SUFFIX)) continue;
374
- const o = await this.#harbor.dna.get(id);
375
- if (o) sources.push({ blob: id, source: text(o.body) });
376
- }
377
- return { live: this.#live ?? null, sources };
378
- }
379
-
380
- modules(): JsonObject {
381
- const modules: JsonObject = {};
382
- for (const [name, r] of this.#running) modules[name] = { running: r.module.version, blob: r.blob };
383
- for (const [name, f] of this.#failed) modules[name] = { running: null, blob: f.blob, failed: f.reason };
384
- return { live: this.#live ?? null, modules, ...(this.#fault === null ? {} : { failed: this.#fault }) };
385
- }
386
- }
@@ -1,116 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // The DNA's objects, kept in the root memory under the catalogue's own
3
- // places and sealed under the package as every row is, so the terrain
4
- // reads no code and no object's id.
5
- //
6
- // place the hex of `catalogue`, then the first two digits of the
7
- // entry's name, git's fan-out
8
- // entry 16 bytes under ["dna", object id], as hex
9
- // bytes nonce (12) || AES-256-GCM( the object deflated as git keeps
10
- // it loose ), under 32 bytes of ["seal", "dna"], the entry's
11
- // name as additional data
12
- //
13
- // An object read back is checked against its id, so a store that hands
14
- // back other bytes hands back nothing.
15
- import { concat, decrypt, encrypt, hex, utf8 } from '../crypto/index.ts';
16
- import { deflated, idOf, inflated, type GitObject, type ObjectStore } from '../git/index.ts';
17
- import type { Memory } from '../contract/index.ts';
18
- import type { Package } from './package.ts';
19
-
20
- const NONCE = 12;
21
- const FAN = 2;
22
-
23
- export class Dna implements ObjectStore {
24
- // The places under this prefix are the catalogue's, never a ward's: a
25
- // ward's place is 32 digits, and a memory faculty's is its key's hex and
26
- // 32 more, never fewer than 34.
27
- static readonly prefix = hex(utf8('catalogue'));
28
- readonly #memory: Memory;
29
- readonly #pack: Package;
30
- readonly #held = new Map<string, GitObject>();
31
- #seal: Promise<Uint8Array> | undefined;
32
-
33
- constructor(memory: Memory, pack: Package) {
34
- this.#memory = memory;
35
- this.#pack = pack;
36
- }
37
-
38
- static occupies(place: string): boolean {
39
- return place.length === Dna.prefix.length + FAN && place.startsWith(Dna.prefix);
40
- }
41
-
42
- #key(): Promise<Uint8Array> {
43
- return (this.#seal ??= this.#pack.derive(['seal', 'dna'], 32));
44
- }
45
-
46
- async #entry(id: string): Promise<{ place: string; name: string }> {
47
- const name = hex(await this.#pack.derive(['dna', id], 16));
48
- return { place: Dna.prefix + name.slice(0, FAN), name };
49
- }
50
-
51
- async get(id: string): Promise<GitObject | null> {
52
- const held = this.#held.get(id);
53
- if (held) return held;
54
- const { place, name } = await this.#entry(id);
55
- const bytes = (await this.#memory.read(place)).get(name);
56
- if (!bytes || bytes.length <= NONCE) return null;
57
- const open = await decrypt(await this.#key(), bytes.subarray(0, NONCE), utf8(name), bytes.subarray(NONCE));
58
- if (open === null) return null;
59
- const o = await inflated(open);
60
- if ((await idOf(o)) !== id) return null;
61
- this.#held.set(id, o);
62
- return o;
63
- }
64
-
65
- // Every object sealed and written, one keep for each place.
66
- async put(objects: readonly GitObject[]): Promise<string[]> {
67
- const ids: string[] = [];
68
- const places = new Map<string, Map<string, Uint8Array>>();
69
- const kept = new Map<string, GitObject>();
70
- for (const o of objects) {
71
- const id = await idOf(o);
72
- ids.push(id);
73
- if (this.#held.has(id) || kept.has(id)) continue;
74
- const { place, name } = await this.#entry(id);
75
- const nonce = this.#pack.entropy.draw(NONCE);
76
- const sealed = concat(nonce, await encrypt(await this.#key(), nonce, utf8(name), await deflated(o)));
77
- if (!places.has(place)) places.set(place, new Map());
78
- places.get(place)!.set(name, sealed);
79
- kept.set(id, o);
80
- }
81
- for (const [place, entries] of places) await this.#memory.write(place, entries);
82
- for (const [id, o] of kept) this.#held.set(id, o);
83
- return ids;
84
- }
85
-
86
- async #places(): Promise<string[]> {
87
- return (await this.#memory.places()).filter((place) => Dna.occupies(place));
88
- }
89
-
90
- // How many objects are kept.
91
- async count(): Promise<number> {
92
- let n = 0;
93
- for (const place of await this.#places()) n += (await this.#memory.read(place)).size;
94
- return n;
95
- }
96
-
97
- // Every object but those `keep` names forgotten, and how many were. The
98
- // names kept are drawn before any entry is touched, and a place is
99
- // written with only its forgotten entries, so a cut anywhere loses
100
- // nothing `keep` names.
101
- async collect(keep: Iterable<string>): Promise<number> {
102
- const ids = new Set(keep);
103
- const names = new Set<string>();
104
- for (const id of ids) names.add((await this.#entry(id)).name);
105
- let forgotten = 0;
106
- for (const place of await this.#places()) {
107
- const gone = new Map<string, null>();
108
- for (const name of (await this.#memory.read(place)).keys()) if (!names.has(name)) gone.set(name, null);
109
- if (gone.size === 0) continue;
110
- await this.#memory.write(place, gone);
111
- forgotten += gone.size;
112
- }
113
- for (const id of [...this.#held.keys()]) if (!ids.has(id)) this.#held.delete(id);
114
- return forgotten;
115
- }
116
- }