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
package/README.md CHANGED
@@ -1,449 +1,122 @@
1
1
  # nervur
2
2
 
3
- Nervur's kit of [Quo](https://quo.systems). Quo is a protocol: an object
4
- asks another object and gets an answer, without knowing where it is. This
5
- package is one implementation of it, and the two names never stand for
6
- the same thing. Where they disagree, Quo's spec wins.
7
-
8
- You write classes, beings and faculties, and nothing else. A harbor
9
- unpacks a whole world from them.
10
-
11
- ## Install
12
-
13
- ```sh
14
- npm install nervur
15
- ```
16
-
17
- Node 22.18 or later. The main entry imports no platform, so it runs in a
18
- browser, Deno, Bun and workerd as well. `nervur/folder` keeps a harbor on
19
- a disk and needs Node's file system.
20
-
21
- ## A harbor where you run
22
-
23
- ```js
24
- import { readFile } from 'node:fs/promises';
25
- import { Harbor } from 'nervur';
26
-
27
- const harbor = await Harbor.open();
28
- await harbor.ask({ method: 'stand' });
29
- const source = await readFile('./greetings.js', 'utf8');
30
- await harbor.ask({ method: 'ask', args: { being: 'catalogue', method: 'add', args: { source } } });
31
- ```
32
-
33
- A harbor is asked and nothing else. `harbor.ask` takes one root request,
34
- `{ ward?, method?, args? }`, asks the box ward, or the hosted ward named,
35
- as its root, and answers one plain JSON value. `arrive`, `holds` and
36
- `close` are the rest of what a program holds of a harbor.
37
-
38
- With no terrain, the harbor picks its ground's bodies itself. In Node it
39
- keeps itself in a folder, `where` if you name one, else `$NERVUR_DIR`,
40
- else `~/.nervur`, speaks TCP and the web where you open them,
41
- and serves its root line, so the `nervur` command below asks it while it
42
- stands. A folder opens in one run at a time. Bundled for a browser, in a
43
- page or a worker, it keeps itself in the IndexedDB database `where`
44
- names, else `nervur`, its seed sealed under a key the browser never hands
45
- out, speaks the web where you open it, and opens in one run at a time.
46
- On Cloudflare Workers it is one Durable Object of many a worker carries,
47
- running in a child worker the object loads for the commit `live` names,
48
- answering Quo at `/<name>/quo` on whatever host reaches it, and asking
49
- over TCP and the web. Anywhere else it lives as long as its process and
50
- speaks the web where you open it. Hand in a terrain, as below, and that
51
- one is used.
52
-
53
- Nothing enters a harbor unasked. A new harbor holds its catalogue alone,
54
- and a carrier stands only once the root opens it:
55
-
56
- ```js
57
- await harbor.ask({ method: 'open', args: { key: 'web', class: 'org.nervur.web' } });
58
- ```
59
-
60
- ## A harbor on the edge
61
-
62
- An edge harbor is born on your machine and carried there, so you pilot it
63
- from your own harbor, as you pilot one on a server, and you move its code
64
- the same way, with no deploy. One worker carries as many harbors as you
65
- pack into it, each a Durable Object by its name, answering at
66
- `/<name>/quo`. The worker is a shell: it keeps each harbor's storage and
67
- its web door, and runs the harbor, the kit and the modules its `live`
68
- commit holds, in a child worker Cloudflare's Worker Loader makes of them.
69
- The worker is a folder of its own, an ES module project (`"type":
70
- "module"` in its `package.json`), holding the worker and its
71
- `wrangler.toml`:
72
-
73
- ```js
74
- // worker.js
75
- import { harborShell, harborWorker } from 'nervur/edge';
76
- import kit from 'nervur/edge/kit';
77
- import pack from './pack.edge.json';
78
-
79
- export const Harbor = harborShell({ kit, pack });
80
- export default harborWorker();
81
- ```
82
-
83
- ```toml
84
- # wrangler.toml
85
- name = "harbor"
86
- main = "worker.js"
87
- compatibility_date = "2026-09-01"
88
-
89
- [[durable_objects.bindings]]
90
- name = "HARBOR"
91
- class_name = "Harbor"
92
-
93
- [[migrations]]
94
- tag = "v1"
95
- new_sqlite_classes = ["Harbor"]
96
-
97
- [[worker_loaders]]
98
- binding = "LOADER"
99
- ```
100
-
101
- The Worker Loader is in beta, and on Cloudflare it needs the Workers Paid
102
- plan. `wrangler dev` runs it on your machine at no cost.
103
-
104
- Make the harbor and set it up with the command, from that folder, naming
105
- where the edge will reach it:
106
-
107
- ```sh
108
- nervur init --dir ./harbor
109
- nervur module add ./greetings.js --dir ./harbor
110
- nervur reach http://127.0.0.1:8787/main/quo --dir ./harbor
111
- nervur own me --dir ./harbor
112
- ```
113
-
114
- `own` prints the owner invitation, which never leaves your machine. Run
115
- it on this machine first:
116
-
117
- ```sh
118
- nervur edge dev ./pack.edge.json main --dir ./harbor
119
- ```
120
-
121
- `edge dev` packs the harbor as `main` into `pack.edge.json`, beside any
122
- harbor packed there before, and runs your `wrangler dev`, keeping the
123
- objects' storage and a secret of its own in `.nervur-edge`, so the
124
- harbor stands again each time you run it. The harbor's code travels in
125
- its package, as its DNA. The first time its object starts, the harbor
126
- lands in its storage; after that the storage is the harbor, and a new
127
- deploy leaves it be. Then, from your own harbor:
128
-
129
- ```sh
130
- nervur pilot edge '<the owner invitation>' --dir ./mine
131
- nervur host shop --via edge --dir ./mine
132
- nervur module add ./greetings.js --via edge --dir ./mine
133
- ```
134
-
135
- A module added, or `live` moved back, runs on the edge at once: the
136
- worker loads the next child for the commit `live` names, with no deploy.
137
- A module that does not load there is refused with its reason, and `live`
138
- stays where it was.
139
-
140
- For Cloudflare, keep one secret for the worker, `wrangler secret put
141
- NERVUR_SECRET`, and hold the same one as `NERVUR_SECRET` in your shell.
142
- Name each harbor's address with `reach`, pack each with
143
- `nervur edge pack ./pack.edge.json <name> --dir <its folder>`, and
144
- `wrangler deploy`. A pack holds every seed sealed under that secret, so
145
- it ships in the bundle and opens nowhere else, and a new harbor is a new
146
- deploy, never a new secret. `pilot` opens the web carrier where the
147
- invitation names a web address. A name the pack does not hold answers
148
- 404, so a stranger's request mints nothing.
149
-
150
- ## A world in one process
151
-
152
- A module is one file of JavaScript that imports nothing but `nervur`:
153
-
154
- ```js
155
- // greetings.js
156
- import { Being, Faculty } from 'nervur';
157
-
158
- // Its name, as a kind is named, and its version.
159
- export const module = 'org.example.greetings';
160
- export const version = '1.0.0';
161
-
162
- // A contract, and a faculty that fulfils it. Every class names its kind.
163
- class Clock extends Faculty {
164
- static kind = 'org.example.clock';
165
- }
166
- class SystemTime extends Clock {
167
- static kind = 'org.example.system-time';
168
- static asks = { now: {} };
169
- now() {
170
- return { now: Date.now() };
171
- }
172
- }
173
-
174
- // A being, who lends a clock by its contract.
175
- class Greeter extends Being {
176
- static kind = 'org.example.greeter';
177
- static asks = { hello: {} };
178
- async hello(args, asker) {
179
- if (!this.stance.standings.get('clock')) await this.stance.lend(Clock, 'clock');
180
- const time = await this.stance.standings.get('clock')?.ask('now');
181
- return { hello: asker.id ?? 'stranger', time };
3
+ `nervur` is a library for writing beings and opening the house that holds
4
+ them. It is the first kit of [Quo](https://quo.systems), a protocol where
5
+ a door is one function: bytes in, bytes or nothing out.
6
+
7
+ This version is a prerelease, and the API moves until 1.0.0. Install it
8
+ with `npm i nervur@next`. It runs on Node 22.18 or later.
9
+ [AUTHORING.md](AUTHORING.md) teaches beings, faculties and grounds.
10
+ [KIT-SPEC.md](KIT-SPEC.md) answers every choice Quo leaves to a kit.
11
+
12
+ ## Words
13
+
14
+ A **being** is an instance of a class you write. She keeps **cells**,
15
+ which are JSON values, and answers **asks**, which are the methods others
16
+ may call. The **house** holds beings, keeps their cells, and seals every
17
+ ask that crosses its door. A **ground** is the process houses run in. It
18
+ hands each house a seed, somewhere to keep rows, its classes, a way to
19
+ carry bytes, and the **faculties** its beings may call.
20
+
21
+ ## A being
22
+
23
+ Every ask declares its arguments and its result, and may carry examples.
24
+ The house refuses arguments that do not match.
25
+
26
+ ```ts
27
+ // greeter.ts
28
+ import { Being, s, type Args } from 'nervur/being';
29
+
30
+ export class Greeter extends Being.of({
31
+ kind: 'org.example.greeter',
32
+ description: 'Greets whoever asks, and counts them.',
33
+ cells: { greeted: 0 },
34
+ asks: {
35
+ hello: {
36
+ args: s.object({ name: s.string() }),
37
+ result: s.string(),
38
+ examples: [{ cells: { greeted: 2 }, args: { name: 'Ada' }, gives: { result: 'Hello, Ada. You are number 3.' } }],
39
+ },
40
+ },
41
+ }) {
42
+ hello({ name }: Args<Greeter, 'hello'>) {
43
+ this.cells.greeted += 1;
44
+ return `Hello, ${name}. You are number ${this.cells.greeted}.`;
182
45
  }
183
46
  }
