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.
- package/README.md +215 -158
- package/dist/browser.js +4 -3
- package/dist/cli.js +16 -0
- package/dist/{being → core/being}/being.js +10 -0
- package/dist/{being → core/being}/faculty.js +5 -2
- package/dist/{being → core/being}/index.d.ts +1 -1
- package/dist/{being → core/being}/index.js +1 -1
- package/dist/{being → core/being}/kind.d.ts +2 -0
- package/dist/{being → core/being}/kind.js +6 -0
- package/dist/{being → core/being}/types.js +1 -1
- package/dist/{browser → core/browser}/index.d.ts +6 -5
- package/dist/{browser → core/browser}/index.js +10 -10
- package/dist/{browser → core/browser}/worker.d.ts +2 -3
- package/dist/{browser → core/browser}/worker.js +8 -11
- package/dist/{cli → core/cli}/command.d.ts +4 -4
- package/dist/{cli → core/cli}/command.js +116 -66
- package/dist/{cli → core/cli}/edge.js +4 -2
- package/dist/core/cli/harbor.d.ts +25 -0
- package/dist/{cli → core/cli}/harbor.js +45 -33
- package/dist/{contract → core/contract}/index.d.ts +6 -5
- package/dist/{contract → core/contract}/index.js +8 -9
- package/dist/core/contract/link.d.ts +4 -0
- package/dist/core/contract/link.js +45 -0
- package/dist/{crypto → core/crypto}/ed25519.js +22 -14
- package/dist/core/crypto/subtle.d.ts +3 -0
- package/dist/core/crypto/subtle.js +11 -0
- package/dist/core/crypto/x25519.js +24 -0
- package/dist/core/edge/index.d.ts +164 -0
- package/dist/core/edge/index.js +739 -0
- package/dist/core/edge/kit.d.ts +2 -0
- package/dist/core/edge/kit.js +2 -0
- package/dist/core/git/http.d.ts +6 -0
- package/dist/core/git/http.js +102 -0
- package/dist/core/git/index.d.ts +5 -0
- package/dist/core/git/index.js +10 -0
- package/dist/core/git/object.d.ts +40 -0
- package/dist/core/git/object.js +103 -0
- package/dist/core/git/pack.d.ts +9 -0
- package/dist/core/git/pack.js +171 -0
- package/dist/core/git/store.d.ts +23 -0
- package/dist/core/git/store.js +120 -0
- package/dist/core/git/zlib.d.ts +6 -0
- package/dist/core/git/zlib.js +210 -0
- package/dist/core/harbor/carrying.d.ts +51 -0
- package/dist/core/harbor/carrying.js +69 -0
- package/dist/core/harbor/catalogue.d.ts +33 -0
- package/dist/core/harbor/catalogue.js +365 -0
- package/dist/core/harbor/dna.d.ts +13 -0
- package/dist/core/harbor/dna.js +120 -0
- package/dist/{harbor → core/harbor}/dock.d.ts +22 -13
- package/dist/core/harbor/dock.js +381 -0
- package/dist/core/harbor/harbor.d.ts +16 -0
- package/dist/core/harbor/harbor.js +438 -0
- package/dist/core/harbor/index.d.ts +11 -0
- package/dist/{harbor → core/harbor}/index.js +5 -5
- package/dist/core/harbor/memory.d.ts +10 -0
- package/dist/core/harbor/memory.js +25 -0
- package/dist/{harbor → core/harbor}/package.d.ts +0 -1
- package/dist/{harbor → core/harbor}/package.js +9 -9
- package/dist/core/harbor/probe.d.ts +22 -0
- package/dist/core/harbor/probe.js +15 -0
- package/dist/core/harbor/registry.d.ts +15 -0
- package/dist/{harbor → core/harbor}/registry.js +26 -10
- package/dist/core/harbor/root-line.d.ts +7 -0
- package/dist/core/harbor/root-line.js +9 -0
- package/dist/{harbor → core/harbor}/terrain.d.ts +9 -6
- package/dist/{harbor → core/harbor}/terrain.js +5 -4
- package/dist/core/http/index.d.ts +2 -0
- package/dist/{http → core/http}/index.js +3 -5
- package/dist/{line → core/line}/answer.d.ts +2 -2
- package/dist/{line → core/line}/frame.d.ts +0 -5
- package/dist/{line → core/line}/frame.js +0 -4
- package/dist/core/line/ground.js +7 -0
- package/dist/core/line/index.d.ts +4 -0
- package/dist/core/line/index.js +8 -0
- package/dist/core/line/web.d.ts +12 -0
- package/dist/{line → core/line}/web.js +13 -77
- package/dist/{node → core/node}/index.d.ts +2 -15
- package/dist/core/node/index.js +124 -0
- package/dist/{pointer → core/pointer}/bodies.d.ts +7 -5
- package/dist/core/pointer/bodies.js +118 -0
- package/dist/core/pointer/index.d.ts +2 -0
- package/dist/{pointer → core/pointer}/index.js +1 -1
- package/dist/{pointer → core/pointer}/world.d.ts +13 -9
- package/dist/{pointer → core/pointer}/world.js +31 -16
- package/dist/{proof → core/proof}/contracts.d.ts +6 -2
- package/dist/{proof → core/proof}/contracts.js +11 -10
- package/dist/core/proof/index.d.ts +3 -0
- package/dist/{proof → core/proof}/index.js +2 -2
- package/dist/core/proof/law.d.ts +25 -0
- package/dist/core/proof/law.js +715 -0
- package/dist/{tcp → core/tcp}/index.d.ts +7 -4
- package/dist/{tcp → core/tcp}/index.js +11 -62
- package/dist/{ward/ward.d.ts → core/ward/house.d.ts} +24 -10
- package/dist/core/ward/house.js +473 -0
- package/dist/core/ward/index.d.ts +5 -0
- package/dist/core/ward/index.js +7 -0
- package/dist/{ward → core/ward}/partition.d.ts +1 -0
- package/dist/{ward → core/ward}/stance.d.ts +2 -2
- package/dist/{ward → core/ward}/stance.js +5 -2
- package/dist/{ward/ward-being.d.ts → core/ward/ward.d.ts} +14 -6
- package/dist/core/ward/ward.js +140 -0
- package/dist/core.d.ts +10 -0
- package/dist/core.js +19 -0
- package/dist/defaults/dock/index.d.ts +4 -0
- package/dist/defaults/dock/index.js +11 -0
- package/dist/defaults/index.d.ts +5 -0
- package/dist/defaults/index.js +10 -0
- package/dist/defaults/memory/index.d.ts +12 -0
- package/dist/defaults/memory/index.js +39 -0
- package/dist/defaults/tcp/index.d.ts +16 -0
- package/dist/defaults/tcp/index.js +82 -0
- package/dist/defaults/ward/index.d.ts +4 -0
- package/dist/defaults/ward/index.js +11 -0
- package/dist/defaults/web/index.d.ts +15 -0
- package/dist/defaults/web/index.js +90 -0
- package/dist/edge.js +4 -3
- package/dist/index.d.ts +1 -8
- package/dist/index.js +13 -18
- package/dist/kit.d.ts +4 -0
- package/dist/kit.js +12 -0
- package/dist/node.js +4 -3
- package/package.json +23 -18
- package/src/browser.ts +4 -3
- package/src/cli.ts +15 -0
- package/src/{being → core/being}/being.ts +4 -0
- package/src/{being → core/being}/faculty.ts +5 -2
- package/src/{being → core/being}/index.ts +1 -1
- package/src/{being → core/being}/kind.ts +7 -0
- package/src/{being → core/being}/types.ts +1 -1
- package/src/{browser → core/browser}/index.ts +16 -13
- package/src/{browser → core/browser}/worker.ts +11 -14
- package/src/{cli → core/cli}/command.ts +113 -66
- package/src/{cli → core/cli}/edge.ts +4 -2
- package/src/{cli → core/cli}/harbor.ts +48 -31
- package/src/{contract → core/contract}/index.ts +14 -14
- package/src/core/contract/link.ts +58 -0
- package/src/{crypto → core/crypto}/ed25519.ts +22 -14
- package/src/core/crypto/subtle.ts +13 -0
- package/src/core/crypto/x25519.ts +23 -0
- package/src/core/edge/index.ts +865 -0
- package/src/core/git/http.ts +103 -0
- package/src/core/git/index.ts +10 -0
- package/src/core/git/object.ts +116 -0
- package/src/core/git/pack.ts +147 -0
- package/src/core/git/store.ts +122 -0
- package/src/core/git/zlib.ts +197 -0
- package/src/core/harbor/carrying.ts +124 -0
- package/src/core/harbor/catalogue.ts +386 -0
- package/src/core/harbor/dna.ts +116 -0
- package/src/core/harbor/dock.ts +420 -0
- package/src/core/harbor/harbor.ts +433 -0
- package/src/core/harbor/index.ts +14 -0
- package/src/core/harbor/memory.ts +31 -0
- package/src/{harbor → core/harbor}/package.ts +15 -15
- package/src/core/harbor/probe.ts +39 -0
- package/src/{harbor → core/harbor}/registry.ts +28 -11
- package/src/core/harbor/root-line.ts +19 -0
- package/src/{harbor → core/harbor}/terrain.ts +14 -7
- package/src/{http → core/http}/index.ts +5 -8
- package/src/{line → core/line}/answer.ts +3 -2
- package/src/{line → core/line}/frame.ts +0 -5
- package/src/core/line/ground.ts +18 -0
- package/src/core/line/index.ts +8 -0
- package/src/{line → core/line}/web.ts +1 -105
- package/src/core/node/index.ts +139 -0
- package/src/core/pointer/bodies.ts +122 -0
- package/src/core/pointer/index.ts +4 -0
- package/src/{pointer → core/pointer}/world.ts +45 -21
- package/src/{proof → core/proof}/contracts.ts +18 -13
- package/src/{proof → core/proof}/index.ts +3 -3
- package/src/core/proof/law.ts +742 -0
- package/src/{stand → core/stand}/stand.ts +2 -2
- package/src/{tcp → core/tcp}/index.ts +17 -74
- package/src/core/ward/house.ts +524 -0
- package/src/core/ward/index.ts +7 -0
- package/src/{ward → core/ward}/partition.ts +5 -1
- package/src/{ward → core/ward}/stance.ts +5 -2
- package/src/core/ward/ward.ts +166 -0
- package/src/core.ts +55 -0
- package/src/defaults/dock/index.ts +12 -0
- package/src/defaults/index.ts +10 -0
- package/src/defaults/memory/index.ts +50 -0
- package/src/defaults/tcp/index.ts +89 -0
- package/src/defaults/ward/index.ts +12 -0
- package/src/defaults/web/index.ts +97 -0
- package/src/edge.ts +4 -3
- package/src/index.ts +13 -50
- package/src/kit.ts +15 -0
- package/src/node.ts +4 -3
- package/dist/cli/harbor.d.ts +0 -16
- package/dist/cli/main.js +0 -14
- package/dist/crypto/subtle.d.ts +0 -10
- package/dist/crypto/subtle.js +0 -29
- package/dist/crypto/x25519.js +0 -21
- package/dist/edge/index.d.ts +0 -81
- package/dist/edge/index.js +0 -400
- package/dist/harbor/carrying.d.ts +0 -17
- package/dist/harbor/carrying.js +0 -38
- package/dist/harbor/catalogue.d.ts +0 -28
- package/dist/harbor/catalogue.js +0 -109
- package/dist/harbor/dock.js +0 -236
- package/dist/harbor/harbor.d.ts +0 -45
- package/dist/harbor/harbor.js +0 -347
- package/dist/harbor/index.d.ts +0 -11
- package/dist/harbor/probe.d.ts +0 -18
- package/dist/harbor/probe.js +0 -15
- package/dist/harbor/registry.d.ts +0 -10
- package/dist/harbor/relay.d.ts +0 -15
- package/dist/harbor/relay.js +0 -406
- package/dist/harbor/root-line.d.ts +0 -9
- package/dist/harbor/root-line.js +0 -38
- package/dist/harbor/store.d.ts +0 -13
- package/dist/harbor/store.js +0 -53
- package/dist/http/index.d.ts +0 -4
- package/dist/line/ground.js +0 -9
- package/dist/line/index.d.ts +0 -5
- package/dist/line/index.js +0 -9
- package/dist/line/push.d.ts +0 -7
- package/dist/line/push.js +0 -92
- package/dist/line/web.d.ts +0 -30
- package/dist/node/index.js +0 -236
- package/dist/pointer/bodies.js +0 -80
- package/dist/pointer/index.d.ts +0 -2
- package/dist/proof/index.d.ts +0 -3
- package/dist/proof/law.d.ts +0 -90
- package/dist/proof/law.js +0 -591
- package/dist/tcp/frame.d.ts +0 -25
- package/dist/tcp/frame.js +0 -64
- package/dist/ward/index.d.ts +0 -6
- package/dist/ward/index.js +0 -8
- package/dist/ward/pilot.d.ts +0 -8
- package/dist/ward/pilot.js +0 -50
- package/dist/ward/ward-being.js +0 -82
- package/dist/ward/ward.js +0 -290
- package/src/cli/main.ts +0 -13
- package/src/crypto/subtle.ts +0 -33
- package/src/crypto/x25519.ts +0 -21
- package/src/edge/index.ts +0 -490
- package/src/harbor/carrying.ts +0 -56
- package/src/harbor/catalogue.ts +0 -134
- package/src/harbor/dock.ts +0 -265
- package/src/harbor/harbor.ts +0 -381
- package/src/harbor/index.ts +0 -14
- package/src/harbor/probe.ts +0 -34
- package/src/harbor/relay.ts +0 -418
- package/src/harbor/root-line.ts +0 -39
- package/src/harbor/store.ts +0 -69
- package/src/line/ground.ts +0 -19
- package/src/line/index.ts +0 -9
- package/src/line/push.ts +0 -112
- package/src/node/index.ts +0 -241
- package/src/pointer/bodies.ts +0 -82
- package/src/pointer/index.ts +0 -4
- package/src/proof/law.ts +0 -591
- package/src/ward/index.ts +0 -8
- package/src/ward/pilot.ts +0 -50
- package/src/ward/ward-being.ts +0 -103
- package/src/ward/ward.ts +0 -328
- /package/dist/{cli/main.d.ts → cli.d.ts} +0 -0
- /package/dist/{being → core/being}/being.d.ts +0 -0
- /package/dist/{being → core/being}/digest.d.ts +0 -0
- /package/dist/{being → core/being}/digest.js +0 -0
- /package/dist/{being → core/being}/faculty.d.ts +0 -0
- /package/dist/{being → core/being}/types.d.ts +0 -0
- /package/dist/{being → core/being}/words.d.ts +0 -0
- /package/dist/{being → core/being}/words.js +0 -0
- /package/dist/{cli → core/cli}/edge.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/aes.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/aes.js +0 -0
- /package/dist/{crypto → core/crypto}/bytes.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/bytes.js +0 -0
- /package/dist/{crypto → core/crypto}/ed25519.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/hash.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/hash.js +0 -0
- /package/dist/{crypto → core/crypto}/index.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/index.js +0 -0
- /package/dist/{crypto → core/crypto}/json.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/json.js +0 -0
- /package/dist/{crypto → core/crypto}/mlkem.d.ts +0 -0
- /package/dist/{crypto → core/crypto}/mlkem.js +0 -0
- /package/dist/{crypto → core/crypto}/x25519.d.ts +0 -0
- /package/dist/{folder → core/folder}/index.d.ts +0 -0
- /package/dist/{folder → core/folder}/index.js +0 -0
- /package/dist/{http → core/http}/websocket.d.ts +0 -0
- /package/dist/{http → core/http}/websocket.js +0 -0
- /package/dist/{line → core/line}/answer.js +0 -0
- /package/dist/{line → core/line}/ground.d.ts +0 -0
- /package/dist/{proof → core/proof}/expect.d.ts +0 -0
- /package/dist/{proof → core/proof}/expect.js +0 -0
- /package/dist/{quo → core/quo}/address.d.ts +0 -0
- /package/dist/{quo → core/quo}/address.js +0 -0
- /package/dist/{quo → core/quo}/door.d.ts +0 -0
- /package/dist/{quo → core/quo}/door.js +0 -0
- /package/dist/{quo → core/quo}/index.d.ts +0 -0
- /package/dist/{quo → core/quo}/index.js +0 -0
- /package/dist/{quo → core/quo}/invitation.d.ts +0 -0
- /package/dist/{quo → core/quo}/invitation.js +0 -0
- /package/dist/{quo → core/quo}/keys.d.ts +0 -0
- /package/dist/{quo → core/quo}/keys.js +0 -0
- /package/dist/{quo → core/quo}/payload.d.ts +0 -0
- /package/dist/{quo → core/quo}/payload.js +0 -0
- /package/dist/{quo → core/quo}/relations.d.ts +0 -0
- /package/dist/{quo → core/quo}/relations.js +0 -0
- /package/dist/{quo → core/quo}/reply.d.ts +0 -0
- /package/dist/{quo → core/quo}/reply.js +0 -0
- /package/dist/{quo → core/quo}/seal.d.ts +0 -0
- /package/dist/{quo → core/quo}/seal.js +0 -0
- /package/dist/{quo → core/quo}/standing.d.ts +0 -0
- /package/dist/{quo → core/quo}/standing.js +0 -0
- /package/dist/{ward → core/ward}/allowance.d.ts +0 -0
- /package/dist/{ward → core/ward}/allowance.js +0 -0
- /package/dist/{ward → core/ward}/cells.d.ts +0 -0
- /package/dist/{ward → core/ward}/cells.js +0 -0
- /package/dist/{ward → core/ward}/partition.js +0 -0
- /package/src/{being → core/being}/digest.ts +0 -0
- /package/src/{being → core/being}/words.ts +0 -0
- /package/src/{crypto → core/crypto}/aes.ts +0 -0
- /package/src/{crypto → core/crypto}/bytes.ts +0 -0
- /package/src/{crypto → core/crypto}/hash.ts +0 -0
- /package/src/{crypto → core/crypto}/index.ts +0 -0
- /package/src/{crypto → core/crypto}/json.ts +0 -0
- /package/src/{crypto → core/crypto}/mlkem.ts +0 -0
- /package/src/{folder → core/folder}/index.ts +0 -0
- /package/src/{http → core/http}/websocket.ts +0 -0
- /package/src/{proof → core/proof}/expect.ts +0 -0
- /package/src/{quo → core/quo}/address.ts +0 -0
- /package/src/{quo → core/quo}/door.ts +0 -0
- /package/src/{quo → core/quo}/index.ts +0 -0
- /package/src/{quo → core/quo}/invitation.ts +0 -0
- /package/src/{quo → core/quo}/keys.ts +0 -0
- /package/src/{quo → core/quo}/payload.ts +0 -0
- /package/src/{quo → core/quo}/relations.ts +0 -0
- /package/src/{quo → core/quo}/reply.ts +0 -0
- /package/src/{quo → core/quo}/seal.ts +0 -0
- /package/src/{quo → core/quo}/standing.ts +0 -0
- /package/src/{stand → core/stand}/main.ts +0 -0
- /package/src/{ward → core/ward}/allowance.ts +0 -0
- /package/src/{ward → core/ward}/cells.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Custody, Memory, type
|
|
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 {
|
|
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
|
|
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
|
|
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 {
|
|
15
|
-
|
|
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,
|
|
148
|
-
//
|
|
149
|
-
//
|
|
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
|
|
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: ({
|
|
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 {
|
|
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
|
|
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
|
|
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 = (
|
|
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(
|
|
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
|
|
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?:
|
|
11
|
-
export declare const via: (
|
|
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]
|
|
6
|
-
// its catalogue stood,
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// nervur
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// nervur
|
|
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>
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
// nervur
|
|
34
|
-
//
|
|
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
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
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
|
|
53
|
-
// ward, and a
|
|
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 {
|
|
59
|
-
import { harborDir
|
|
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] [--
|
|
66
|
-
const FLAGS = new Set(['dir', 'ward', 'via', 'seed', '
|
|
67
|
-
// The
|
|
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
|
|
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', {
|
|
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.
|
|
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,
|
|
130
|
-
return { method: 'move', args: { ward: ward,
|
|
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
|
-
|
|
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
|
-
|
|
191
|
-
|
|
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
|
|
241
|
-
const
|
|
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 (
|
|
246
|
-
|
|
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
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
export const pilotRequests = (name, invitation, at, web
|
|
264
|
-
...(
|
|
265
|
-
|
|
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
|
|
270
|
-
export const via = (
|
|
271
|
-
method: '
|
|
272
|
-
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
|
|
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
|
|
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
|
-
|
|
23
|
-
|
|
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
|
|
16
|
-
import { askServed,
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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.
|
|
52
|
-
//
|
|
53
|
-
//
|
|
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
|
|
89
|
-
// host and port.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
113
|
+
const { pk, listening } = await census(harbor);
|
|
114
|
+
return { pk, at: tcpOf(listening), listening, root: socketOf(dir), close: () => harbor.close() };
|
|
103
115
|
};
|