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
@@ -1,7 +1,7 @@
1
- import { Custody, Memory, type Entropy, type Module } from '../contract/index.ts';
2
- import type { GroundProbe } from '../harbor/index.ts';
1
+ import { Custody, Memory, type Bundled, type Entropy } from '../contract/index.ts';
2
+ import type { Defaults, GroundProbe } from '../harbor/index.ts';
3
3
  import { PointerTerrain } from '../pointer/index.ts';
4
- export { ringAll, rootOf, serveWorker, type Reaching } from './worker.ts';
4
+ export { rootOf, serveWorker, type Reaching } from './worker.ts';
5
5
  export declare const BROWSER = "browser";
6
6
  export declare const BROWSER_HARBOR = "nervur";
7
7
  export declare class IdbMemory extends Memory {
@@ -23,12 +23,13 @@ export declare class IdbCustody extends Custody {
23
23
  }
24
24
  export type BrowserParts = {
25
25
  readonly where?: string;
26
- readonly modules?: readonly Module[];
26
+ readonly bundle?: readonly Bundled[];
27
+ readonly defaults: Defaults;
27
28
  };
28
29
  export declare class BrowserTerrain extends PointerTerrain {
29
30
  #private;
30
31
  readonly where: string;
31
- constructor(parts?: BrowserParts);
32
+ constructor(parts: BrowserParts);
32
33
  get foreground(): boolean;
33
34
  claim(): Promise<void>;
34
35
  release(): Promise<void>;
@@ -2,7 +2,8 @@
2
2
  // `nervur/browser`: the browser ground, in a page or a worker. A harbor
3
3
  // keeps its sealed memory and its seed in one IndexedDB database, named
4
4
  // by `where`, speaks the web, and holds its database to one run with a
5
- // Web Lock of the same name.
5
+ // Web Lock of the same name. It imports a module's source from a Blob
6
+ // URL, or, handed a bundle, runs the bundle alone.
6
7
  //
7
8
  // entries one sealed entry per key [place, name]
8
9
  // custody the seed, sealed under an AES-GCM key the engine never
@@ -11,9 +12,8 @@
11
12
  // A keep is one transaction, so it is whole or nothing by IndexedDB's own
12
13
  // rule.
13
14
  import { Custody, Memory } from '../contract/index.js';
14
- import { webFaculty, WEB_OPENING, webPush } from '../line/index.js';
15
- import { CryptoEntropy, HeldLoader, PointerTerrain } from '../pointer/index.js';
16
- export { ringAll, rootOf, serveWorker } from './worker.js';
15
+ import { BundleLoader, CryptoEntropy, PointerTerrain, SourceLoader } from '../pointer/index.js';
16
+ export { rootOf, serveWorker } from './worker.js';
17
17
  export const BROWSER = 'browser';
18
18
  // The database a harbor keeps itself in unless named.
19
19
  export const BROWSER_HARBOR = 'nervur';
@@ -144,16 +144,16 @@ export class IdbCustody extends Custody {
144
144
  return this.#db.close();
145
145
  }
146
146
  }
147
- // A harbor of the browser: its database, the web opened at genesis, Web
148
- // Push beside it, and one run to a database, held by a Web Lock where the
149
- // engine has them.
147
+ // A harbor of the browser: its database, and one run to a database, held
148
+ // by a Web Lock where the engine has them. It listens nowhere and has no
149
+ // sockets, so the web carrier dials from it and nothing else carries.
150
150
  export class BrowserTerrain extends PointerTerrain {
151
151
  where;
152
152
  #release;
153
- constructor(parts = {}) {
153
+ constructor(parts) {
154
154
  const where = parts.where ?? BROWSER_HARBOR;
155
155
  const entropy = new CryptoEntropy();
156
- super({ entropy, loader: new HeldLoader(parts.modules ?? []), custody: new IdbCustody(where, entropy), memory: new IdbMemory(where), faculties: [webFaculty(), webPush], opens: [WEB_OPENING] });
156
+ super({ entropy, loader: parts.bundle ? new BundleLoader(parts.bundle) : new SourceLoader(), custody: new IdbCustody(where, entropy), memory: new IdbMemory(where), defaults: parts.defaults });
157
157
  this.where = where;
158
158
  }
159
159
  // A shared or a service worker outlives any one tab, and a service
@@ -192,5 +192,5 @@ export class BrowserTerrain extends PointerTerrain {
192
192
  export const browserGround = {
193
193
  name: BROWSER,
194
194
  fits: () => typeof indexedDB !== 'undefined' && typeof crypto?.subtle !== 'undefined',
195
- terrain: ({ modules, where }) => new BrowserTerrain({ ...(where ? { where } : {}), ...(modules ? { modules } : {}) }),
195
+ terrain: ({ where, bundle }, defaults) => new BrowserTerrain({ ...(where ? { where } : {}), ...(bundle ? { bundle } : {}), defaults }),
196
196
  };
@@ -1,10 +1,9 @@
1
1
  import type { JsonObject } from '../being/index.ts';
2
- import { type Harbor } from '../harbor/index.ts';
2
+ import type { Harbor } from '../harbor/index.ts';
3
3
  type Scope = {
4
4
  addEventListener(type: string, listener: (event: never) => void): void;
5
5
  };
6
- export declare const ringAll: (harbor: Harbor) => Promise<JsonObject[]>;
7
- export declare const serveWorker: (harbor: Promise<Harbor>, scope?: Scope) => void;
6
+ export declare const serveWorker: (opening: Promise<Harbor>, scope?: Scope) => void;
8
7
  export type Reaching = {
9
8
  postMessage(message: unknown, transfer: Transferable[]): void;
10
9
  };
@@ -1,33 +1,30 @@
1
- import { RELAY_CLIENT, rootLine } from '../harbor/index.js';
2
1
  const answer = async (harbor, data, reply) => {
3
2
  if (!reply)
4
3
  return;
5
4
  let out;
6
5
  try {
7
- out = await rootLine(await harbor, data?.request);
6
+ out = await (await harbor).ask(data?.request);
8
7
  }
9
8
  catch {
10
9
  out = { error: 'the harbor threw' };
11
10
  }
12
11
  reply.postMessage(out);
13
12
  };
14
- // Every relay client of the harbor asked to collect what waits.
15
- export const ringAll = async (harbor) => {
16
- const keys = Object.entries(harbor.box.partition.beings)
17
- .filter(([, row]) => row.class === RELAY_CLIENT)
18
- .map(([key]) => key);
19
- return Promise.all(keys.map(async (being) => (await harbor.root('ask', { being, method: 'ring' }))));
20
- };
21
13
  // Called as the worker's script starts, so no tab's first message is
22
14
  // lost while the harbor opens.
23
- export const serveWorker = (harbor, scope = globalThis) => {
15
+ export const serveWorker = (opening, scope = globalThis) => {
16
+ // The worker holds the harbor, so it asks its `stand` before any tab's.
17
+ const harbor = opening.then(async (h) => {
18
+ await h.ask({ method: 'stand' });
19
+ return h;
20
+ });
24
21
  scope.addEventListener('connect', (event) => {
25
22
  const port = event.ports[0];
26
23
  port.onmessage = (message) => void answer(harbor, message.data, message.ports[0]);
27
24
  port.start();
28
25
  });
29
26
  scope.addEventListener('message', (event) => void answer(harbor, event.data, event.ports[0]));
30
- scope.addEventListener('push', (event) => event.waitUntil(harbor.then(ringAll)));
27
+ scope.addEventListener('push', (event) => event.waitUntil(harbor.then((h) => h.ask({ method: 'heard' }))));
31
28
  };
32
29
  // A tab's root line to the worker's harbor.
33
30
  export const rootOf = (worker) => (request) => new Promise((resolve) => {
@@ -1,13 +1,13 @@
1
1
  import type { JsonObject } from '../being/index.ts';
2
- import type { RootRequest } from '../harbor/index.ts';
2
+ import { type Defaults, type RootRequest } from '../harbor/index.ts';
3
3
  export declare const parse: (argv: string[]) => {
4
4
  command?: string;
5
5
  words: string[];
6
6
  flags: Record<string, string>;
7
7
  };
8
8
  export declare const requestOf: (command: string, words: string[], flags: Record<string, string>) => RootRequest;
9
- export declare const main: (argv: string[], env: Record<string, string | undefined>, print: (line: string) => void) => Promise<number>;
10
- export declare const pilotRequests: (name: string, invitation: JsonObject, at?: string, web?: boolean) => RootRequest[];
11
- export declare const via: (pilot: string, far: RootRequest) => RootRequest;
9
+ export declare const main: (argv: string[], env: Record<string, string | undefined>, print: (line: string) => void, defaults: Defaults) => Promise<number>;
10
+ export declare const pilotRequests: (name: string, invitation: JsonObject, at?: string, web?: RootRequest) => RootRequest[];
11
+ export declare const via: (name: string, far: RootRequest) => RootRequest;
12
12
  export declare const farAnswer: (local: JsonObject) => JsonObject;
13
13
  export declare const SERVING = -1;
@@ -2,16 +2,33 @@
2
2
  // `nervur`: a harbor on this machine. Each command is one root request, the
3
3
  // same the root line carries from any front, printed as one JSON line.
4
4
  //
5
- // nervur init [--dir D] the harbor made: its seed drawn,
6
- // its catalogue stood, and an owner
7
- // invitation for whoever made it
8
- // nervur serve [--dir D] [--host H] [--port P] the harbor served: Quo over TCP,
9
- // and the root line on its socket
10
- // nervur module add <file | package | id> a module the catalogue runs, kept
11
- // by the id it declares
12
- // nervur module remove <module> a module it runs no more
13
- // nervur modules what the catalogue runs
5
+ // nervur init [--dir D] [--no-tcp] the harbor made: its seed drawn,
6
+ // its catalogue stood, the tcp
7
+ // carrier opened unless --no-tcp,
8
+ // and an owner invitation for
9
+ // whoever made it
10
+ // nervur serve [--dir D] [--host H] [--port P] the harbor served: Quo over the
11
+ // tcp carrier it holds, and the
12
+ // root line on its socket
13
+ // nervur module add <file> the module's source committed on
14
+ // live, and live moved to it
15
+ // nervur module remove <module> its file committed away, and live
16
+ // moved
17
+ // nervur modules what live runs
18
+ // nervur live [commit | ref] live moved there, or the commit
19
+ // that stands
20
+ // nervur log the commits from live back
21
+ // nervur origin <url | none> where fetch reads
22
+ // nervur fetch every ref of origin and all it
23
+ // reaches, kept
24
+ // nervur gc every object live and the
25
+ // fetched refs reach no more, gone
14
26
  // nervur census [--ward W] the empty ask
27
+ // nervur stand [--ward W] what does not stand yet, stood:
28
+ // the dock's faculties and wards,
29
+ // or one ward's beings; every
30
+ // command asks it of the harbor
31
+ // it opens
15
32
  // nervur sweep every place of the folder this
16
33
  // harbor does not name, gone
17
34
  // nervur export [--with-seed] the harbor as one JSON line, to
@@ -22,16 +39,21 @@
22
39
  // nervur edge pack <file> <name> the harbor for an edge, under its
23
40
  // name, in the pack the file holds:
24
41
  // its seed sealed under
25
- // $NERVUR_SECRET, and its places
42
+ // $NERVUR_SECRET, and its places,
43
+ // its code among them
26
44
  // nervur edge dev <file> <name> [--port P] the harbor packed so, and the pack
27
45
  // run by the worker's own wrangler
28
46
  // dev, from this folder, at
29
47
  // http://127.0.0.1:P/<name>/quo
30
- // nervur open <key> <kind> a faculty stands in the box ward
31
- // nervur host <ward> [--seed S] [--store K] a hosted ward stands, kept by the
32
- // root memory or the store K
33
- // nervur move <ward> <store | root> a hosted ward carried to a store,
34
- // or back to the root memory
48
+ // nervur open <key> <kind> [--registry R] a faculty stands in the box ward,
49
+ // her class resolved through the
50
+ // registry faculty R or the catalogue
51
+ // nervur host <ward> [--seed S] [--memory K] a hosted ward stands, kept by the
52
+ // [--class C] [--registry R] root memory or the memory faculty K,
53
+ // its ward of the ward class C, every
54
+ // class of it resolved through R
55
+ // nervur move <ward> <memory | root> a hosted ward carried to a memory
56
+ // faculty, or back to the root memory
35
57
  // nervur route <ward pk> <address... | none> where a ward is reached, in order
36
58
  // nervur reach <address...> where this harbor is reached, as
37
59
  // every invitation it gives says
@@ -42,30 +64,37 @@
42
64
  // nervur ask [--ward W] [being] [method] [args] a being, asked as the owner
43
65
  // nervur own [--ward W] <id> an invitation for an owner
44
66
  // nervur disown [--ward W] <id> an owner no more
45
- // nervur pilot <name> <invitation> [address] a far ward held as its owner, by a
46
- // pilot being of the box ward, at
47
- // the address or the invitation's at
48
- // nervur <command> --via <name> ... the command asked of the far ward
49
- // that pilot holds, as its owner
67
+ // nervur become [--ward W] <kind> the ward born again of that class;
68
+ // [--registry R] the dock's resolved through R
69
+ // nervur pilot <name> <invitation> [address] a far being held as its owner by the
70
+ // dock, under the name, at the address
71
+ // or the invitation's at, the web
72
+ // carrier opened first where it is on
73
+ // the web and none stands
74
+ // nervur <command> --via <name> ... the command asked of the far being
75
+ // the dock holds under that name, as
76
+ // its owner
50
77
  //
51
78
  // D is --dir, then $NERVUR_DIR, then ~/.nervur. A module file is named from
52
- // where the command runs and kept by its absolute path. No --ward is the box
53
- // ward, and a pilot holds one ward, so --via takes no --ward. The exit is 1
54
- // when the answer is an error.
55
- import { existsSync } from 'node:fs';
79
+ // where the command runs, and its text is what the harbor keeps. No --ward is the box
80
+ // ward, and a name holds one far being, so --via takes no --ward. The exit
81
+ // is 1 when the answer is an error.
82
+ import { existsSync, readFileSync } from 'node:fs';
56
83
  import { readFile } from 'node:fs/promises';
57
84
  import { join, resolve } from 'node:path';
58
- import { WEB_OPENING } from '../line/index.js';
59
- import { harborDir, isFile } from '../node/index.js';
85
+ import { carrierIn } from '../harbor/index.js';
86
+ import { harborDir } from '../node/index.js';
60
87
  import { readAt, webAddress } from '../quo/index.js';
61
88
  import { edgeDev } from './edge.js';
62
- import { carry, isServed, land, open, pack, request, serve } from './harbor.js';
89
+ import { carry, census, isServed, land, open, pack, request, serve } from './harbor.js';
63
90
  // Where `edge dev` answers unless --port names another, wrangler's own.
64
91
  const EDGE_PORT = 8787;
65
- const USAGE = 'usage: nervur <init|serve|module|modules|census|sweep|open|host|move|route|reach|boot|unboot|public|invite|ask|own|disown|pilot|export|import|edge> [args] [--dir D] [--ward W] [--via V] [--seed S] [--store K] [--with-seed] [--host H] [--port P]';
66
- const FLAGS = new Set(['dir', 'ward', 'via', 'seed', 'store', 'host', 'port']);
67
- // The one flag that stands alone, since what it names is a yes.
92
+ const USAGE = 'usage: nervur <init|serve|module|modules|live|log|origin|fetch|gc|census|stand|sweep|open|host|move|route|reach|boot|unboot|public|invite|ask|own|disown|become|pilot|export|import|edge> [args] [--dir D] [--ward W] [--via V] [--seed S] [--memory K] [--class C] [--registry R] [--with-seed] [--no-tcp] [--host H] [--port P]';
93
+ const FLAGS = new Set(['dir', 'ward', 'via', 'seed', 'memory', 'class', 'registry', 'host', 'port']);
94
+ // The flags that stand alone, since what each names is a yes.
68
95
  const ALONE = 'with-seed';
96
+ const NO_TCP = 'no-tcp';
97
+ const YES = new Set([ALONE, NO_TCP]);
69
98
  export const parse = (argv) => {
70
99
  const flags = {};
71
100
  const words = [];
@@ -74,7 +103,7 @@ export const parse = (argv) => {
74
103
  const name = arg.startsWith('--') ? arg.slice(2) : undefined;
75
104
  if (name === undefined)
76
105
  words.push(arg);
77
- else if (name === ALONE)
106
+ else if (YES.has(name))
78
107
  flags[name] = 'yes';
79
108
  else if (!FLAGS.has(name) || argv[i + 1] === undefined)
80
109
  throw new Error(`--${name} is no flag with a value`);
@@ -102,32 +131,45 @@ export const requestOf = (command, words, flags) => {
102
131
  return words;
103
132
  };
104
133
  const at = flags.ward === undefined ? {} : { ward: flags.ward };
134
+ const through = flags.registry === undefined ? {} : { registry: flags.registry };
105
135
  switch (command) {
106
136
  case 'module': {
107
137
  const [verb, what] = need(2);
108
138
  if (verb === 'add')
109
- return catalogue('add', { from: isFile(what) ? resolve(what) : what });
139
+ return catalogue('add', { source: readFileSync(resolve(what), 'utf8') });
110
140
  if (verb === 'remove')
111
141
  return catalogue('remove', { module: what });
112
142
  throw new Error('module is add or remove');
113
143
  }
114
144
  case 'modules':
115
145
  return (need(0), catalogue('modules'));
146
+ case 'live':
147
+ if (words.length > 1)
148
+ throw new Error('live takes a commit, or nothing');
149
+ return catalogue('live', words[0] === undefined ? {} : { commit: words[0] });
150
+ case 'log':
151
+ return (need(0), catalogue('log'));
152
+ case 'origin':
153
+ return catalogue('origin', { url: none(need(1)[0]) });
154
+ case 'fetch':
155
+ return (need(0), catalogue('fetch'));
156
+ case 'gc':
157
+ return (need(0), catalogue('gc'));
116
158
  case 'sweep':
117
159
  return (need(0), { method: 'sweep', args: {} });
118
160
  case 'census':
119
161
  return (need(0), at);
120
162
  case 'open': {
121
163
  const [key, kind] = need(2);
122
- return { method: 'open', args: { key: key, class: kind } };
164
+ return { method: 'open', args: { key: key, class: kind, ...through } };
123
165
  }
124
166
  case 'host': {
125
167
  const [ward] = need(1);
126
- return { method: 'host', args: { ward: ward, ...(flags.seed === undefined ? {} : { seed: flags.seed }), ...(flags.store === undefined ? {} : { store: flags.store }) } };
168
+ return { method: 'host', args: { ward: ward, ...(flags.seed === undefined ? {} : { seed: flags.seed }), ...(flags.memory === undefined ? {} : { memory: flags.memory }), ...(flags.class === undefined ? {} : { class: flags.class }), ...through } };
127
169
  }
128
170
  case 'move': {
129
- const [ward, store] = need(2);
130
- return { method: 'move', args: { ward: ward, store: store === 'root' ? null : store } };
171
+ const [ward, memory] = need(2);
172
+ return { method: 'move', args: { ward: ward, memory: memory === 'root' ? null : memory } };
131
173
  }
132
174
  case 'route': {
133
175
  const [ward, ...where] = words;
@@ -160,6 +202,10 @@ export const requestOf = (command, words, flags) => {
160
202
  case 'own':
161
203
  case 'disown':
162
204
  return { ...at, method: command, args: { id: need(1)[0] } };
205
+ case 'stand':
206
+ return (need(0), { ...at, method: 'stand', args: {} });
207
+ case 'become':
208
+ return { ...at, method: 'become', args: { class: need(1)[0], ...through } };
163
209
  default:
164
210
  throw new Error(USAGE);
165
211
  }
@@ -171,7 +217,9 @@ const failed = (answer) => {
171
217
  const a = answer;
172
218
  return 'error' in a || failed(a.answer);
173
219
  };
174
- export const main = async (argv, env, print) => {
220
+ // The command, over the harbors of this machine, each running the defaults
221
+ // its entry hands it.
222
+ export const main = async (argv, env, print, defaults) => {
175
223
  const { command, words, flags } = parse(argv);
176
224
  if (command === undefined)
177
225
  throw new Error(USAGE);
@@ -185,10 +233,18 @@ export const main = async (argv, env, print) => {
185
233
  throw new Error('init takes no argument');
186
234
  if (existsSync(join(dir, 'seed')))
187
235
  return out({ error: `a harbor stands at ${dir}` });
188
- const harbor = await open(dir);
236
+ const harbor = await open(dir, defaults);
189
237
  try {
190
- const owner = await harbor.root('own', { id: 'owner' });
191
- return out({ pk: harbor.box.pk, owner: owner });
238
+ if (flags[NO_TCP] === undefined) {
239
+ const tcp = carrierIn((await census(harbor)).beings, defaults.classes, 'tcp');
240
+ if (tcp === null)
241
+ return out({ error: 'no class this command runs carries tcp' });
242
+ const opened = tcp.open === undefined ? {} : (await harbor.ask(tcp.open)).answer;
243
+ if (opened.error !== undefined)
244
+ return out(opened);
245
+ }
246
+ const owner = (await harbor.ask({ method: 'own', args: { id: 'owner' } })).answer;
247
+ return out({ pk: (await census(harbor)).pk, owner });
192
248
  }
193
249
  finally {
194
250
  await harbor.close();
@@ -225,7 +281,7 @@ export const main = async (argv, env, print) => {
225
281
  if (command === 'serve') {
226
282
  if (words.length > 0)
227
283
  throw new Error('serve takes no argument');
228
- const served = await serve(dir, flags.host, flags.port === undefined ? undefined : Number(flags.port));
284
+ const served = await serve(dir, defaults, flags.host, flags.port === undefined ? undefined : Number(flags.port));
229
285
  const stop = () => void served.close().then(() => process.exit(0));
230
286
  process.once('SIGINT', stop);
231
287
  process.once('SIGTERM', stop);
@@ -237,43 +293,37 @@ export const main = async (argv, env, print) => {
237
293
  throw new Error('pilot takes a name, an invitation, and an address where the invitation carries none');
238
294
  const [name, invitation, at] = words;
239
295
  const held = JSON.parse(invitation);
240
- const census = (await request(dir, {}));
241
- const beings = census.answer?.notes?.beings;
242
- const web = beings !== undefined && Object.hasOwn(beings, WEB_OPENING.key);
296
+ const asked = (await request(dir, defaults, {}));
297
+ const web = carrierIn(asked.answer?.notes?.beings ?? {}, defaults.classes, 'web')?.open;
243
298
  for (const req of pilotRequests(name, held, at, web)) {
244
- const answer = await request(dir, req);
245
- if (!failed(answer))
246
- continue;
247
- if (req.method === 'ask')
248
- await request(dir, { method: 'unboot', args: { being: name } });
249
- return out(answer);
299
+ const answer = await request(dir, defaults, req);
300
+ if (failed(answer))
301
+ return out(answer);
250
302
  }
251
303
  return out({ piloting: name, ward: held.ward });
252
304
  }
253
305
  if (flags.via === undefined)
254
- return out(await request(dir, requestOf(command, words, flags)));
306
+ return out(await request(dir, defaults, requestOf(command, words, flags)));
255
307
  if (flags.ward !== undefined)
256
308
  throw new Error('--via takes no --ward');
257
- return out(farAnswer(await request(dir, via(flags.via, requestOf(command, words, flags)))));
309
+ return out(farAnswer(await request(dir, defaults, via(flags.via, requestOf(command, words, flags)))));
258
310
  };
259
311
  // The root requests that hold a far ward: the web carrier opened, where the
260
- // far ward is reached on the web and this harbor has none; its route where
261
- // one is named, else the take learns it from the invitation's `at`; the
262
- // pilot; the take.
263
- export const pilotRequests = (name, invitation, at, web = false) => [
264
- ...(!web && readAt([...(at === undefined ? [] : [at]), ...readAt(invitation.at)]).some((a) => webAddress(a) !== null) ? [{ method: 'open', args: { key: WEB_OPENING.key, class: WEB_OPENING.kind } }] : []),
265
- ...(at === undefined ? [] : [{ method: 'route', args: { ward: invitation.ward ?? null, at: [at] } }]),
266
- { method: 'boot', args: { key: name, class: 'org.nervur.pilot' } },
267
- { method: 'ask', args: { being: name, method: 'hold', args: { invitation } } },
312
+ // far ward is reached on the web and `web` is the open this harbor still
313
+ // needs; then the dock's `hold`, at the address named, else where the
314
+ // invitation's `at` says.
315
+ export const pilotRequests = (name, invitation, at, web) => [
316
+ ...(web !== undefined && readAt([...(at === undefined ? [] : [at]), ...readAt(invitation.at)]).some((a) => webAddress(a) !== null) ? [web] : []),
317
+ { method: 'hold', args: { name, invitation, ...(at === undefined ? {} : { at }) } },
268
318
  ];
269
- // A root request, asked of the far ward a pilot holds.
270
- export const via = (pilot, far) => ({
271
- method: 'ask',
272
- args: { being: pilot, method: 'pilot', args: { ...(far.method === undefined ? {} : { method: far.method }), ...(far.args === undefined ? {} : { args: far.args }) } },
319
+ // A root request, asked of the far being the dock holds under a name.
320
+ export const via = (name, far) => ({
321
+ method: 'pilot',
322
+ args: { name, ...(far.method === undefined ? {} : { method: far.method }), ...(far.args === undefined ? {} : { args: far.args }) },
273
323
  });
274
- // The far ward-being's answer out of the pilot's, or the local error.
324
+ // The far being's answer out of the dock's, or the local error.
275
325
  export const farAnswer = (local) => {
276
- const inner = local.answer?.answer;
326
+ const inner = local.answer;
277
327
  return typeof inner === 'object' && inner !== null && !Array.isArray(inner) ? inner : local;
278
328
  };
279
329
  // What `main` answers for a harbor it keeps serving: no exit yet.
@@ -19,8 +19,10 @@ import { hex } from '../crypto/index.js';
19
19
  import { CryptoEntropy } from '../pointer/index.js';
20
20
  import { pack } from './harbor.js';
21
21
  export const EDGE_STATE = '.nervur-edge';
22
- const READY_TRIES = 240;
23
- const READY_EVERY = 250;
22
+ // A refused fetch costs next to nothing, so wrangler is asked often and is
23
+ // found the moment it answers, within the same minute as ever.
24
+ const READY_TRIES = 2400;
25
+ const READY_EVERY = 25;
24
26
  const answers = (url) => fetch(url).then(() => true, () => false);
25
27
  // Resolved once wrangler answers at `url`, rejected once it exits or never
26
28
  // answers.
@@ -0,0 +1,25 @@
1
+ import type { JsonObject } from '../being/index.ts';
2
+ import { Harbor, type Carried, type Defaults, type RootRequest } from '../harbor/index.ts';
3
+ export type Census = {
4
+ pk: string;
5
+ beings: Record<string, {
6
+ class: string;
7
+ absent: boolean;
8
+ }>;
9
+ listening: string[];
10
+ };
11
+ export declare const census: (harbor: Harbor) => Promise<Census>;
12
+ export declare const open: (dir: string, defaults: Defaults) => Promise<Harbor>;
13
+ export declare const isServed: (dir: string) => Promise<boolean>;
14
+ export declare const request: (dir: string, defaults: Defaults, req: RootRequest) => Promise<JsonObject>;
15
+ export declare const carry: (dir: string, seed: boolean) => Promise<Carried>;
16
+ export declare const pack: (dir: string, file: string, name: string, secret: string | undefined) => Promise<JsonObject>;
17
+ export declare const land: (dir: string, value: unknown) => Promise<string[]>;
18
+ export type Served = {
19
+ pk: string;
20
+ at: string;
21
+ listening: string[];
22
+ root: string;
23
+ close(): Promise<void>;
24
+ };
25
+ export declare const serve: (dir: string, defaults: Defaults, host?: string, port?: number) => Promise<Served>;
@@ -12,22 +12,30 @@ import { join } from 'node:path';
12
12
  import { hex, unhex } from '../crypto/index.js';
13
13
  import { isHarborName, readPack, sealSeed } from '../edge/index.js';
14
14
  import { FolderCustody, FolderMemory } from '../folder/index.js';
15
- import { carryPlaces, Harbor, landPlaces, readCarried, rootLine } from '../harbor/index.js';
16
- import { askServed, MODULES, NodeTerrain, socketOf } from '../node/index.js';
15
+ import { carrierIn, carryPlaces, Harbor, landPlaces, readCarried } from '../harbor/index.js';
16
+ import { askServed, NodeTerrain, socketOf } from '../node/index.js';
17
17
  import { CryptoEntropy } from '../pointer/index.js';
18
- import { TCP_OPENING } from '../tcp/index.js';
18
+ import { tcpAddress } from '../quo/index.js';
19
19
  // A harbor of a folder, opened for one ask: it listens nowhere and serves
20
20
  // nothing.
21
- export const open = (dir) => Harbor.open(new NodeTerrain({ dir, wakes: false, serves: false }));
21
+ // Every harbor the command opens runs the defaults its entry hands it, and
22
+ // the command holds it, so it asks its `stand` once it opens.
23
+ const standing = async (terrain) => {
24
+ const harbor = await Harbor.open(terrain);
25
+ await harbor.ask({ method: 'stand' });
26
+ return harbor;
27
+ };
28
+ export const census = async (harbor) => (await harbor.ask({})).answer.notes;
29
+ export const open = (dir, defaults) => standing(new NodeTerrain({ dir, defaults, wakes: false, serves: false }));
22
30
  // Whether a harbor of this folder is served now.
23
31
  export const isServed = async (dir) => (await askServed(dir, {})) !== undefined;
24
- export const request = async (dir, req) => {
32
+ export const request = async (dir, defaults, req) => {
25
33
  const served = await askServed(dir, req);
26
34
  if (served !== undefined)
27
35
  return served;
28
- const harbor = await open(dir);
36
+ const harbor = await open(dir, defaults);
29
37
  try {
30
- return await rootLine(harbor, req);
38
+ return await harbor.ask(req);
31
39
  }
32
40
  finally {
33
41
  await harbor.close();
@@ -37,20 +45,16 @@ export const request = async (dir, req) => {
37
45
  // one who asks says so, since custody holds it and a package without it
38
46
  // opens nowhere. No harbor opens, so nothing is asked and nothing is
39
47
  // written.
40
- export const carry = async (dir, seed) => {
41
- const places = await carryPlaces(new FolderMemory(dir));
42
- const modules = await readFile(join(dir, MODULES), 'utf8').then((text) => JSON.parse(text), () => undefined);
43
- return {
44
- ...(seed ? { seed: hex(await new FolderCustody(dir, new CryptoEntropy()).seed()) } : {}),
45
- places,
46
- ...(modules ? { modules } : {}),
47
- };
48
- };
48
+ export const carry = async (dir, seed) => ({
49
+ ...(seed ? { seed: hex(await new FolderCustody(dir, new CryptoEntropy()).seed()) } : {}),
50
+ places: await carryPlaces(new FolderMemory(dir)),
51
+ });
49
52
  // What `nervur edge pack` hands a deploy: the harbor of a folder, under
50
53
  // its name, in the pack the worker bundles, its seed sealed under the
51
- // worker's `NERVUR_SECRET` beside its sealed places. Every other harbor
52
- // the pack holds stays, so one worker carries them all, and nothing in the
53
- // pack opens without the secret.
54
+ // worker's `NERVUR_SECRET` beside its sealed places. Its code travels in
55
+ // its places, as its DNA, so the edge loads what `live` names from there.
56
+ // Every other harbor the pack holds stays, so one worker carries them all,
57
+ // and nothing in the pack opens without the secret.
54
58
  export const pack = async (dir, file, name, secret) => {
55
59
  if (!isHarborName(name))
56
60
  throw new Error(`${name} is no harbor name: lowercase letters, digits and -`);
@@ -81,23 +85,31 @@ export const land = async (dir, value) => {
81
85
  await writeFile(join(dir, 'seed'), `${held.seed}\n`, { mode: 0o600, flag: 'wx' });
82
86
  else if (!existsSync(join(dir, 'seed')))
83
87
  throw new Error('the package carries no seed, and none is held here');
84
- if (held.modules && !existsSync(join(dir, MODULES)))
85
- await writeFile(join(dir, MODULES), `${JSON.stringify(held.modules, null, 2)}\n`, { mode: 0o600 });
86
88
  return landPlaces(memory, held);
87
89
  };
88
- // The harbor served: a harbor of the Node ground, with Quo over TCP on
89
- // host and port.
90
- export const serve = async (dir, host, port) => {
91
- const harbor = await Harbor.open(new NodeTerrain({ dir }));
92
- if (!harbor.box.being(TCP_OPENING.key))
93
- await harbor.root('open', { key: TCP_OPENING.key, class: TCP_OPENING.kind });
94
- const tcp = harbor.box.being(TCP_OPENING.key);
95
- if (host !== undefined || port !== undefined || tcp.listening().length === 0) {
96
- const heard = (await harbor.root('ask', { being: TCP_OPENING.key, method: 'listen', args: { ...(host === undefined ? {} : { host }), ...(port === undefined ? {} : { port }) } }));
97
- if (typeof heard.answer?.at !== 'string') {
90
+ // The harbor served: a harbor of the Node ground, with Quo over the TCP
91
+ // carrier its root opened, on host and port. Serving adds nothing to the
92
+ // harbor, so one with no TCP carrier is not served.
93
+ export const serve = async (dir, defaults, host, port) => {
94
+ if (!existsSync(join(dir, 'seed')))
95
+ throw new Error(`no harbor stands at ${dir}: init one first`);
96
+ const harbor = await standing(new NodeTerrain({ dir, defaults }));
97
+ const tcpOf = (listening) => listening.find((address) => tcpAddress(address) !== null);
98
+ const before = await census(harbor);
99
+ const present = Object.fromEntries(Object.entries(before.beings).filter(([, being]) => !being.absent));
100
+ const tcp = carrierIn(present, defaults.classes, 'tcp');
101
+ if (tcp?.open !== undefined || tcp === null) {
102
+ await harbor.close();
103
+ const kind = tcp?.open?.args?.class;
104
+ throw new Error(`the harbor at ${dir} has no tcp carrier${typeof kind === 'string' ? `: open one with \`nervur open tcp ${kind}\`` : ''}`);
105
+ }
106
+ if (host !== undefined || port !== undefined || tcpOf(before.listening) === undefined) {
107
+ const heard = await harbor.ask({ method: 'ask', args: { being: tcp.key, method: 'listen', args: { ...(host === undefined ? {} : { host }), ...(port === undefined ? {} : { port }) } } });
108
+ if (typeof heard.answer?.answer?.at !== 'string') {
98
109
  await harbor.close();
99
- throw new Error(`the harbor does not listen: ${JSON.stringify(heard)}`);
110
+ throw new Error(`the harbor does not listen: ${JSON.stringify(heard.answer ?? heard)}`);
100
111
  }
101
112
  }
102
- return { pk: harbor.box.pk, at: tcp.listening()[0], listening: harbor.carriers.flatMap((c) => c.listening()), root: socketOf(dir), close: () => harbor.close() };
113
+ const { pk, listening } = await census(harbor);
114
+ return { pk, at: tcpOf(listening), listening, root: socketOf(dir), close: () => harbor.close() };
103
115
  };