184
-
185
- export const classes = [SystemTime, Greeter];
186
47
  ```
187
48
 
188
- A harbor's catalogue takes its source, commits it, and runs it:
189
-
190
- ```js
191
- import { readFile } from 'node:fs/promises';
192
- import { DEFAULTS, World } from 'nervur';
193
-
194
- const world = new World(DEFAULTS);
195
- const harbor = await world.harbor('home');
196
- const source = await readFile('./greetings.js', 'utf8');
197
- await harbor.ask({ method: 'ask', args: { being: 'catalogue', method: 'add', args: { source } } });
198
- await harbor.ask({ method: 'open', args: { key: 'clock', class: 'org.example.system-time' } });
199
- await harbor.ask({ method: 'host', args: { ward: 'alice' } });
200
- await harbor.ask({ ward: 'alice', method: 'boot', args: { key: 'greeter', class: 'org.example.greeter' } });
49
+ ## A test
50
+
51
+ The bench opens two houses in one process, so every ask crosses a door
52
+ as it would in production. `Bench.check` runs every example twice and
53
+ describes every state to every role.
54
+
55
+ ```ts
56
+ // greeter.test.ts
57
+ import assert from 'node:assert/strict';
58
+ import { test } from 'node:test';
59
+ import { Bench } from 'nervur/bench';
60
+ import { Greeter } from './greeter.ts';
61
+
62
+ test('Greeter keeps her examples and her table', async () => {
63
+ await Bench.check(Greeter);
64
+ });
65
+
66
+ test('Greeter counts whoever she greets', async () => {
67
+ const bench = await Bench.open({ classes: [Greeter] });
68
+ const greeter = await bench.place(Greeter);
69
+ assert.deepEqual(await greeter.ask('hello', { name: 'Ada' }), { result: 'Hello, Ada. You are number 1.' });
70
+ assert.deepEqual(await greeter.cells(), { greeted: 1 });
71
+ });
201
72
  ```
