nervur 0.19.2 → 0.20.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 +66 -101
- package/dist/being/being.d.ts +7 -15
- package/dist/being/being.js +16 -67
- package/dist/being/digest.d.ts +1 -1
- package/dist/being/digest.js +7 -27
- package/dist/being/faculty.d.ts +9 -0
- package/dist/being/faculty.js +68 -0
- package/dist/being/index.d.ts +4 -5
- package/dist/being/index.js +5 -5
- package/dist/being/types.d.ts +35 -62
- package/dist/being/types.js +3 -57
- package/dist/being/words.d.ts +13 -0
- package/dist/being/words.js +14 -0
- package/dist/contract/index.d.ts +26 -0
- package/dist/contract/index.js +19 -0
- package/dist/crypto/aes.d.ts +3 -0
- package/dist/crypto/aes.js +24 -0
- package/dist/crypto/bytes.d.ts +6 -0
- package/dist/crypto/bytes.js +33 -0
- package/dist/crypto/ed25519.d.ts +3 -0
- package/dist/crypto/ed25519.js +85 -0
- package/dist/crypto/hash.d.ts +2 -0
- package/dist/crypto/hash.js +11 -0
- package/dist/crypto/index.d.ts +7 -0
- package/dist/crypto/index.js +10 -0
- package/dist/crypto/json.d.ts +8 -0
- package/dist/crypto/json.js +250 -0
- package/dist/crypto/mlkem.d.ts +12 -0
- package/dist/crypto/mlkem.js +36 -0
- package/dist/crypto/subtle.d.ts +10 -0
- package/dist/crypto/subtle.js +29 -0
- package/dist/crypto/x25519.d.ts +2 -0
- package/dist/crypto/x25519.js +21 -0
- package/dist/folder/index.d.ts +13 -0
- package/dist/folder/index.js +125 -0
- package/dist/harbor/dock.d.ts +19 -0
- package/dist/harbor/dock.js +92 -0
- package/dist/harbor/harbor.d.ts +22 -0
- package/dist/harbor/harbor.js +84 -0
- package/dist/harbor/index.d.ts +4 -10
- package/dist/harbor/index.js +5 -18
- package/dist/harbor/registry.d.ts +7 -0
- package/dist/harbor/registry.js +13 -0
- package/dist/harbor/terrain.d.ts +8 -0
- package/dist/harbor/terrain.js +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +14 -0
- package/dist/pointer/bodies.d.ts +20 -0
- package/dist/pointer/bodies.js +45 -0
- package/dist/pointer/index.d.ts +2 -0
- package/dist/pointer/index.js +4 -0
- package/dist/pointer/world.d.ts +34 -0
- package/dist/pointer/world.js +76 -0
- package/dist/quo/door.d.ts +34 -0
- package/dist/quo/door.js +172 -0
- package/dist/quo/index.d.ts +8 -0
- package/dist/quo/index.js +11 -0
- package/dist/quo/invitation.d.ts +7 -0
- package/dist/quo/invitation.js +15 -0
- package/dist/quo/keys.d.ts +40 -0
- package/dist/quo/keys.js +79 -0
- package/dist/quo/payload.d.ts +15 -0
- package/dist/quo/payload.js +55 -0
- package/dist/quo/relations.d.ts +40 -0
- package/dist/quo/relations.js +33 -0
- package/dist/quo/reply.d.ts +13 -0
- package/dist/quo/reply.js +35 -0
- package/dist/quo/seal.d.ts +42 -0
- package/dist/quo/seal.js +78 -0
- package/dist/quo/standing.d.ts +39 -0
- package/dist/quo/standing.js +90 -0
- package/dist/ward/allowance.d.ts +13 -9
- package/dist/ward/allowance.js +28 -67
- package/dist/ward/cells.d.ts +6 -6
- package/dist/ward/cells.js +67 -179
- package/dist/ward/index.d.ts +5 -10
- package/dist/ward/index.js +6 -13
- package/dist/ward/partition.d.ts +44 -60
- package/dist/ward/partition.js +56 -285
- package/dist/ward/stance.d.ts +29 -20
- package/dist/ward/stance.js +173 -406
- package/dist/ward/ward-being.d.ts +33 -0
- package/dist/ward/ward-being.js +76 -0
- package/dist/ward/ward.d.ts +43 -11
- package/dist/ward/ward.js +215 -363
- package/package.json +19 -33
- package/src/being/being.ts +31 -78
- package/src/being/digest.ts +7 -35
- package/src/being/faculty.ts +66 -0
- package/src/being/index.ts +5 -6
- package/src/being/types.ts +47 -145
- package/src/being/words.ts +31 -0
- package/src/contract/index.ts +44 -0
- package/src/crypto/aes.ts +26 -0
- package/src/crypto/bytes.ts +37 -0
- package/src/crypto/ed25519.ts +84 -0
- package/src/crypto/hash.ts +14 -0
- package/src/crypto/index.ts +10 -0
- package/src/crypto/json.ts +241 -0
- package/src/crypto/mlkem.ts +38 -0
- package/src/crypto/subtle.ts +33 -0
- package/src/crypto/x25519.ts +21 -0
- package/src/folder/index.ts +134 -0
- package/src/harbor/dock.ts +101 -0
- package/src/harbor/harbor.ts +105 -0
- package/src/harbor/index.ts +5 -19
- package/src/harbor/registry.ts +20 -0
- package/src/harbor/terrain.ts +13 -0
- package/src/index.ts +20 -0
- package/src/pointer/bodies.ts +47 -0
- package/src/pointer/index.ts +4 -0
- package/src/pointer/world.ts +91 -0
- package/src/quo/door.ts +178 -0
- package/src/quo/index.ts +11 -0
- package/src/quo/invitation.ts +15 -0
- package/src/quo/keys.ts +91 -0
- package/src/quo/payload.ts +61 -0
- package/src/quo/relations.ts +62 -0
- package/src/quo/reply.ts +38 -0
- package/src/quo/seal.ts +101 -0
- package/src/quo/standing.ts +111 -0
- package/src/stand/main.ts +19 -0
- package/src/stand/stand.ts +178 -0
- package/src/ward/allowance.ts +37 -75
- package/src/ward/cells.ts +63 -176
- package/src/ward/index.ts +6 -17
- package/src/ward/partition.ts +86 -326
- package/src/ward/stance.ts +185 -420
- package/src/ward/ward-being.ts +97 -0
- package/src/ward/ward.ts +229 -363
- package/dist/being/lent.d.ts +0 -32
- package/dist/being/lent.js +0 -72
- package/dist/being/silence.d.ts +0 -12
- package/dist/being/silence.js +0 -41
- package/dist/conformance/assert.d.ts +0 -11
- package/dist/conformance/assert.js +0 -106
- package/dist/conformance/beings.d.ts +0 -199
- package/dist/conformance/beings.js +0 -188
- package/dist/conformance/estate.d.ts +0 -5
- package/dist/conformance/estate.js +0 -388
- package/dist/conformance/index.d.ts +0 -80
- package/dist/conformance/index.js +0 -819
- package/dist/conformance/reach.d.ts +0 -10
- package/dist/conformance/reach.js +0 -72
- package/dist/conformance/store.d.ts +0 -5
- package/dist/conformance/store.js +0 -113
- package/dist/harbor/box.d.ts +0 -121
- package/dist/harbor/box.js +0 -121
- package/dist/harbor/core.d.ts +0 -55
- package/dist/harbor/core.js +0 -662
- package/dist/harbor/dial.d.ts +0 -9
- package/dist/harbor/dial.js +0 -81
- package/dist/harbor/memory.d.ts +0 -29
- package/dist/harbor/memory.js +0 -104
- package/dist/harbor/reach.d.ts +0 -36
- package/dist/harbor/reach.js +0 -199
- package/dist/harbor/store.d.ts +0 -35
- package/dist/harbor/store.js +0 -62
- package/dist/vector/cases.d.ts +0 -42
- package/dist/vector/cases.js +0 -223
- package/dist/vector/index.d.ts +0 -6
- package/dist/vector/index.js +0 -8
- package/dist/vector/stand.d.ts +0 -9
- package/dist/vector/stand.js +0 -77
- package/dist/vector/world.d.ts +0 -144
- package/dist/vector/world.js +0 -209
- package/dist/ward/arithmetic.d.ts +0 -31
- package/dist/ward/arithmetic.js +0 -249
- package/dist/ward/door.d.ts +0 -18
- package/dist/ward/door.js +0 -186
- package/dist/ward/ground.d.ts +0 -29
- package/dist/ward/ground.js +0 -56
- package/dist/ward/heirs.d.ts +0 -13
- package/dist/ward/heirs.js +0 -117
- package/dist/ward/json.d.ts +0 -2
- package/dist/ward/json.js +0 -163
- package/dist/ward/owner.d.ts +0 -13
- package/dist/ward/owner.js +0 -220
- package/dist/ward/seal.d.ts +0 -52
- package/dist/ward/seal.js +0 -150
- package/src/being/lent.ts +0 -72
- package/src/being/silence.ts +0 -46
- package/src/conformance/assert.ts +0 -100
- package/src/conformance/beings.ts +0 -188
- package/src/conformance/estate.ts +0 -412
- package/src/conformance/index.ts +0 -965
- package/src/conformance/reach.ts +0 -83
- package/src/conformance/store.ts +0 -125
- package/src/harbor/box.ts +0 -131
- package/src/harbor/core.ts +0 -699
- package/src/harbor/dial.ts +0 -112
- package/src/harbor/memory.ts +0 -123
- package/src/harbor/reach.ts +0 -221
- package/src/harbor/store.ts +0 -91
- package/src/vector/cases.ts +0 -257
- package/src/vector/index.ts +0 -11
- package/src/vector/stand.ts +0 -76
- package/src/vector/world.ts +0 -232
- package/src/ward/arithmetic.ts +0 -251
- package/src/ward/door.ts +0 -186
- package/src/ward/ground.ts +0 -142
- package/src/ward/heirs.ts +0 -116
- package/src/ward/json.ts +0 -144
- package/src/ward/owner.ts +0 -214
- package/src/ward/seal.ts +0 -178
package/dist/ward/index.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
5
|
-
export {
|
|
6
|
-
export type { AskPayload, ReplyPayload } from './seal.ts';
|
|
7
|
-
export * as seal from './seal.ts';
|
|
8
|
-
export * as arithmetic from './arithmetic.ts';
|
|
9
|
-
export { allow, spent, DEFAULT, CEILING } from './allowance.ts';
|
|
10
|
-
export type { Allowance } from './allowance.ts';
|
|
1
|
+
export { allow, CEILING, DEFAULT } from './allowance.ts';
|
|
2
|
+
export { HEAD_ROW, Partition, type BeingRow, type Head, type StandingRow } from './partition.ts';
|
|
3
|
+
export { DEPTH } from './stance.ts';
|
|
4
|
+
export { DOCK, Ward, type Catalogue, type Lender, type WardParts } from './ward.ts';
|
|
5
|
+
export { ownerAsk, pilots, WardBeing, type Steward, type WardBeingStance } from './ward-being.ts';
|
package/dist/ward/index.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
//
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
// The seal and the arithmetic, for a kit in another language to check its
|
|
9
|
-
// bytes against, and for tests that speak to a door directly.
|
|
10
|
-
export * as seal from './seal.js';
|
|
11
|
-
export * as arithmetic from './arithmetic.js';
|
|
12
|
-
// The allowance every ask carries, for a kit in another language and for
|
|
13
|
-
// tests that speak to a door directly.
|
|
14
|
-
export { allow, spent, DEFAULT, CEILING } from './allowance.js';
|
|
2
|
+
// The ward: its partition, its stances, its ward-being, and the ward.
|
|
3
|
+
export { allow, CEILING, DEFAULT } from './allowance.js';
|
|
4
|
+
export { HEAD_ROW, Partition } from './partition.js';
|
|
5
|
+
export { DEPTH } from './stance.js';
|
|
6
|
+
export { DOCK, Ward } from './ward.js';
|
|
7
|
+
export { ownerAsk, pilots, WardBeing } from './ward-being.js';
|
package/dist/ward/partition.d.ts
CHANGED
|
@@ -1,65 +1,49 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
seq: number;
|
|
14
|
-
reply: string;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
export type StandingKeys = {
|
|
18
|
-
ward: string;
|
|
19
|
-
heir: string | null;
|
|
20
|
-
current: string;
|
|
21
|
-
next: string | null;
|
|
22
|
-
seq: number;
|
|
23
|
-
};
|
|
24
|
-
export type Bind = {
|
|
25
|
-
standings: Record<string, StandingKeys>;
|
|
26
|
-
occupants: Record<string, string>;
|
|
27
|
-
knocks: Record<string, {
|
|
28
|
-
current: string;
|
|
29
|
-
next: string | null;
|
|
30
|
-
spoke: boolean;
|
|
31
|
-
sent: boolean;
|
|
32
|
-
seq: number;
|
|
1
|
+
import type { Lock } from '../crypto/index.ts';
|
|
2
|
+
import { type HeirRecord, type Invitation, type KeptLock, type Relations, type StandingState } from '../quo/index.ts';
|
|
3
|
+
import type { Rows } from '../contract/index.ts';
|
|
4
|
+
import type { JsonObject } from '../being/index.ts';
|
|
5
|
+
export declare const HEAD_ROW = "";
|
|
6
|
+
export type Head = {
|
|
7
|
+
lock?: KeptLock;
|
|
8
|
+
heirs: Record<string, HeirRecord>;
|
|
9
|
+
gone: string[];
|
|
10
|
+
bind: Record<string, {
|
|
11
|
+
being: string;
|
|
12
|
+
id: string;
|
|
33
13
|
}>;
|
|
34
|
-
|
|
35
|
-
minted: string[];
|
|
14
|
+
public: string | null;
|
|
36
15
|
};
|
|
37
|
-
export type
|
|
38
|
-
|
|
39
|
-
|
|
16
|
+
export type StandingRow = {
|
|
17
|
+
invitation: Invitation;
|
|
18
|
+
state: StandingState;
|
|
19
|
+
seen: string | null;
|
|
40
20
|
};
|
|
41
|
-
export
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
beings: Record<string, Cells & {
|
|
48
|
-
class?: string;
|
|
21
|
+
export type BeingRow = {
|
|
22
|
+
class: string;
|
|
23
|
+
cells: JsonObject;
|
|
24
|
+
occupants: Record<string, {
|
|
25
|
+
heir: string;
|
|
26
|
+
notes: JsonObject;
|
|
49
27
|
}>;
|
|
50
|
-
|
|
51
|
-
heirs: Record<string, Heir>;
|
|
52
|
-
gone: Record<string, Gone>;
|
|
53
|
-
public: string | null;
|
|
28
|
+
standings: Record<string, StandingRow>;
|
|
54
29
|
};
|
|
55
|
-
export declare
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
export declare
|
|
30
|
+
export declare class Partition {
|
|
31
|
+
readonly memory: Rows;
|
|
32
|
+
constructor(memory: Rows);
|
|
33
|
+
get head(): Head;
|
|
34
|
+
get beings(): Record<string, BeingRow>;
|
|
35
|
+
being(key: string): BeingRow | undefined;
|
|
36
|
+
told(key: string): void;
|
|
37
|
+
toldHead(): void;
|
|
38
|
+
kept(): Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
export declare class PartitionRelations implements Relations {
|
|
41
|
+
#private;
|
|
42
|
+
constructor(partition: Partition);
|
|
43
|
+
lock(): Lock | undefined;
|
|
44
|
+
setLock(lock: Lock): void;
|
|
45
|
+
get(heir: string): HeirRecord | undefined;
|
|
46
|
+
set(heir: string, record: HeirRecord): void;
|
|
47
|
+
delete(heir: string): void;
|
|
48
|
+
kept(): Promise<boolean>;
|
|
49
|
+
}
|
package/dist/ward/partition.js
CHANGED
|
@@ -1,295 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
// One value, and it does not move until 1.0.0. Before a release there is
|
|
12
|
-
// nobody holding a partition of another shape to tell apart: if the types
|
|
13
|
-
// below change, the partition is thrown away, not migrated to and not counted.
|
|
14
|
-
// A number that climbed with every change would be a changelog, and the only
|
|
15
|
-
// question asked here is answered by equality — is this a partition this ward
|
|
16
|
-
// can read. At 1.0.0 this changes once, and from then on it means something.
|
|
17
|
-
export const VERSION = 'pre-1.0.0';
|
|
18
|
-
// Every version this ward can read, newest last. Today it is one, and the
|
|
19
|
-
// seam below is what makes it able to be more than one later: a partition
|
|
20
|
-
// written under an older readable version is carried forward by `upgrade`
|
|
21
|
-
// before the ward touches it. The seam is here before 1.0.0 because after
|
|
22
|
-
// 1.0.0 there is nowhere to put it. A partition holds every secret and every
|
|
23
|
-
// relation a world has, so the first shape change after the freeze cannot be
|
|
24
|
-
// answered by throwing it away, and a ward that meets a shape it has no seam
|
|
25
|
-
// for refuses to boot with everything still inside it.
|
|
26
|
-
export const READS = [VERSION];
|
|
27
|
-
// Carry a partition written under an older readable version forward to this
|
|
28
|
-
// one. There is nothing to carry today, because READS has one member. Each
|
|
29
|
-
// step added here is from one member of READS to the next.
|
|
30
|
-
function upgrade(p) {
|
|
31
|
-
return p;
|
|
32
|
-
}
|
|
33
|
-
export const GONE = 256;
|
|
34
|
-
// The last few pks a relation minted, and no more. A relation rotates on
|
|
35
|
-
// every ask, so a list of all of them is a partition that grows for as long
|
|
36
|
-
// as she keeps talking and can never be written down. It lives here, beside
|
|
37
|
-
// the other bound on the durable shape, because it is a fact about what a
|
|
38
|
-
// partition may hold and not about how a ward mints.
|
|
39
|
-
export const MINTED = 8;
|
|
40
|
-
// A knock record is a key she minted for one invitation, kept until she takes
|
|
41
|
-
// it. Only take deletes one, so a being who knocks and never takes would grow
|
|
42
|
-
// her bind table for the life of the ward, one secret seed at a time. The
|
|
43
|
-
// list is bounded like `gone`: past the count the oldest go, and a relation
|
|
44
|
-
// that answered outlives one that never did, since an answered knock is one
|
|
45
|
-
// she may still take.
|
|
46
|
-
export const KNOCKS = 64;
|
|
47
|
-
export const prune = (knocks, answered) => {
|
|
48
|
-
const names = Object.keys(knocks);
|
|
49
|
-
if (names.length <= KNOCKS)
|
|
50
|
-
return;
|
|
51
|
-
const order = [...names.filter((n) => !answered[n]), ...names.filter((n) => answered[n])];
|
|
52
|
-
for (const old of order.slice(0, names.length - KNOCKS)) {
|
|
53
|
-
delete knocks[old];
|
|
54
|
-
delete answered[old];
|
|
1
|
+
import { GONE, keptLock, lockOf } from '../quo/index.js';
|
|
2
|
+
export const HEAD_ROW = '';
|
|
3
|
+
export class Partition {
|
|
4
|
+
memory;
|
|
5
|
+
constructor(memory) {
|
|
6
|
+
this.memory = memory;
|
|
7
|
+
const rows = memory.rows;
|
|
8
|
+
rows.ward ??= { heirs: {}, gone: [], bind: {}, public: null };
|
|
9
|
+
rows.beings ??= {};
|
|
55
10
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// this shape by construction; one it adopted was written by a hand, another
|
|
59
|
-
// kit, or a file that was cut short, and every field below is one the ward,
|
|
60
|
-
// the door or the heirs then act on without looking again. A `spent` that is
|
|
61
|
-
// not an array rejects the door's promise on the first bound ask, a `mark`
|
|
62
|
-
// that is not a number honours every number ever sent and grows without
|
|
63
|
-
// bound, a being row that is null refuses the whole ward at birth by
|
|
64
|
-
// accident and says nothing about why. So the shape is read once, here, and
|
|
65
|
-
// what is not it throws with the path that failed, which names the trouble
|
|
66
|
-
// to whoever is holding the file.
|
|
67
|
-
//
|
|
68
|
-
// The rule, so the reader does not grow into a schema: read every field the
|
|
69
|
-
// ward acts on, and refuse only what would make it act wrongly. So `minted`
|
|
70
|
-
// must be a list, because she pushes to it, and the truth in `answered` is
|
|
71
|
-
// not read, because anything there says answered and nothing else follows.
|
|
72
|
-
// `last` is reserved and nobody reads it, so nobody reads its shape either;
|
|
73
|
-
// the run that gives it a reader gives it a line here. A being's own cells
|
|
74
|
-
// are hers, of any shape JSON carries, and only the two records the ward
|
|
75
|
-
// keeps inside them are read.
|
|
76
|
-
const fault = (path, want) => {
|
|
77
|
-
throw new Error(`partition ${path} is not ${want}`);
|
|
78
|
-
};
|
|
79
|
-
const table = (v, path) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : fault(path, 'an object'));
|
|
80
|
-
const list = (v, path) => (Array.isArray(v) ? v : fault(path, 'an array'));
|
|
81
|
-
const text = (v, path) => void (typeof v === 'string' || fault(path, 'a string'));
|
|
82
|
-
const orNull = (v, path) => void (v === null || typeof v === 'string' || fault(path, 'a string or null'));
|
|
83
|
-
const whole = (v, path) => void (Number.isSafeInteger(v) || fault(path, 'a whole number'));
|
|
84
|
-
const flag = (v, path) => void (typeof v === 'boolean' || fault(path, 'true or false'));
|
|
85
|
-
function read(p) {
|
|
86
|
-
for (const [key, cells] of Object.entries(table(p.beings, 'beings'))) {
|
|
87
|
-
const c = table(cells, `beings.${key}`);
|
|
88
|
-
table(c.standings, `beings.${key}.standings`);
|
|
89
|
-
table(c.occupants, `beings.${key}.occupants`);
|
|
90
|
-
if (c.class !== undefined)
|
|
91
|
-
text(c.class, `beings.${key}.class`);
|
|
11
|
+
get head() {
|
|
12
|
+
return this.memory.rows.ward;
|
|
92
13
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
for (const [id, keys] of Object.entries(table(b.standings, `bind.${key}.standings`))) {
|
|
96
|
-
const w = `bind.${key}.standings.${id}`;
|
|
97
|
-
const s = table(keys, w);
|
|
98
|
-
text(s.ward, `${w}.ward`);
|
|
99
|
-
orNull(s.heir, `${w}.heir`);
|
|
100
|
-
text(s.current, `${w}.current`);
|
|
101
|
-
orNull(s.next, `${w}.next`);
|
|
102
|
-
whole(s.seq, `${w}.seq`);
|
|
103
|
-
}
|
|
104
|
-
for (const [id, pk] of Object.entries(table(b.occupants, `bind.${key}.occupants`)))
|
|
105
|
-
text(pk, `bind.${key}.occupants.${id}`);
|
|
106
|
-
for (const [name, keys] of Object.entries(table(b.knocks, `bind.${key}.knocks`))) {
|
|
107
|
-
const w = `bind.${key}.knocks.${name}`;
|
|
108
|
-
const k = table(keys, w);
|
|
109
|
-
text(k.current, `${w}.current`);
|
|
110
|
-
orNull(k.next, `${w}.next`);
|
|
111
|
-
flag(k.spoke, `${w}.spoke`);
|
|
112
|
-
flag(k.sent, `${w}.sent`);
|
|
113
|
-
whole(k.seq, `${w}.seq`);
|
|
114
|
-
}
|
|
115
|
-
table(b.answered, `bind.${key}.answered`);
|
|
116
|
-
for (const [i, pk] of list(b.minted, `bind.${key}.minted`).entries())
|
|
117
|
-
text(pk, `bind.${key}.minted[${i}]`);
|
|
14
|
+
get beings() {
|
|
15
|
+
return this.memory.rows.beings;
|
|
118
16
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
text(h.being, `heirs.${pk}.being`);
|
|
122
|
-
text(h.id, `heirs.${pk}.id`);
|
|
123
|
-
text(h.current, `heirs.${pk}.current`);
|
|
124
|
-
orNull(h.announced, `heirs.${pk}.announced`);
|
|
125
|
-
flag(h.fresh, `heirs.${pk}.fresh`);
|
|
126
|
-
whole(h.mark, `heirs.${pk}.mark`);
|
|
127
|
-
for (const [i, n] of list(h.spent, `heirs.${pk}.spent`).entries())
|
|
128
|
-
whole(n, `heirs.${pk}.spent[${i}]`);
|
|
17
|
+
being(key) {
|
|
18
|
+
return Object.hasOwn(this.beings, key) ? this.beings[key] : undefined;
|
|
129
19
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
text(g.current, `gone.${pk}.current`);
|
|
133
|
-
orNull(g.announced, `gone.${pk}.announced`);
|
|
20
|
+
told(key) {
|
|
21
|
+
this.memory.told(key);
|
|
134
22
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// say it is this version and be the shape this version names, and a ward that
|
|
141
|
-
// cannot read it does not boot. Birth is where a ward is allowed to be loud:
|
|
142
|
-
// silence is the door's word, for asks that were made, and no ask has been
|
|
143
|
-
// made yet.
|
|
144
|
-
export function open(memory) {
|
|
145
|
-
const p = memory;
|
|
146
|
-
if (Object.keys(memory).length > 0 && p.version !== VERSION) {
|
|
147
|
-
if (!READS.includes(p.version))
|
|
148
|
-
throw new Error(`partition is version ${p.version}, this ward reads ${READS.join(', ')}`);
|
|
149
|
-
upgrade(p).version = VERSION;
|
|
23
|
+
toldHead() {
|
|
24
|
+
this.memory.told(HEAD_ROW);
|
|
25
|
+
}
|
|
26
|
+
kept() {
|
|
27
|
+
return this.memory.kept().catch(() => false);
|
|
150
28
|
}
|
|
151
|
-
p.version ??= VERSION;
|
|
152
|
-
p.beings ??= {};
|
|
153
|
-
p.bind ??= {};
|
|
154
|
-
p.heirs ??= {};
|
|
155
|
-
p.gone ??= {};
|
|
156
|
-
p.public ??= null;
|
|
157
|
-
return read(p);
|
|
158
29
|
}
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return value;
|
|
168
|
-
};
|
|
169
|
-
export const drop = (rec, key) => {
|
|
170
|
-
if (Object.hasOwn(rec, key))
|
|
171
|
-
delete rec[key];
|
|
172
|
-
};
|
|
173
|
-
export const emptyCells = () => ({ standings: {}, occupants: {} });
|
|
174
|
-
export const emptyBind = () => ({ standings: {}, occupants: {}, knocks: {}, answered: {}, minted: [] });
|
|
175
|
-
// ---- the partition in rows, for a store that keeps it
|
|
176
|
-
//
|
|
177
|
-
// A ward hands a harbor one object, so a being who writes one cell has every
|
|
178
|
-
// other being in her ward written down beside her. What a being holds is the
|
|
179
|
-
// one thing here that grows without limit, so she is a row: her cells and her
|
|
180
|
-
// bind table, under her key. Everything else is one head row, and every part
|
|
181
|
-
// of it is bounded already, one record per occupant and two lists that drop
|
|
182
|
-
// their oldest.
|
|
183
|
-
//
|
|
184
|
-
// The split is here, where the shape is, and not in the harbor, which keeps
|
|
185
|
-
// what it is given and reads none of it. A store is handed the rows that
|
|
186
|
-
// moved; what it does with that is its own, and one that writes every row is
|
|
187
|
-
// as correct as one that writes the few.
|
|
188
|
-
export const HEAD = ''; // the row that is not a being: no being's key is empty
|
|
189
|
-
// What a put back never moves: the two sides of a relation. `beings` and
|
|
190
|
-
// `bind` are the tables the rows hang under and are never written whole.
|
|
191
|
-
// `heirs` and `gone` are the door's side of every relation this ward holds,
|
|
192
|
-
// and a being's own `bind` row is her side of hers.
|
|
193
|
-
//
|
|
194
|
-
// A relation cannot be put back, only broken. Her keys rotate when a reply
|
|
195
|
-
// opens and the door's rotate when it honours, so the two move at different
|
|
196
|
-
// moments and neither side holds the seed of a key it has moved past. Stand
|
|
197
|
-
// either one at an earlier moment and it speaks under a key the other will
|
|
198
|
-
// not admit, with no way back: the seed is gone. The count needs no help
|
|
199
|
-
// here, because a door honours any unseen number inside its span and a
|
|
200
|
-
// caller's count climbs at every attempt, so numbers find each other again
|
|
201
|
-
// on their own. Keys do not.
|
|
202
|
-
//
|
|
203
|
-
// Ahead of the device is survivable and behind the far side is not, so what
|
|
204
|
-
// a refusal puts back is what a being wrote and never what her relations are
|
|
205
|
-
// standing on. What it costs is that her keys are then ahead of what the
|
|
206
|
-
// store kept, which a restart can undo: a smaller hole, and the same one a
|
|
207
|
-
// restart has anyway.
|
|
208
|
-
const STANDING = new Set(['beings', 'bind', 'heirs', 'gone']);
|
|
209
|
-
// One row's value: a being, or the head, which is everything the partition
|
|
210
|
-
// holds that is not filed under a being. The head is read as what is left
|
|
211
|
-
// rather than as a list of names, so a store keeps whatever it was handed and
|
|
212
|
-
// hands the same thing back, and a field this file grows later needs no line
|
|
213
|
-
// in a store to survive a round trip.
|
|
214
|
-
//
|
|
215
|
-
// Undefined where the key names nobody, which is a row the store drops.
|
|
216
|
-
export const rowOf = (p, row) => {
|
|
217
|
-
const all = p;
|
|
218
|
-
if (row === HEAD)
|
|
219
|
-
return Object.fromEntries(Object.entries(all).filter(([k]) => k !== 'beings' && k !== 'bind'));
|
|
220
|
-
const cells = at(p.beings ?? {}, row);
|
|
221
|
-
return cells === undefined ? undefined : { cells, bind: at(p.bind ?? {}, row) ?? emptyBind() };
|
|
222
|
-
};
|
|
223
|
-
export const rowsIn = (p) => [HEAD, ...Object.keys(p.beings ?? {})];
|
|
224
|
-
// One row put back to what a store holds for it. A store that refused a row
|
|
225
|
-
// left the ward's memory ahead of the device, and everything written to that
|
|
226
|
-
// being afterwards would be lost at the next reload while she went on
|
|
227
|
-
// answering out of a memory nobody keeps. So the row is written back to the
|
|
228
|
-
// last value that was kept, and she stands at what is on the device.
|
|
229
|
-
//
|
|
230
|
-
// In place, always. A booted being holds her cells and her bind table by
|
|
231
|
-
// reference: her stance, her guard and her door all point at the objects the
|
|
232
|
-
// partition already has, so a row replaced by a fresh object would strand her
|
|
233
|
-
// on cells nothing keeps. Only the head may be written whole, because
|
|
234
|
-
// everything under it is read through the partition each time.
|
|
235
|
-
//
|
|
236
|
-
// A row the store does not hold is a being it never kept, and what is kept
|
|
237
|
-
// for her is nothing: her row goes, the way the store's own is already gone.
|
|
238
|
-
export const restoreRow = (p, row, value) => {
|
|
239
|
-
const all = p;
|
|
240
|
-
if (row === HEAD) {
|
|
241
|
-
for (const k of Object.keys(all))
|
|
242
|
-
if (!STANDING.has(k))
|
|
243
|
-
drop(all, k);
|
|
244
|
-
for (const [k, v] of Object.entries(value ?? {}))
|
|
245
|
-
if (!STANDING.has(k))
|
|
246
|
-
put(all, k, v);
|
|
247
|
-
return;
|
|
30
|
+
// The door's memory, written into the head.
|
|
31
|
+
export class PartitionRelations {
|
|
32
|
+
#partition;
|
|
33
|
+
constructor(partition) {
|
|
34
|
+
this.#partition = partition;
|
|
35
|
+
}
|
|
36
|
+
get #head() {
|
|
37
|
+
return this.#partition.head;
|
|
248
38
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// Her bind goes with her: a being the store never kept has no relation
|
|
252
|
-
// anybody is standing on, so there is nothing to leave forward.
|
|
253
|
-
drop(p.bind ?? {}, row);
|
|
254
|
-
return;
|
|
39
|
+
lock() {
|
|
40
|
+
return lockOf(this.#head.lock);
|
|
255
41
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
// the ward and marks nothing dirty.
|
|
260
|
-
const into = (rows, kept) => {
|
|
261
|
-
const guarded = at(rows, row);
|
|
262
|
-
if (guarded === undefined)
|
|
263
|
-
return void put(rows, row, kept);
|
|
264
|
-
const held = unguarded(guarded);
|
|
265
|
-
for (const k of Object.keys(held))
|
|
266
|
-
drop(held, k);
|
|
267
|
-
for (const [k, v] of Object.entries(kept))
|
|
268
|
-
put(held, k, v);
|
|
269
|
-
};
|
|
270
|
-
into(p.beings ?? {}, (value.cells ?? emptyCells()));
|
|
271
|
-
};
|
|
272
|
-
// The partition back from its rows. A head that is absent is a partition
|
|
273
|
-
// nobody has written, and `open` makes an empty one of it.
|
|
274
|
-
export const fromRows = (rows) => {
|
|
275
|
-
const out = { ...(rows[HEAD] ?? {}) };
|
|
276
|
-
const beings = {};
|
|
277
|
-
const bind = {};
|
|
278
|
-
let any = Object.keys(out).length > 0;
|
|
279
|
-
for (const [row, value] of Object.entries(rows)) {
|
|
280
|
-
if (row === HEAD)
|
|
281
|
-
continue;
|
|
282
|
-
put(beings, row, value.cells);
|
|
283
|
-
put(bind, row, value.bind);
|
|
284
|
-
any = true;
|
|
42
|
+
setLock(lock) {
|
|
43
|
+
this.#head.lock = keptLock(lock);
|
|
44
|
+
this.#partition.toldHead();
|
|
285
45
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
46
|
+
get(heir) {
|
|
47
|
+
return Object.hasOwn(this.#head.heirs, heir) ? this.#head.heirs[heir] : undefined;
|
|
48
|
+
}
|
|
49
|
+
set(heir, record) {
|
|
50
|
+
const head = this.#head;
|
|
51
|
+
head.heirs[heir] = record;
|
|
52
|
+
if (record.state === 'kept') {
|
|
53
|
+
head.gone.push(heir);
|
|
54
|
+
while (head.gone.length > GONE)
|
|
55
|
+
delete head.heirs[head.gone.shift()];
|
|
56
|
+
}
|
|
57
|
+
this.#partition.toldHead();
|
|
58
|
+
}
|
|
59
|
+
delete(heir) {
|
|
60
|
+
delete this.#head.heirs[heir];
|
|
61
|
+
this.#partition.toldHead();
|
|
62
|
+
}
|
|
63
|
+
kept() {
|
|
64
|
+
return this.#partition.kept();
|
|
65
|
+
}
|
|
66
|
+
}
|
package/dist/ward/stance.d.ts
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
send(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { type Door, type Draw, type Invitation } from '../quo/index.ts';
|
|
2
|
+
import type { Clock } from '../contract/index.ts';
|
|
3
|
+
import { type JsonObject, type Occupants, type Stance, type Standings } from '../being/index.ts';
|
|
4
|
+
import type { BeingRow, Partition } from './partition.ts';
|
|
5
|
+
import { DEPTH } from './cells.ts';
|
|
6
|
+
export { DEPTH };
|
|
7
|
+
export interface Inside {
|
|
8
|
+
readonly partition: Partition;
|
|
9
|
+
readonly door: Door;
|
|
10
|
+
readonly draw: Draw;
|
|
11
|
+
readonly clock: Clock;
|
|
12
|
+
live(key: string, row: BeingRow): boolean;
|
|
13
|
+
send(pk: string, bytes: Uint8Array): Promise<Uint8Array | null>;
|
|
14
|
+
boot(maker: string, className: string, key: string, id?: string): Promise<string | null>;
|
|
15
|
+
offer(contract: string): Promise<Invitation | null>;
|
|
16
|
+
retract(contract: string, heir: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare class WardStance implements Stance {
|
|
19
|
+
#private;
|
|
20
|
+
readonly key: string;
|
|
21
|
+
readonly occupants: Occupants;
|
|
22
|
+
readonly standings: Standings;
|
|
23
|
+
constructor(inside: Inside, key: string, row: BeingRow);
|
|
24
|
+
get cells(): JsonObject;
|
|
25
|
+
boot(className: string, key: string, id?: string): Promise<string | null>;
|
|
26
|
+
lend(contract: {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
}, id: string): Promise<string | null>;
|
|
29
|
+
}
|