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
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// The dock: the contract of the box ward's ward. Beside the root's asks of
|
|
3
|
+
// every ward, she opens faculties, hosts wards, and lends each contract a
|
|
4
|
+
// faculty fulfils to the wards she hosts. The core names no class of it:
|
|
5
|
+
// the terrain hands the harbor the one that stands at genesis. She is born
|
|
6
|
+
// of her stance alone, which carries her harbor as `ground`.
|
|
7
|
+
//
|
|
8
|
+
// She stands once the harbor has booted: its seed, its memory, the
|
|
9
|
+
// catalogue and every registry the catalogue resolves stand, and her class
|
|
10
|
+
// resolved through the registry her row names. The harbor hands her the
|
|
11
|
+
// door and is done; from there everything is an ask. Her `stand` is the
|
|
12
|
+
// second level, hers alone, asked by whoever holds the harbor or pilots
|
|
13
|
+
// it: every other faculty of the box, each once the registry it names
|
|
14
|
+
// stands, registries first, then memory faculties, then the rest; then
|
|
15
|
+
// every hosted ward, her house unpacked and her ward stood. A being of a
|
|
16
|
+
// hosted ward stands nowhere: she is born for the asks that reach her. It
|
|
17
|
+
// answers what stood, or silence where everything already stands. A
|
|
18
|
+
// faculty names its class and its registry, and keeps its cells in the box
|
|
19
|
+
// ward. A hosted ward names its class, its registry and the memory that
|
|
20
|
+
// keeps it.
|
|
21
|
+
//
|
|
22
|
+
// stand every faculty and hosted ward that does
|
|
23
|
+
// not stand yet, stood
|
|
24
|
+
// open { key, class, a faculty stands in the box ward, her class
|
|
25
|
+
// registry? } resolved through the registry faculty named
|
|
26
|
+
// or the catalogue, and the dock holds a
|
|
27
|
+
// standing on her under her key
|
|
28
|
+
// host { ward, seed?, a hosted ward stands under the seed named,
|
|
29
|
+
// memory?, class?, or a drawn one, of the ward class named or
|
|
30
|
+
// registry? } the default one, resolved with every class
|
|
31
|
+
// of the ward through the registry faculty
|
|
32
|
+
// named or the catalogue, holding a standing
|
|
33
|
+
// on the dock; the dock keeps its name, its
|
|
34
|
+
// seed, its registry and the memory faculty
|
|
35
|
+
// that keeps its place, or none for the root
|
|
36
|
+
// memory
|
|
37
|
+
// move { ward, memory } a hosted ward's place carried whole to
|
|
38
|
+
// another keeper, a memory faculty's key or
|
|
39
|
+
// null for the root memory, and forgotten
|
|
40
|
+
// where it was
|
|
41
|
+
// lend { contract } asked by a hosted ward: an offer from a
|
|
42
|
+
// faculty that fulfils the contract
|
|
43
|
+
// retract { contract, heir } an offer that was not taken
|
|
44
|
+
// route { ward, at } where a ward pk is reached, addresses in the
|
|
45
|
+
// order they are tried, or null to forget
|
|
46
|
+
// it; the dock keeps it and the harbor hands
|
|
47
|
+
// it to its carrier
|
|
48
|
+
// hold { name, invitation, a far being held as the ward's `hold`
|
|
49
|
+
// at? } holds it, its ward routed at the address
|
|
50
|
+
// named first
|
|
51
|
+
// reach { at } where this harbor is reached, the
|
|
52
|
+
// addresses every invitation it gives carries
|
|
53
|
+
// heard a push heard, told to every carrier faculty,
|
|
54
|
+
// so one that collects for this harbor
|
|
55
|
+
// collects
|
|
56
|
+
//
|
|
57
|
+
// Her census adds, for whoever pilots, what her cells keep, each hosted
|
|
58
|
+
// ward by name with its keeper and registry but never its seed, the routes
|
|
59
|
+
// and the reach; what did not stand; and every address the harbor's
|
|
60
|
+
// carriers listen at.
|
|
61
|
+
//
|
|
62
|
+
// A take of an invitation that carries `at` teaches the dock that ward's
|
|
63
|
+
// route, where the root set none.
|
|
64
|
+
import { Faculty, ships, WARD, type Asker, type AskSpec, type BeingClass, type Blueprint, type Invitation, type JsonObject, type Stance } from '../being/index.ts';
|
|
65
|
+
import { Catalogue, CATALOGUE } from './catalogue.ts';
|
|
66
|
+
import { MEMORY, MemoryFaculty } from './memory.ts';
|
|
67
|
+
import { registers } from './registry.ts';
|
|
68
|
+
import { readAt, readInvitation } from '../quo/index.ts';
|
|
69
|
+
import { ownerAsk, pilots, rootAsk, Ward, type Lender, type WardStance } from '../ward/index.ts';
|
|
70
|
+
|
|
71
|
+
// What the dock asks of her harbor: a ward standing, and the seed, as hex,
|
|
72
|
+
// it stands under.
|
|
73
|
+
export interface Hosting {
|
|
74
|
+
host(name: string, invitation: Invitation, seed?: string, memory?: string, kind?: string, registry?: string): Promise<string | null>;
|
|
75
|
+
// A hosted ward the dock's cells name, standing: its house unpacked and
|
|
76
|
+
// its ward stood where they are not. Whether it stood now; one that does
|
|
77
|
+
// not stand fails alone, and the census names it.
|
|
78
|
+
stand(hosted: Hosted): Promise<boolean>;
|
|
79
|
+
// A standing ward's place, carried to another keeper and standing from
|
|
80
|
+
// there: null, or why not. Where it was stays until `release`.
|
|
81
|
+
move(name: string, seed: string, from: string | undefined, to: string | undefined): Promise<string | null>;
|
|
82
|
+
// A ward's place, forgotten by the keeper named.
|
|
83
|
+
release(name: string, memory: string | undefined): Promise<void>;
|
|
84
|
+
// Whether the harbor's carrier took the route.
|
|
85
|
+
route(pk: string, at: readonly string[] | null): boolean;
|
|
86
|
+
// A route the dock keeps, handed to the carrier as the harbor stands:
|
|
87
|
+
// where no carrier dials it, the census names it.
|
|
88
|
+
reached(pk: string, at: readonly string[]): void;
|
|
89
|
+
// Whether the box ward's partition was kept.
|
|
90
|
+
keep(): Promise<boolean>;
|
|
91
|
+
// What did not stand when the harbor opened.
|
|
92
|
+
failures(): Failures;
|
|
93
|
+
// Whether the harbor lives only as long as a screen.
|
|
94
|
+
readonly foreground: boolean;
|
|
95
|
+
// Every place of the memory the dock does not name, gone.
|
|
96
|
+
sweep(): Promise<string[]>;
|
|
97
|
+
// A faculty just opened, woken where it wakes; one stood as the harbor
|
|
98
|
+
// stands, woken where the harbor's carriers wake; and one about to go,
|
|
99
|
+
// put to sleep.
|
|
100
|
+
awaken(key: string): Promise<void>;
|
|
101
|
+
rouse(key: string): Promise<void>;
|
|
102
|
+
lull(key: string): Promise<void>;
|
|
103
|
+
// Every address the harbor's carriers listen at now.
|
|
104
|
+
listening(): string[];
|
|
105
|
+
// A push heard, told to every carrier faculty.
|
|
106
|
+
heard(): Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// One hosted ward, as the dock's cells keep it, with the key of the memory
|
|
110
|
+
// faculty that keeps its place where the root memory does not, and of the
|
|
111
|
+
// registry faculty its classes resolve through where the catalogue does
|
|
112
|
+
// not.
|
|
113
|
+
export type Hosted = { ward: string; seed: string; memory?: string; registry?: string };
|
|
114
|
+
|
|
115
|
+
// Each hosted ward that did not unpack and each route the carrier did not
|
|
116
|
+
// take, with the reason, by name and by ward pk.
|
|
117
|
+
export type Failures = { wards: Record<string, string>; routes: Record<string, string> };
|
|
118
|
+
|
|
119
|
+
export const BOX = 'box';
|
|
120
|
+
const text = (v: unknown): v is string => typeof v === 'string';
|
|
121
|
+
// A list of addresses, each a URI with a scheme, and at least one.
|
|
122
|
+
const addresses = (v: unknown): v is string[] => Array.isArray(v) && v.length > 0 && readAt(v).length === v.length;
|
|
123
|
+
const hosted: AskSpec['for'] = (_: Asker, notes: JsonObject | undefined) => notes?.hosted === true;
|
|
124
|
+
|
|
125
|
+
// The box ward's stance: a ward's, and the harbor she docks.
|
|
126
|
+
export type DockStance = WardStance & { readonly ground: Hosting };
|
|
127
|
+
|
|
128
|
+
// Whether a class is the catalogue's, which stands under `catalogue` alone.
|
|
129
|
+
const catalogues = (C: unknown): boolean => C === Catalogue || (typeof C === 'function' && C.prototype instanceof Catalogue);
|
|
130
|
+
|
|
131
|
+
// Whether a class may be a hosted ward's: a ward, and no dock.
|
|
132
|
+
export const hostable = (C: unknown): boolean => Ward.fulfils(C) && !Dock.fulfils(C);
|
|
133
|
+
|
|
134
|
+
export abstract class Dock extends Ward implements Lender {
|
|
135
|
+
static override readonly kind: string = 'org.nervur.dock';
|
|
136
|
+
static {
|
|
137
|
+
ships(this);
|
|
138
|
+
}
|
|
139
|
+
static override cells: JsonObject = { hosted: [], routes: {}, reach: [] };
|
|
140
|
+
static override asks: Record<string, AskSpec> = {
|
|
141
|
+
...Ward.asks,
|
|
142
|
+
stand: ownerAsk('every faculty and hosted ward that does not stand yet, stood; silence where everything stands'),
|
|
143
|
+
open: ownerAsk('a faculty of this harbor', { required: ['key', 'class'] }),
|
|
144
|
+
host: ownerAsk('a ward this harbor hosts, kept by the root memory or by the memory faculty named', { required: ['ward'] }),
|
|
145
|
+
move: ownerAsk('a hosted ward carried to a memory faculty, or to the root memory with null', { required: ['ward', 'memory'] }),
|
|
146
|
+
hold: ownerAsk('an owner invitation on a far being, held under a name from now on, at the address named', { required: ['name', 'invitation'] }),
|
|
147
|
+
route: ownerAsk('where a ward is reached, addresses in order, or null', { required: ['ward', 'at'] }),
|
|
148
|
+
reach: ownerAsk('where this harbor is reached, the addresses every invitation carries', { required: ['at'] }),
|
|
149
|
+
sweep: rootAsk('every place of the memory this harbor does not name, gone'),
|
|
150
|
+
heard: ownerAsk('a push heard, told to every carrier, so one that collects for this harbor collects'),
|
|
151
|
+
lend: { description: 'an offer from a faculty fulfilling a contract', input: { type: 'object', required: ['contract'] }, for: hosted },
|
|
152
|
+
retract: { description: 'an offer that was not taken', input: { type: 'object', required: ['contract', 'heir'] }, for: hosted },
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
readonly #hosting: Hosting;
|
|
156
|
+
|
|
157
|
+
constructor(stance: Stance) {
|
|
158
|
+
super(stance);
|
|
159
|
+
this.#hosting = (stance as DockStance).ground;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// The second level: every faculty of the box that does not stand yet,
|
|
163
|
+
// each once the registry she names stands, registries first, then
|
|
164
|
+
// memory faculties, then the rest; every route handed to the carrier;
|
|
165
|
+
// then every hosted ward and her ward. Asked once the harbor boots, and
|
|
166
|
+
// again whenever the code that runs moves, so it stands only what does
|
|
167
|
+
// not stand yet, and answers silence where everything already stands.
|
|
168
|
+
async stand(): Promise<JsonObject | undefined> {
|
|
169
|
+
const stood = [...(await this.#standFaculties(registers)), ...(await this.#standFaculties((C) => C.prototype instanceof MemoryFaculty)), ...(await this.#standFaculties(() => true))];
|
|
170
|
+
for (const [pk, at] of Object.entries(this.routes)) this.#hosting.reached(pk, at);
|
|
171
|
+
const wards: string[] = [];
|
|
172
|
+
for (const row of this.hosted) if (await this.#hosting.stand(row)) wards.push(row.ward);
|
|
173
|
+
return stood.length + wards.length > 0 ? { stood, wards } : undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// The absent faculties whose class resolves now and fits, stood, again
|
|
177
|
+
// and again while one more stands, since a registry stood makes the
|
|
178
|
+
// classes named through it resolve.
|
|
179
|
+
async #standFaculties(fits: (C: BeingClass) => boolean): Promise<string[]> {
|
|
180
|
+
const stood: string[] = [];
|
|
181
|
+
for (let more = true; more; ) {
|
|
182
|
+
more = false;
|
|
183
|
+
for (const [key, being] of Object.entries(this.steward.beings())) {
|
|
184
|
+
const C = being.absent ? this.steward.classOf(being.class, being.registry) : undefined;
|
|
185
|
+
if (!C || !fits(C) || this.steward.stand(key) !== 'booted') continue;
|
|
186
|
+
more = true;
|
|
187
|
+
stood.push(key);
|
|
188
|
+
await this.#hosting.rouse(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return stood;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// The census adds what did not stand, for whoever pilots, and whether
|
|
195
|
+
// the harbor lives only as long as a screen.
|
|
196
|
+
override describe(asker: Asker): Blueprint {
|
|
197
|
+
const blueprint = super.describe(asker);
|
|
198
|
+
if (!pilots(asker, this.notes(asker))) return blueprint;
|
|
199
|
+
const notes = blueprint.notes as JsonObject;
|
|
200
|
+
notes.wards = Object.fromEntries(this.hosted.map(({ ward, memory, registry }) => [ward, { ...(memory === undefined ? {} : { memory }), ...(registry === undefined ? {} : { registry }) }]));
|
|
201
|
+
notes.routes = this.routes;
|
|
202
|
+
notes.reach = this.addresses;
|
|
203
|
+
notes.failed = this.#hosting.failures();
|
|
204
|
+
notes.listening = this.#hosting.listening();
|
|
205
|
+
if (this.#hosting.foreground) notes.foreground = true;
|
|
206
|
+
return blueprint;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async heard(): Promise<JsonObject> {
|
|
210
|
+
await this.#hosting.heard();
|
|
211
|
+
return { heard: true };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
get hosted(): Hosted[] {
|
|
215
|
+
return (this.cells.hosted as Hosted[]).map(({ ward, seed, memory, registry }) => ({
|
|
216
|
+
ward,
|
|
217
|
+
seed,
|
|
218
|
+
...(memory === undefined ? {} : { memory }),
|
|
219
|
+
...(registry === undefined ? {} : { registry }),
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Whether a key names a memory faculty the dock opened.
|
|
224
|
+
#memory(key: unknown): key is string {
|
|
225
|
+
return text(key) && this.#fulfilling(MEMORY).includes(key);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// The registry an ask names: none for the catalogue, the key of a
|
|
229
|
+
// registry faculty standing in the box, or no registry at all.
|
|
230
|
+
#registry(named: unknown): { registry: string | undefined } | null {
|
|
231
|
+
if (named === undefined || named === null || named === CATALOGUE) return { registry: undefined };
|
|
232
|
+
if (!text(named)) return null;
|
|
233
|
+
const being = this.steward.beings()[named];
|
|
234
|
+
const C = being && !being.absent ? this.steward.classOf(being.class, being.registry) : undefined;
|
|
235
|
+
return registers(C) ? { registry: named } : null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
get routes(): Record<string, string[]> {
|
|
239
|
+
return Object.fromEntries(Object.entries(this.cells.routes as Record<string, string[]>).map(([pk, at]) => [pk, [...at]]));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Where this harbor is reached, in the order a caller tries it.
|
|
243
|
+
get addresses(): string[] {
|
|
244
|
+
return [...(this.cells.reach as string[])];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
route(args: JsonObject): JsonObject {
|
|
248
|
+
const { ward } = args;
|
|
249
|
+
const at = typeof args.at === 'string' ? [args.at] : args.at;
|
|
250
|
+
if (!text(ward) || (at !== null && !addresses(at)) || !this.#hosting.route(ward, at)) return { error: 'not routed' };
|
|
251
|
+
const routes = this.cells.routes as Record<string, string[]>;
|
|
252
|
+
if (at === null) delete routes[ward];
|
|
253
|
+
else routes[ward] = [...at];
|
|
254
|
+
return { routed: ward };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
reach(args: JsonObject): JsonObject {
|
|
258
|
+
if (!addresses(args.at)) return { error: 'at is a list of addresses' };
|
|
259
|
+
this.cells.reach = [...args.at];
|
|
260
|
+
return { reach: [...args.at] };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// A far ward held at the address named is routed there first, so the
|
|
264
|
+
// take reaches it where its invitation says nothing.
|
|
265
|
+
override async hold(args: JsonObject): Promise<JsonObject> {
|
|
266
|
+
if (args.at !== undefined) {
|
|
267
|
+
if (!addresses([args.at])) return { error: 'at is an address' };
|
|
268
|
+
const ward = readInvitation(args.invitation)?.ward;
|
|
269
|
+
if (ward === undefined) return { error: 'no invitation' };
|
|
270
|
+
const routed = this.route({ ward, at: [args.at] });
|
|
271
|
+
if (routed.error !== undefined) return routed;
|
|
272
|
+
}
|
|
273
|
+
return super.hold(args);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// A route learned from an invitation's `at`, where the root set none,
|
|
277
|
+
// and where the carrier dials one of its addresses.
|
|
278
|
+
async learn(ward: string, at: readonly string[]): Promise<void> {
|
|
279
|
+
const routes = this.cells.routes as Record<string, string[]>;
|
|
280
|
+
if (Object.hasOwn(routes, ward) || !this.#hosting.route(ward, at)) return;
|
|
281
|
+
routes[ward] = [...at];
|
|
282
|
+
await this.#hosting.keep();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// The dock born again of a class, resolved through the catalogue or a
|
|
286
|
+
// registry the catalogue stands, since she stands before any other.
|
|
287
|
+
override become(args: JsonObject): JsonObject {
|
|
288
|
+
if (!text(args.class)) return { error: 'class is text' };
|
|
289
|
+
const through = this.#registry(args.registry);
|
|
290
|
+
if (through === null) return { error: 'no such registry faculty' };
|
|
291
|
+
const { registry } = through;
|
|
292
|
+
if (registry !== undefined && this.steward.beings()[registry]!.registry !== undefined) return { error: 'the dock stands through the catalogue or a registry it stands' };
|
|
293
|
+
const refused = this.steward.become(args.class, registry);
|
|
294
|
+
return refused === null ? { became: args.class } : { error: refused };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// The box ward holds faculties alone, and a faculty stands by `open`,
|
|
298
|
+
// which takes a standing on her.
|
|
299
|
+
override boot(): Promise<JsonObject> {
|
|
300
|
+
return Promise.resolve({ error: 'a faculty is opened, and nothing else stands in the box ward' });
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// A faculty that goes stops listening first, and a memory faculty
|
|
304
|
+
// keeping a ward's place does not go.
|
|
305
|
+
override async unboot(args: JsonObject): Promise<JsonObject> {
|
|
306
|
+
if (this.hosted.some((h) => h.memory !== undefined && h.memory === args.being)) return { error: 'a ward is kept by this memory faculty' };
|
|
307
|
+
if (typeof args.being === 'string') await this.#hosting.lull(args.being);
|
|
308
|
+
return super.unboot(args);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// A faculty of any class the registry named resolves: a kit faculty
|
|
312
|
+
// resolves only where this ground ships it. The catalogue is the core's,
|
|
313
|
+
// and no ask opens one.
|
|
314
|
+
async open(args: JsonObject): Promise<JsonObject> {
|
|
315
|
+
if (!text(args.key) || !text(args.class)) return { error: 'key and class are text' };
|
|
316
|
+
const through = this.#registry(args.registry);
|
|
317
|
+
if (through === null) return { error: 'no such registry faculty' };
|
|
318
|
+
const { registry } = through;
|
|
319
|
+
const C = this.steward.classOf(args.class, registry);
|
|
320
|
+
if (!Faculty.fulfils(C) || catalogues(C)) return { error: 'no such faculty' };
|
|
321
|
+
if ((await this.steward.boot(args.key, args.class, registry)) !== 'booted') return { error: 'not opened' };
|
|
322
|
+
const invitation = await this.steward.invite(args.key, WARD, {});
|
|
323
|
+
if (invitation === null || (await this.stance.standings.take(args.key, invitation)) === null) {
|
|
324
|
+
this.steward.unboot(args.key);
|
|
325
|
+
return { error: 'not opened' };
|
|
326
|
+
}
|
|
327
|
+
await this.#hosting.awaken(args.key);
|
|
328
|
+
return { opened: args.key };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async sweep(): Promise<JsonObject> {
|
|
332
|
+
return { swept: await this.#hosting.sweep() };
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async host(args: JsonObject): Promise<JsonObject> {
|
|
336
|
+
const name = args.ward;
|
|
337
|
+
if (!text(name)) return { error: 'ward is text' };
|
|
338
|
+
if (name === BOX) return { error: 'box is the box ward' };
|
|
339
|
+
if (this.hosted.some((h) => h.ward === name)) return { error: `${name} is hosted already` };
|
|
340
|
+
if (args.seed !== undefined && !text(args.seed)) return { error: 'seed is text' };
|
|
341
|
+
const memory = args.memory ?? undefined;
|
|
342
|
+
if (memory !== undefined && !this.#memory(memory)) return { error: 'no such memory faculty' };
|
|
343
|
+
const through = this.#registry(args.registry);
|
|
344
|
+
if (through === null) return { error: 'no such registry faculty' };
|
|
345
|
+
const { registry } = through;
|
|
346
|
+
const kind = args.class ?? undefined;
|
|
347
|
+
if (kind !== undefined && (!text(kind) || !hostable(this.steward.classOf(kind, registry)))) return { error: 'no such ward class' };
|
|
348
|
+
const invitation = await this.stance.occupants.invite(name, { hosted: true });
|
|
349
|
+
if (invitation === null) return { error: 'not hosted' };
|
|
350
|
+
const seed = await this.#hosting.host(name, invitation, args.seed, memory, kind, registry);
|
|
351
|
+
if (seed === null) {
|
|
352
|
+
this.stance.occupants.remove(name);
|
|
353
|
+
return { error: 'not hosted' };
|
|
354
|
+
}
|
|
355
|
+
(this.cells.hosted as Hosted[]).push({ ward: name, seed, ...(memory === undefined ? {} : { memory }), ...(registry === undefined ? {} : { registry }) });
|
|
356
|
+
return { hosted: name };
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// The place is written where it goes before the dock's cells say so, and
|
|
360
|
+
// forgotten where it was only once they are kept, so a cut at any step
|
|
361
|
+
// leaves the ward whole under the keeper the cells name.
|
|
362
|
+
async move(args: JsonObject): Promise<JsonObject> {
|
|
363
|
+
const rows = this.cells.hosted as Hosted[];
|
|
364
|
+
const row = rows.find((h) => h.ward === args.ward);
|
|
365
|
+
if (!row) return { error: 'no such ward' };
|
|
366
|
+
const to = args.memory ?? undefined;
|
|
367
|
+
if (to !== undefined && !this.#memory(to)) return { error: 'no such memory faculty' };
|
|
368
|
+
const from = row.memory;
|
|
369
|
+
if (from === to) return { error: `${row.ward} is kept there already` };
|
|
370
|
+
const refused = await this.#hosting.move(row.ward, row.seed, from, to);
|
|
371
|
+
if (refused !== null) return { error: refused };
|
|
372
|
+
const set = (memory: string | undefined): void => {
|
|
373
|
+
if (memory === undefined) delete row.memory;
|
|
374
|
+
else row.memory = memory;
|
|
375
|
+
};
|
|
376
|
+
set(to);
|
|
377
|
+
if (!(await this.#hosting.keep())) {
|
|
378
|
+
set(from);
|
|
379
|
+
await this.#hosting.move(row.ward, row.seed, to, from);
|
|
380
|
+
return { error: 'not kept' };
|
|
381
|
+
}
|
|
382
|
+
await this.#hosting.release(row.ward, from);
|
|
383
|
+
return { moved: row.ward, memory: to ?? null };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async lend(args: JsonObject): Promise<JsonObject> {
|
|
387
|
+
if (!text(args.contract)) return { error: 'contract is text' };
|
|
388
|
+
const invitation = await this.offer(args.contract);
|
|
389
|
+
return invitation ? { invitation } : { error: 'nothing lent' };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
async retract(args: JsonObject): Promise<JsonObject> {
|
|
393
|
+
if (!text(args.contract) || !text(args.heir)) return { error: 'contract and heir are text' };
|
|
394
|
+
await this.withdraw(args.contract, args.heir);
|
|
395
|
+
return { retracted: args.heir };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Lender: the first standing faculty that fulfils the contract offers.
|
|
399
|
+
async offer(contract: string): Promise<Invitation | null> {
|
|
400
|
+
for (const key of this.#fulfilling(contract)) {
|
|
401
|
+
const out = await this.stance.standings.get(key)?.ask('offer');
|
|
402
|
+
const invitation = readInvitation((out as { invitation?: unknown } | undefined)?.invitation);
|
|
403
|
+
if (invitation) return invitation;
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async withdraw(contract: string, heir: string): Promise<void> {
|
|
409
|
+
for (const key of this.#fulfilling(contract)) await this.stance.standings.get(key)?.ask('retract', { heir });
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
#fulfilling(contract: string): string[] {
|
|
413
|
+
const beings = this.steward.beings();
|
|
414
|
+
return this.stance.standings.ids().filter((key) => {
|
|
415
|
+
const being = beings[key];
|
|
416
|
+
const C = being && !being.absent ? this.steward.classOf(being.class, being.registry) : undefined;
|
|
417
|
+
return Faculty.fulfils(C) && Faculty.contracts(C).includes(contract);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}
|