202
73
 
203
- A second harbor in the same world takes an invitation on the greeter and
204
- asks it through the world, sealed as Quo's bytes. `world.restart('home')`
205
- opens the harbor again from what its memory kept.
206
-
207
- ## Kinds
208
-
209
- A row keeps the kind of the class a being is born of, and a being lends
210
- by a contract's kind. A kind is declared on the class, because a bundler
211
- renames classes. It is a domain you own, reversed, then a name, as Apple
212
- and Matrix name things: `com.acme.shop`. Every segment is lowercase
213
- letters, digits and `-`, and there are three at least. Each class
214
- declares its own: a subclass that stands, and every contract between a
215
- faculty and `Faculty`. `org.nervur.` is the kit's, and `org.example.` is
216
- for examples like the one above. A module's classes stand under its own
217
- domain: `com.acme.shop` stands `com.acme.*` kinds. A harbor refuses a
218
- module in which one kind names two classes or two contracts, or names a
219
- class and a contract.
220
-
221
- ## The DNA
222
-
223
- Your classes come in modules, each one file exporting `module`, `version`
224
- and `classes`, a module named as a kind is. A harbor's catalogue keeps
225
- its code as a git repository, its DNA, from its first moment: a commit
226
- holds `modules/<module>.js` for every module the harbor runs, and `live`
227
- names the commit that stands. Her asks, the root's and an owner's:
228
-
229
- - `add { source, name? }` commits a module's source on `live` and moves
230
- `live` to it; the same module again takes its new version.
231
- - `remove { module }` commits its file away, refused while a being or a
232
- ward stands on its kinds.
233
- - `live { commit? }` moves `live` to a commit or a fetched ref, or, with
234
- none, names the commit that stands. Moving `live` back is a rollback.
235
- - `log` walks back from `live`. `modules` shows what `live` runs, and why
236
- a module does not.
237
- - `origin { url }` names a git repository over HTTP, and `fetch` reads
238
- every ref it has and all they reach into the harbor, touching nothing
239
- there.
240
-
241
- Moving `live` runs the commit's modules together, or refuses them with
242
- the reason and leaves `live` where it was. Once they run, every being a
243
- new class resolves is born again of it, on the cells she keeps. A
244
- restart stands `live` from what the harbor keeps, with no network. The
245
- objects live in the harbor's memory, sealed as everything else is, so a
246
- harbor carried to another ground carries its DNA. Real `git` reads a
247
- harbor's objects, and a harbor reads what `git` serves.
74
+ ## A ground
248
75
 
