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
package/src/ward/ward-being.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The ward-being: the first being of every ward, the ward itself. Her asks
|
|
3
|
-
// are the root's, shown and answered to `OWNER` alone.
|
|
4
|
-
import { Being, isSilence, isWord, KIT, OWNER, told, type Answer, type Asker, type AskSpec, type BeingClass, type Blueprint, type Invitation, type JsonObject, type Stance } from '../being/index.ts';
|
|
5
|
-
|
|
6
|
-
// What the ward lends its ward-being, and no other being.
|
|
7
|
-
export interface Steward {
|
|
8
|
-
pk(): string;
|
|
9
|
-
classOf(name: string): BeingClass | undefined;
|
|
10
|
-
beings(): Record<string, { class: string; public: boolean; absent: boolean }>;
|
|
11
|
-
boot(key: string, className: string): Promise<'booted' | 'key taken' | 'no such class' | 'threw at birth'>;
|
|
12
|
-
unboot(key: string): boolean;
|
|
13
|
-
publish(key: string | null): boolean;
|
|
14
|
-
invite(being: string, id: string, notes: JsonObject): Promise<Invitation | null>;
|
|
15
|
-
ask(being: string | null, method: string | undefined, args: JsonObject): Promise<Answer>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type WardBeingStance = Stance & { readonly steward: Steward };
|
|
19
|
-
|
|
20
|
-
// Whoever pilots a ward: the root, holding its unsealed ask, or an owner,
|
|
21
|
-
// an occupant of the ward-being the root invited as one.
|
|
22
|
-
export const pilots = (asker: Asker, notes: JsonObject | undefined): boolean => asker.id === OWNER || notes?.owner === true;
|
|
23
|
-
|
|
24
|
-
// An ask whoever pilots the ward may make.
|
|
25
|
-
export const ownerAsk = (description: string, input: JsonObject = {}): AskSpec => ({ description, input: { type: 'object', ...input }, for: pilots });
|
|
26
|
-
|
|
27
|
-
// An ask the root alone may make, so a carried key pilots but never hands
|
|
28
|
-
// piloting on.
|
|
29
|
-
export const rootAsk = (description: string, input: JsonObject = {}): AskSpec => ({ description, input: { type: 'object', ...input }, for: (asker: Asker) => asker.id === OWNER });
|
|
30
|
-
// The one kit kind the root boots: every other kit class stands where the
|
|
31
|
-
// kit puts it.
|
|
32
|
-
export const PILOT = 'org.nervur.pilot';
|
|
33
|
-
|
|
34
|
-
const text = (v: unknown): v is string => typeof v === 'string';
|
|
35
|
-
const object = (v: unknown): v is JsonObject => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
36
|
-
|
|
37
|
-
export class WardBeing extends Being {
|
|
38
|
-
static override readonly kind: string = 'org.nervur.ward-being';
|
|
39
|
-
static override asks: Record<string, AskSpec> = {
|
|
40
|
-
boot: ownerAsk('a new being of this ward', { required: ['key', 'class'] }),
|
|
41
|
-
unboot: ownerAsk('a being out, with every relation she holds', { required: ['being'] }),
|
|
42
|
-
public: ownerAsk('the being a stranger reaches, or none', { required: ['key'] }),
|
|
43
|
-
invite: ownerAsk('an invitation on a being of this ward', { required: ['being', 'id'] }),
|
|
44
|
-
ask: ownerAsk('a being of this ward, asked as the owner; with no being, the public being asked as nobody'),
|
|
45
|
-
own: rootAsk('an invitation for an owner of this ward, under an id', { required: ['id'] }),
|
|
46
|
-
disown: rootAsk('an owner no more', { required: ['id'] }),
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
readonly steward: Steward;
|
|
50
|
-
|
|
51
|
-
constructor(stance: WardBeingStance) {
|
|
52
|
-
super(stance);
|
|
53
|
-
this.steward = stance.steward;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
override describe(asker: Asker): Blueprint {
|
|
57
|
-
const { asks } = super.describe(asker);
|
|
58
|
-
return { asks, notes: pilots(asker, this.notes(asker)) ? { pk: this.steward.pk(), beings: this.steward.beings() } : {} };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async own(args: JsonObject): Promise<JsonObject> {
|
|
62
|
-
if (!text(args.id)) return { error: 'id is text' };
|
|
63
|
-
return (await this.stance.occupants.invite(args.id, { owner: true })) ?? { error: 'id taken' };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
disown(args: JsonObject): JsonObject {
|
|
67
|
-
if (!text(args.id) || this.stance.occupants.notes(args.id)?.owner !== true) return { error: 'no such owner' };
|
|
68
|
-
this.stance.occupants.remove(args.id);
|
|
69
|
-
return { disowned: args.id };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async boot(args: JsonObject): Promise<JsonObject> {
|
|
73
|
-
if (!text(args.key) || !text(args.class)) return { error: 'key and class are text' };
|
|
74
|
-
if (args.class.startsWith(KIT) && args.class !== PILOT) return { error: 'no such class' };
|
|
75
|
-
const out = await this.steward.boot(args.key, args.class);
|
|
76
|
-
return out === 'booted' ? { booted: args.key } : { error: out };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
unboot(args: JsonObject): JsonObject | Promise<JsonObject> {
|
|
80
|
-
return text(args.being) && this.steward.unboot(args.being) ? { unbooted: args.being } : { error: 'no such being' };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public(args: JsonObject): JsonObject {
|
|
84
|
-
if (args.key !== null && !text(args.key)) return { error: 'key is text or null' };
|
|
85
|
-
return this.steward.publish(args.key) ? { public: args.key } : { error: 'no such being' };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
async invite(args: JsonObject): Promise<JsonObject> {
|
|
89
|
-
if (!text(args.being) || !text(args.id) || (args.notes !== undefined && !object(args.notes))) return { error: 'being and id are text, notes an object' };
|
|
90
|
-
const invitation = await this.steward.invite(args.being, args.id, args.notes ?? {});
|
|
91
|
-
return invitation ?? { error: 'not invited' };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async ask(args: JsonObject): Promise<JsonObject> {
|
|
95
|
-
if ((args.being !== undefined && !text(args.being)) || (args.method !== undefined && !text(args.method)) || (args.args !== undefined && !object(args.args))) {
|
|
96
|
-
return { error: 'being and method are text, args an object' };
|
|
97
|
-
}
|
|
98
|
-
const out = await this.steward.ask(args.being ?? null, args.method, args.args ?? {});
|
|
99
|
-
if (isSilence(out)) return { error: 'silence' };
|
|
100
|
-
if (isWord(out)) return { error: told(out) as string };
|
|
101
|
-
return { answer: out };
|
|
102
|
-
}
|
|
103
|
-
}
|
package/src/ward/ward.ts
DELETED
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The ward: one door, one partition, and the beings behind the door. It
|
|
3
|
-
// unpacks from its seed, its memory and a catalogue of classes, the
|
|
4
|
-
// ward-being first and every other being from her own row, and it stands
|
|
5
|
-
// what is behind its door for `quo/`.
|
|
6
|
-
import { readValue, writeValue } from '../crypto/index.ts';
|
|
7
|
-
import { Door, readInvitation, WardKey, type Behind, type Choice, type Invitation, type Payload } from '../quo/index.ts';
|
|
8
|
-
import type { Carrier, Clock, Entropy, Rows } from '../contract/index.ts';
|
|
9
|
-
import { digest, isSilence, isWord, kindOf, OWNER, silence, WARD, word, type Answer, type Asker, type BeingClass, type BeingLike, type JsonObject, type Reply } from '../being/index.ts';
|
|
10
|
-
import { Partition, PartitionRelations, type BeingRow } from './partition.ts';
|
|
11
|
-
import { DEPTH, WardStance, type Inside } from './stance.ts';
|
|
12
|
-
import { WardBeing, type Steward, type WardBeingStance } from './ward-being.ts';
|
|
13
|
-
|
|
14
|
-
// Where a ward finds a class by the kind its row keeps.
|
|
15
|
-
export interface Catalogue {
|
|
16
|
-
classOf(kind: string): BeingClass | undefined;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type WardParts = {
|
|
20
|
-
readonly seed: Uint8Array | string;
|
|
21
|
-
readonly memory: Rows;
|
|
22
|
-
readonly catalogue: Catalogue;
|
|
23
|
-
readonly entropy: Entropy;
|
|
24
|
-
readonly clock: Clock;
|
|
25
|
-
readonly carrier: Carrier;
|
|
26
|
-
// The ward-being: `WardBeing`, or a being that extends it.
|
|
27
|
-
readonly root?: (stance: WardBeingStance) => WardBeing;
|
|
28
|
-
// An invitation on the dock, taken by the ward-being under `dock` when
|
|
29
|
-
// she holds no such standing yet.
|
|
30
|
-
readonly dock?: Invitation;
|
|
31
|
-
// Where the ward is reached, and where a ward it takes an invitation of
|
|
32
|
-
// is reached. A ward alone is reached nowhere and learns nothing.
|
|
33
|
-
readonly routes?: Routes;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export interface Routes {
|
|
37
|
-
reach(): readonly string[];
|
|
38
|
-
learn(ward: string, at: readonly string[]): Promise<void>;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// The standing every hosted ward's ward-being holds on the dock.
|
|
42
|
-
export const DOCK = 'dock';
|
|
43
|
-
|
|
44
|
-
// A ward-being that lends to her own ward's beings, as the dock does.
|
|
45
|
-
export interface Lender {
|
|
46
|
-
offer(contract: string): Promise<Invitation | null>;
|
|
47
|
-
withdraw(contract: string, heir: string): Promise<void>;
|
|
48
|
-
}
|
|
49
|
-
const lends = (being: unknown): being is Lender => typeof (being as Partial<Lender>).offer === 'function';
|
|
50
|
-
|
|
51
|
-
type Birth = 'booted' | 'key taken' | 'no such class' | 'threw at birth';
|
|
52
|
-
type Resident = { being: BeingLike; row: BeingRow; stance: WardStance };
|
|
53
|
-
|
|
54
|
-
class RootStance extends WardStance implements WardBeingStance {
|
|
55
|
-
readonly steward: Steward;
|
|
56
|
-
constructor(inside: Inside, row: BeingRow, steward: Steward) {
|
|
57
|
-
super(inside, WARD, row);
|
|
58
|
-
this.steward = steward;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export class Ward implements Behind, Inside {
|
|
63
|
-
readonly key: WardKey;
|
|
64
|
-
readonly partition: Partition;
|
|
65
|
-
readonly door: Door;
|
|
66
|
-
readonly clock: Clock;
|
|
67
|
-
readonly #parts: WardParts;
|
|
68
|
-
readonly #residents = new Map<string, Resident>();
|
|
69
|
-
readonly #birthing = new Set<string>();
|
|
70
|
-
|
|
71
|
-
private constructor(parts: WardParts, key: WardKey) {
|
|
72
|
-
this.#parts = parts;
|
|
73
|
-
this.key = key;
|
|
74
|
-
this.clock = parts.clock;
|
|
75
|
-
this.partition = new Partition(parts.memory);
|
|
76
|
-
this.door = new Door(key, new PartitionRelations(this.partition), this, parts.entropy.drawer);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// The ward-being first, then every being her row names. A class the
|
|
80
|
-
// catalogue lacks, or one that throws, leaves that being absent and her
|
|
81
|
-
// row as it was.
|
|
82
|
-
static async unpack(parts: WardParts): Promise<Ward> {
|
|
83
|
-
const ward = new Ward(parts, await WardKey.from(parts.seed));
|
|
84
|
-
if (!ward.partition.being(WARD)) {
|
|
85
|
-
ward.partition.beings[WARD] = { class: '', cells: {}, occupants: {}, standings: {} };
|
|
86
|
-
ward.partition.told(WARD);
|
|
87
|
-
ward.partition.toldHead();
|
|
88
|
-
}
|
|
89
|
-
const own = ward.partition.being(WARD)!;
|
|
90
|
-
const stance = new RootStance(ward, own, ward.#steward);
|
|
91
|
-
const being = parts.root ? parts.root(stance) : new WardBeing(stance);
|
|
92
|
-
own.class = kindOf(being.constructor);
|
|
93
|
-
ward.#residents.set(WARD, { being, row: own, stance });
|
|
94
|
-
// The standing on the dock is kept at once: its heir is spent, so a
|
|
95
|
-
// restart before the ward's first keep would find no way back.
|
|
96
|
-
if (parts.dock && !Object.hasOwn(own.standings, DOCK) && (await stance.standings.take(DOCK, parts.dock)) !== null && !(await ward.partition.kept())) {
|
|
97
|
-
throw new Error('the standing on the dock was not kept');
|
|
98
|
-
}
|
|
99
|
-
for (const [key, row] of Object.entries(ward.partition.beings)) {
|
|
100
|
-
const C = key === WARD ? undefined : parts.catalogue.classOf(row.class);
|
|
101
|
-
if (C) ward.#bear(key, row, C);
|
|
102
|
-
}
|
|
103
|
-
return ward;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get pk(): string {
|
|
107
|
-
return this.key.pk;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
get draw() {
|
|
111
|
-
return this.#parts.entropy.drawer;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
get wardBeing(): WardBeing {
|
|
115
|
-
return this.#residents.get(WARD)!.being as WardBeing;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// The being standing under a key, for the harbor's own faculties.
|
|
119
|
-
being(key: string): BeingLike | undefined {
|
|
120
|
-
return this.#residents.get(key)?.being;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Every being her row names, of the class the catalogue now resolves for
|
|
124
|
-
// her kind: an absent being is born, and one whose class a module
|
|
125
|
-
// replaced is born again of the new class on the stance she holds, so
|
|
126
|
-
// her relations and their lanes stay hers. A new class that throws at
|
|
127
|
-
// birth leaves her as she was.
|
|
128
|
-
bearAnew(): void {
|
|
129
|
-
for (const [key, row] of Object.entries(this.partition.beings)) {
|
|
130
|
-
const C = key === WARD ? undefined : this.#parts.catalogue.classOf(row.class);
|
|
131
|
-
const resident = this.#residents.get(key);
|
|
132
|
-
if (!C || resident?.being.constructor === C) continue;
|
|
133
|
-
if (!resident) {
|
|
134
|
-
this.#bear(key, row, C);
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
resident.being = new C(resident.stance);
|
|
139
|
-
} catch {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// The unsealed ask: the ward-being, asked by whoever holds this ward.
|
|
146
|
-
// It reaches every being of the ward through the ward-being, so every
|
|
147
|
-
// row is put back where the memory refuses.
|
|
148
|
-
async root(method?: string, args: JsonObject = {}): Promise<Answer> {
|
|
149
|
-
return this.#kept(Object.keys(this.partition.beings), () => this.#answer(WARD, { id: OWNER }, method, args));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// An answer, kept. Where the memory refuses, what the beings wrote is put
|
|
153
|
-
// back and the answer is silence. What their relations stand on is not
|
|
154
|
-
// put back: a relation's keys move only as far as its standing follows.
|
|
155
|
-
async #kept(keys: readonly string[], work: () => Promise<Answer>): Promise<Answer> {
|
|
156
|
-
const before = keys.flatMap((key): [string, JsonObject, string][] => {
|
|
157
|
-
const row = this.partition.being(key);
|
|
158
|
-
return row ? [[key, row.cells, JSON.stringify(row.cells)]] : [];
|
|
159
|
-
});
|
|
160
|
-
const out = await work();
|
|
161
|
-
if (await this.partition.kept()) return out;
|
|
162
|
-
for (const [key, cells, was] of before) {
|
|
163
|
-
if (JSON.stringify(cells) === was) continue;
|
|
164
|
-
for (const k of Object.keys(cells)) delete cells[k];
|
|
165
|
-
for (const [k, v] of Object.entries(JSON.parse(was) as JsonObject)) Object.defineProperty(cells, k, { value: v, enumerable: true, writable: true, configurable: true });
|
|
166
|
-
this.partition.told(key);
|
|
167
|
-
}
|
|
168
|
-
return silence;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Behind: the zero head reaches the public being, an heir the being that
|
|
172
|
-
// invited it.
|
|
173
|
-
get zero(): boolean {
|
|
174
|
-
const key = this.partition.head.public;
|
|
175
|
-
return key !== null && this.#residents.has(key);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async answer(heir: string | null, p: Payload): Promise<Choice> {
|
|
179
|
-
const bound = heir === null ? undefined : this.partition.head.bind[heir];
|
|
180
|
-
const key = heir === null ? this.partition.head.public : bound?.being;
|
|
181
|
-
const asker: Asker = bound ? { id: bound.id } : {};
|
|
182
|
-
const args = p.args === undefined ? {} : readValue(p.args, DEPTH + 1);
|
|
183
|
-
if (key === null || key === undefined || typeof args !== 'object' || args === null || Array.isArray(args)) return { silence: true };
|
|
184
|
-
const out = await this.#kept([key], () => this.#answer(key, asker, p.method, args));
|
|
185
|
-
const object = isSilence(out) || isWord(out) ? undefined : writeValue(out, DEPTH);
|
|
186
|
-
if (object === undefined) return { silence: true };
|
|
187
|
-
const being = this.#residents.get(key)?.being;
|
|
188
|
-
const seen = p.method === undefined || !being?.describe ? null : await digest(being.describe(asker));
|
|
189
|
-
return { object, seen };
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Every path that reaches a being's answer. A throw, a word out of her,
|
|
193
|
-
// or nothing at all is silence.
|
|
194
|
-
async #answer(key: string, asker: Asker, method: string | undefined, args: JsonObject): Promise<Answer> {
|
|
195
|
-
const resident = this.#residents.get(key);
|
|
196
|
-
if (!resident) return silence;
|
|
197
|
-
let out: Reply;
|
|
198
|
-
try {
|
|
199
|
-
out = await resident.being.answer(asker, method, args);
|
|
200
|
-
} catch {
|
|
201
|
-
return silence;
|
|
202
|
-
}
|
|
203
|
-
return out === undefined || isWord(out) ? silence : out;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Inside: what every stance of this ward stands on.
|
|
207
|
-
|
|
208
|
-
// One path through a door for every ask, this ward's own included.
|
|
209
|
-
async send(pk: string, bytes: Uint8Array): Promise<Uint8Array | null> {
|
|
210
|
-
if (pk === this.pk) return (await this.door.arrive(bytes)).bytes;
|
|
211
|
-
return this.#parts.carrier.carry(pk, bytes);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// A lend: the ward-being lends herself, as the dock does, or asks the dock
|
|
215
|
-
// through her standing.
|
|
216
|
-
async offer(contract: string): Promise<Invitation | null> {
|
|
217
|
-
const own = this.#residents.get(WARD)!;
|
|
218
|
-
if (lends(own.being)) return own.being.offer(contract);
|
|
219
|
-
const out = await own.stance.standings.get(DOCK)?.ask('lend', { contract });
|
|
220
|
-
return readInvitation((out as { invitation?: unknown } | undefined)?.invitation);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async retract(contract: string, heir: string): Promise<void> {
|
|
224
|
-
const own = this.#residents.get(WARD)!;
|
|
225
|
-
if (lends(own.being)) return own.being.withdraw(contract, heir);
|
|
226
|
-
await own.stance.standings.get(DOCK)?.ask('retract', { contract, heir });
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
reach(): readonly string[] {
|
|
230
|
-
return this.#parts.routes?.reach() ?? [];
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
learn(ward: string, at: readonly string[]): Promise<void> {
|
|
234
|
-
return this.#parts.routes?.learn(ward, at) ?? Promise.resolve();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
live(key: string, row: BeingRow): boolean {
|
|
238
|
-
return this.#residents.get(key)?.row === row;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// A being boots another of this ward. With an id, the new being invites
|
|
242
|
-
// her maker under the maker's key, and the maker takes it under id; a
|
|
243
|
-
// relation that could not be made unmakes the new being.
|
|
244
|
-
async boot(maker: string, className: string, key: string, id?: string): Promise<string | null> {
|
|
245
|
-
if ((await this.#make(key, className)) !== 'booted') return null;
|
|
246
|
-
if (id === undefined) return key;
|
|
247
|
-
const invitation = await this.#residents.get(key)!.stance.occupants.invite(maker);
|
|
248
|
-
const taken = invitation ? await this.#residents.get(maker)?.stance.standings.take(id, invitation) : null;
|
|
249
|
-
if (taken) return key;
|
|
250
|
-
this.#unboot(key);
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
async #make(key: string, className: string): Promise<Birth> {
|
|
255
|
-
if (key === '' || key === WARD || this.partition.being(key) || this.#birthing.has(key)) return 'key taken';
|
|
256
|
-
const C = this.#parts.catalogue.classOf(className);
|
|
257
|
-
if (!C) return 'no such class';
|
|
258
|
-
this.#birthing.add(key);
|
|
259
|
-
try {
|
|
260
|
-
const row: BeingRow = { class: className, cells: {}, occupants: {}, standings: {} };
|
|
261
|
-
this.partition.beings[key] = row;
|
|
262
|
-
if (!this.#bear(key, row, C)) {
|
|
263
|
-
delete this.partition.beings[key];
|
|
264
|
-
return 'threw at birth';
|
|
265
|
-
}
|
|
266
|
-
this.partition.told(key);
|
|
267
|
-
return 'booted';
|
|
268
|
-
} finally {
|
|
269
|
-
this.#birthing.delete(key);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
#bear(key: string, row: BeingRow, C: BeingClass): boolean {
|
|
274
|
-
const stance = new WardStance(this, key, row);
|
|
275
|
-
try {
|
|
276
|
-
this.#residents.set(key, { being: new C(stance), row, stance });
|
|
277
|
-
return true;
|
|
278
|
-
} catch {
|
|
279
|
-
this.#residents.delete(key);
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
#unboot(key: string): boolean {
|
|
285
|
-
const row = key === WARD ? undefined : this.partition.being(key);
|
|
286
|
-
if (!row) return false;
|
|
287
|
-
for (const { heir } of Object.values(row.occupants)) {
|
|
288
|
-
this.door.remove(heir);
|
|
289
|
-
delete this.partition.head.bind[heir];
|
|
290
|
-
}
|
|
291
|
-
if (this.partition.head.public === key) this.partition.head.public = null;
|
|
292
|
-
delete this.partition.beings[key];
|
|
293
|
-
this.#residents.delete(key);
|
|
294
|
-
this.partition.toldHead();
|
|
295
|
-
this.partition.told(key);
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// What the ward-being asks of her ward.
|
|
300
|
-
readonly #steward: Steward = {
|
|
301
|
-
pk: () => this.pk,
|
|
302
|
-
classOf: (name) => this.#parts.catalogue.classOf(name),
|
|
303
|
-
beings: () => {
|
|
304
|
-
const out: ReturnType<Steward['beings']> = {};
|
|
305
|
-
for (const [key, row] of Object.entries(this.partition.beings)) {
|
|
306
|
-
if (key !== WARD) out[key] = { class: row.class, public: this.partition.head.public === key, absent: !this.#residents.has(key) };
|
|
307
|
-
}
|
|
308
|
-
return out;
|
|
309
|
-
},
|
|
310
|
-
boot: (key, className) => this.#make(key, className),
|
|
311
|
-
unboot: (key) => this.#unboot(key),
|
|
312
|
-
publish: (key) => {
|
|
313
|
-
if (key !== null && (key === WARD || !this.partition.being(key))) return false;
|
|
314
|
-
this.partition.head.public = key;
|
|
315
|
-
this.partition.toldHead();
|
|
316
|
-
return true;
|
|
317
|
-
},
|
|
318
|
-
invite: (being, id, notes): Promise<Invitation | null> => {
|
|
319
|
-
const resident = being === WARD ? undefined : this.#residents.get(being);
|
|
320
|
-
return resident ? resident.stance.occupants.invite(id, notes) : Promise.resolve(null);
|
|
321
|
-
},
|
|
322
|
-
ask: (being, method, args) => {
|
|
323
|
-
const key = being ?? this.partition.head.public;
|
|
324
|
-
if (key === null || key === WARD) return Promise.resolve(word('unreached'));
|
|
325
|
-
return this.#answer(key, being === null ? {} : { id: OWNER }, method, args);
|
|
326
|
-
},
|
|
327
|
-
};
|
|
328
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|