249
- ## The onion
76
+ A ground is the process houses run in, and you write none. `nervur up`
77
+ runs one on a folder. Each house's code is a folder of its own, whose
78
+ index names its steward. Here the greeter is the steward.
250
79
 
251
- A harbor is one package. Only the seed and the terrain's bodies, its
252
- loader among them, stand outside it. It stands in three levels, and each
253
- level stands the next and leaves it alone.
254
-
255
- 1. **The boot**, the harbor's own, from the library's core alone. The
256
- terrain gives the seed, which opens its memory; the terrain keeps that
257
- memory as sealed bytes and reads none of it. The box ward unpacks, the
258
- catalogue stands and runs every module `live` holds, every registry the
259
- catalogue resolves stands, and then the dock, of her class. The door is
260
- hers from here, and `Harbor.open()` returns. It is one call, and no ask
261
- makes it.
262
- 2. **The dock's**, on her `stand` ask. She stands every other faculty,
263
- registries first, then memory faculties, then the rest; hands her
264
- routes to the carrier; and stands every ward she hosts, under the seed
265
- she keeps for it.
266
- 3. **Each ward's beings**, stood by nothing. A being's cells, occupants
267
- and standings are her ward's rows, so she is born from her row when an
268
- ask reaches her, once for the asks in flight on her, and dropped after.
269
- A harbor holds in memory its faculties, its wards and the beings
270
- answering now.
271
-
272
- After the boot a harbor takes asks alone. Whoever holds it asks `stand`:
273
-
274
- ```js
275
- const harbor = await Harbor.open();
276
- await harbor.ask({ method: 'stand' });
80
+ ```ts
81
+ // house/index.ts
82
+ export { Greeter as steward } from '../greeter.ts';
277
83
  ```
278
84
 
279
- `stand` answers what stood, or silence where everything already stands.
280
- The command asks it of every harbor it opens.
281
-
282
- Cells decide what stands. The modules only resolve a kind a row keeps.
283
- Opening a harbor on empty memory is its genesis: the harbor writes the
284
- catalogue and the default dock, and the root's asks write the rest: `add`
285
- on the catalogue, `open`, `host`, `route`, and `boot` on a ward.
286
- `host { ward, seed? }` stands a ward under a seed you name, or a drawn
287
- one.
288
-
289
- A ward is a being too, and her row keeps her class's kind. `Ward` and
290
- `Dock` are contracts, and `DefaultWard` and `DefaultDock` the library's
291
- defaults of them. A class of yours extending either, in a module the
292
- catalogue runs, is a ward of your own: `host { ward, class }` stands a
293
- hosted ward of it, and `become { class }` on any ward, the box ward's
294
- dock among them, has her born again of it on the same cells and
295
- relations. A dock of yours stands on every open, since she stands once
296
- the catalogue runs.
297
-
298
- Every class comes from a registry. The catalogue is the library's, and a
299
- class of yours extending `RegistryFaculty` is another: open it as any
300
- faculty, and name it where a class is named. `open { key, class,
301
- registry }` stands a faculty through it, `host { ward, registry }` stands
302
- a ward and every class of it through it, and `become { class, registry }`
303
- stands the dock through it, where the catalogue stands that registry. A
304
- registry may stand through another.
305
-
306
- A ward's place is kept by the root memory unless you name a memory
307
- faculty. `open { key: 'vault', class: 'org.nervur.ground-memory' }` opens
308
- the memory faculty every ground ships, and `host { ward, memory: 'vault' }`
309
- keeps the ward there. A class of yours extending `MemoryFaculty` keeps a
310
- ward in a bucket or a database the same way, and `move { ward, memory }`
311
- carries a ward between keepers whole.
312
-
313
- ## What it holds
314
-
315
- - **Being, Faculty, Ward, Dock.** What you extend, each a contract.
316
- A faculty's contract is its class and every class between it and
317
- `Faculty`. `DefaultWard` and `DefaultDock` are the kit's ward and dock.
318
- - **Entropy, Clock, Custody, Memory, Carrier, Loader.** The contracts a
319
- terrain fulfils. Each has one suite, and every body that fulfils it
320
- passes it. `nervur/proof` hands you those suites and the unpacking
321
- law's as scenes, a title and a function each, so a body of your own,
322
- a memory in a cloud or a secret of your platform's, runs them under
323
- your own runner: `for (const [title, scene] of memoryScenes('Mine',
324
- make, expect)) test(title, scene)`. `@nervur-org/s3` is one such body.
325
- - **Harbor, Terrain, Catalogue, Registry.** The onion.
326
- - **World, PointerTerrain** and the pointer bodies. A whole world with
327
- this package alone.
328
- - **SourceLoader, BundleLoader.** A module's source run by the engine's
329
- own import, its `nervur` linked to the kit running, and the modules a
330
- bundle carries, found by their git blob, for a service worker, which
331
- imports nothing once it runs.
332
- - **addGround, grounds**: the grounds `Harbor.open()` tries, and a way to
333
- add your own.
334
- - **NodeTerrain**, from `nervur/node`: the Node ground's terrain, for a
335
- folder you name in code.
336
- - **BrowserTerrain, IdbMemory, IdbCustody**, from `nervur/browser`: the
337
- browser ground's terrain and bodies. `serveWorker(Harbor.open())` at
338
- the top of a shared or service worker holds one harbor for every tab,
339
- each tab asks it with `rootOf(worker)`, and a push the service worker
340
- hears is the dock's `heard`, told to every carrier.
341
- - **harborShell, harborWorker, EdgeMemory, EdgeCustody, EdgeLoader**,
342
- from `nervur/edge`, and the kit as one module's text, from
343
- `nervur/edge/kit`: the edge's shell and the bodies its children stand
344
- on.
345
- - **FolderMemory, FolderCustody**, from `nervur/folder`.
346
- - **TcpCarrier, TcpListener, NodeSockets**, from `nervur/tcp`: Quo over
347
- TCP. Route a ward pk to its `tcp://host:port` addresses on the carrier,
348
- hand the listener your harbor, and harbors in two processes, or a
349
- harbor and another kit, speak. `TcpFaculty` is the same carrier as a
350
- faculty of a harbor, on the sockets its terrain hands it:
351
- `NodeSockets` on Node, a worker's own on the edge.
352
- - **WebDialer, WebFaculty**: Quo over the web, a post to `https://` or a
353
- held line to `wss://`, in any engine with `fetch` and WebSocket.
354
- `webServe`, from `nervur/http`, is the listener a Node terrain hands
355
- the web carrier. `answerPost(harbor, listen, request)` answers one post
356
- and nothing more, for a function that opens a harbor per request and
357
- closes it.
358
- - **DEFAULTS**: the one list of beings and faculties every ground runs
359
- where you write none, handed to a terrain as `defaults`.
85
+ Run the ground in the folder, and leave it running.
360
86
 
361
- Quo crosses two carriers, TCP and the web, and no third. MCP, an HTTP API
362
- and every other outside protocol are gateway faculties: classes that
363
- serve their clients, a UI in a browser, an MCP client, a caller holding
364
- a bearer token, on one side, and stand as an ordinary being on the
365
- other, offering standings, holding occupants and speaking Quo inbound
366
- and outbound. They and every screen
367
- are `@nervur-org/*`'s.
368
-
369
- ## The command
370
-
371
- `nervur` stands a harbor on this machine: its seed and sealed memory in a
372
- folder, Quo over TCP as its carrier. A module is a file that exports
373
- `module`, `version` and `classes`.
374
-
375
- ```sh
376
- nervur init --dir ./harbor
377
- nervur module add ./greetings.js --dir ./harbor
378
- nervur serve --dir ./harbor --port 7000
379
- nervur reach tcp://harbor.example:7000 --dir ./harbor
380
- nervur open web org.nervur.web --dir ./harbor
381
- nervur ask web listen '{"port":8080,"path":"/quo"}' --dir ./harbor
382
- nervur host alice --dir ./harbor
383
- nervur boot --ward alice greeter org.example.greeter --dir ./harbor
384
- nervur ask --ward alice greeter hello --dir ./harbor
87
+ ```bash
88
+ npx nervur up .
385
89
  ```
386
90
 
387
- `reach` names where the harbor is reached, and every invitation it gives
388
- carries those addresses in `at`. With no `reach`, an invitation carries
389
- where the harbor listens, which serves a harbor callers reach directly;
390
- behind a router or a proxy, name the public address with `reach`. A
391
- harbor that takes such an invitation keeps them as that ward's route,
392
- so nobody routes it by hand. Where an invitation carries no `at`,
393
- `nervur route <ward pk> tcp://host:port` names the route, and a route
394
- named this way is trusted first.
395
-
396
- `init` makes the harbor, opens its TCP carrier unless you pass
397
- `--no-tcp`, and prints its pk and an owner invitation. `serve` listens for
398
- Quo on that carrier and for the root's asks on a local socket, open to
399
- you alone, and adds nothing to the harbor: one with no TCP carrier is not
400
- served. Every other command is one root ask, sent to the served
401
- harbor, or answered from the folder when none is served. Each prints one
402
- JSON line. `--dir` defaults to `$NERVUR_DIR`, then `~/.nervur`.
403
- `module add` reads the file and commits its text into the harbor's DNA,
404
- so the harbor holds its own code on any ground. Routes live in the
405
- harbor like everything else, so a restart finds both. `nervur modules`
406
- shows what runs, `nervur module remove <module>` stops one, `nervur log`
407
- walks the commits, `nervur live <commit>` moves `live`, and `nervur
408
- origin <url>` with `nervur fetch` reads a git repository into the
409
- harbor.
91
+ In a second shell, add the house once. The ground keeps it in its record,
92
+ and opens it again at every start.
410
93
 
411
- A harbor elsewhere is piloted with the owner invitation its `init`
412
- printed, from a harbor of your own:
413
-
414
- ```sh
415
- nervur pilot far '<owner invitation>' --dir ./mine
416
- nervur host shop --via far --dir ./mine
94
+ ```bash
95
+ npx nervur houses add name=main memory='{"body":"ledger"}' classes='{"body":"folder","at":"house"}'
417
96
  ```
418
97
 
419
- `pilot` is your dock's `hold`: it keeps the invitation under the name
420
- `far` as an ordinary Quo relation, kept in your harbor's memory, and
421
- reaches the far harbor where its invitation's `at` says; where it says
422
- nothing, name the address after the invitation. With
423
- `--via far`, any command is asked of the far harbor as its owner, sealed
424
- over TCP, except `own` and `disown`, which stay the far root's. Every ward
425
- holds far beings this way, a ward or any other being whose invitation
426
- carries the notes `{ owner: true }`, each under a name, asked with
427
- `pilot { name, method, args }` and let go with `drop { name }`.
428
-
429
- `harbor.ask(request)` is the same request in code, for any other front:
430
- `{ ward?, method?, args? }` in, one JSON answer out.
98
+ Then ask the steward through the ground's hand.
431
99
 
432
- ## Moving a harbor
100
+ ```bash
101
+ npx nervur ask main hello name=Ada
102
+ ```
433
103
 
434
- A harbor moves to another machine by its bytes, with no harbor open:
104
+ Each ask greets Ada once more, since the count lands in the house's
105
+ ledger before the answer, and it outlives a restart. The ground keeps
106
+ the house's seed, its ledger and its record in `state/`, readable by
107
+ you alone. Keep that folder secret: a house opens on no other seed.
108
+ `npx nervur help` lists everything the ground offers.
435
109
 
436
- ```sh
437
- nervur export --with-seed --dir ./harbor > harbor.json
438
- nervur import harbor.json --dir ./elsewhere
439
- ```
110
+ ## Entries
440
111
 
441
- `export` reads the folder's sealed places, and carries the seed only
442
- where you ask for it. `import` writes them into a folder that holds none.
443
- A package with no seed lands where custody already holds the one it was
444
- sealed under. In code, `copyPackage(from, to)` carries every place of one
445
- memory into another.
112
+ | Entry | For |
113
+ | --- | --- |
114
+ | `nervur/being` | writing a being: `Being`, `s`, `need`, `Args`, `Result` |
115
+ | `nervur` | any engine: `Ground`, `House` and the bodies they take |
116
+ | `nervur/node` | a ground on Node: `NodeGround`, the `nervur` command, and its bodies |
117
+ | `nervur/bench` | tests: `Bench`, `BenchGround`, `FakeNetwork` and the fakes of every body |
446
118
 
447
119
  ## License
448
120
 
449
- Apache-2.0.
121
+ Apache-2.0, © Bookarest Digital SRL. Quo is a separate work, under its
122
+ own license. See `NOTICE`.
@@ -0,0 +1,18 @@
1
+ import { BrowserGround, type BrowserGroundOptions } from '../browser/browser-ground.ts';
2
+ import { type NativeSecrets, type NativeStore } from './native.ts';
3
+ /** What the shell hands the ground: its secret store and its native store. */
4
+ export interface NativeShell {
5
+ readonly secrets: NativeSecrets;
6
+ readonly store: NativeStore;
7
+ }
8
+ export interface AppGroundOptions extends Omit<BrowserGroundOptions, 'platform'> {
9
+ readonly shell: NativeShell;
10
+ /** Loads a module of classes by URL, where the app's build hands its own. */
11
+ readonly load?: (href: string) => Promise<unknown>;
12
+ /** Where its classes stand; the web view's own origin where omitted. */
13
+ readonly origin?: string;
14
+ }
15
+ export declare const AppGround: Readonly<{
16
+ /** The app's ground: a BrowserGround whose custody and memory are the shell's own. */
17
+ open({ shell, load, origin, ...options }: AppGroundOptions): Promise<BrowserGround>;
18
+ }>;
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // The ground in a phone's app: a BrowserGround in the shell's web view,
3
+ // on the two bodies the shell hands in. Its seeds rest in the platform's
4
+ // Keychain or Keystore, and its memory in a native store the system never
5
+ // evicts. The code arrives signed in the app's bundle, and one web view
6
+ // runs, so the lock is taken at once. A wake by push is the app's own
7
+ // recipe's faculty, since the library ships no faculty.
8
+ import { BrowserGround } from '../browser/browser-ground.js';
9
+ import { NativeCustody, NativeMemory } from './native.js';
10
+ export const AppGround = Object.freeze({
11
+ /** The app's ground: a BrowserGround whose custody and memory are the shell's own. */
12
+ open({ shell, load, origin, ...options }) {
13
+ return BrowserGround.open({
14
+ ...options,
15
+ platform: {
16
+ custody: async () => new NativeCustody(shell.secrets),
17
+ memory: async (name) => new NativeMemory(shell.store, name),
18
+ // The system keeps an app's own store, so there is nothing to ask.
19
+ persist: async () => true,
20
+ ...(load === undefined ? {} : { load }),
21
+ ...(origin === undefined ? {} : { origin }),
22
+ },
23
+ });
24
+ },
25
+ });
@@ -0,0 +1,2 @@
1
+ export { AppGround, type AppGroundOptions, type NativeShell } from './app-ground.ts';
2
+ export { NativeCustody, NativeMemory, type NativeSecrets, type NativeStore } from './native.ts';
@@ -0,0 +1,5 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // `nervur/app`: the ground of a phone's app, a BrowserGround on the bodies
3
+ // its shell hands in, and the contracts a shell's native code fills.
4
+ export { AppGround } from './app-ground.js';
5
+ export { NativeCustody, NativeMemory } from './native.js';
@@ -0,0 +1,46 @@
1
+ import type { Keys, Memory, PlaceRead } from '../foundation.ts';
2
+ import type { Custody } from '../ground/ground.ts';
3
+ /** The platform's secret store: text by name, kept by the Keychain or the Keystore, on this device alone. */
4
+ export interface NativeSecrets {
5
+ get(name: string): Promise<string | null>;
6
+ set(name: string, value: string): Promise<void>;
7
+ }
8
+ /** A native store of text by key, which the operating system never evicts. */
9
+ export interface NativeStore {
10
+ get(key: string): Promise<string | null>;
11
+ /** Every key that begins with `prefix`. */
12
+ keys(prefix: string): Promise<readonly string[]>;
13
+ /**
14
+ * Lands every write together, where every key in `expect` still holds
15
+ * what it names, `null` for absent; otherwise lands nothing. A write of
16
+ * `null` removes its key. Answers whether it landed.
17
+ */
18
+ swap(writes: Readonly<Record<string, string | null>>, expect: Readonly<Record<string, string | null>>): Promise<boolean>;
19
+ }
20
+ /** One seed for each house in the platform's secret store, drawn on first use. */
21
+ export declare class NativeCustody implements Custody {
22
+ #private;
23
+ constructor(secrets: NativeSecrets);
24
+ keys({ house }: {
25
+ house: string;
26
+ }): Promise<Keys>;
27
+ }
28
+ /**
29
+ * Memory over a native store, one memory for each name. Each place is one
30
+ * key, its entries as hex beside its version. Versions come from one
31
+ * counter for the memory, so a place removed and written again never
32
+ * shows a version it showed before. A write reads every place it names
33
+ * and swaps them all against what it read.
34
+ */
35
+ export declare class NativeMemory implements Memory {
36
+ #private;
37
+ constructor(store: NativeStore, name: string);
38
+ read({ place }: {
39
+ place: string;
40
+ }): Promise<PlaceRead>;
41
+ list(): Promise<readonly string[]>;
42
+ write({ writes, expect, }: {
43
+ writes: Readonly<Record<string, Readonly<Record<string, Uint8Array | null>>>>;
44
+ expect: Readonly<Record<string, string | null>>;
45
+ }): Promise<Readonly<Record<string, string | null>> | null>;
46
+ }