nervur 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CONTRIBUTING.md +13 -0
  2. package/LICENSE +55 -202
  3. package/NOTICE +3 -8
  4. package/README.md +14 -156
  5. package/RELEASING.md +15 -0
  6. package/SECURITY.md +9 -0
  7. package/bin/nervur.js +6 -0
  8. package/package.json +26 -81
  9. package/AUTHORING.md +0 -935
  10. package/COMMAND.md +0 -179
  11. package/FACES.md +0 -280
  12. package/FACULTIES.md +0 -578
  13. package/GROUNDS.md +0 -315
  14. package/KIT-SPEC.md +0 -304
  15. package/WORLD.md +0 -195
  16. package/dist/app/app-ground.d.ts +0 -18
  17. package/dist/app/app-ground.js +0 -23
  18. package/dist/app/index.d.ts +0 -2
  19. package/dist/app/index.js +0 -5
  20. package/dist/app/native.d.ts +0 -11
  21. package/dist/app/native.js +0 -13
  22. package/dist/being/being.d.ts +0 -306
  23. package/dist/being/being.js +0 -20
  24. package/dist/being/covers.d.ts +0 -9
  25. package/dist/being/covers.js +0 -21
  26. package/dist/being/index.d.ts +0 -4
  27. package/dist/being/index.js +0 -6
  28. package/dist/being/need.d.ts +0 -49
  29. package/dist/being/need.js +0 -33
  30. package/dist/being/schema.d.ts +0 -100
  31. package/dist/being/schema.js +0 -132
  32. package/dist/being/table.d.ts +0 -48
  33. package/dist/being/table.js +0 -344
  34. package/dist/bench/bench-ground.d.ts +0 -73
  35. package/dist/bench/bench-ground.js +0 -153
  36. package/dist/bench/bench.d.ts +0 -101
  37. package/dist/bench/bench.js +0 -368
  38. package/dist/bench/fake-clock.d.ts +0 -17
  39. package/dist/bench/fake-clock.js +0 -34
  40. package/dist/bench/fake-memory.d.ts +0 -16
  41. package/dist/bench/fake-memory.js +0 -46
  42. package/dist/bench/fake-network.d.ts +0 -66
  43. package/dist/bench/fake-network.js +0 -222
  44. package/dist/bench/fake-unlock.d.ts +0 -6
  45. package/dist/bench/fake-unlock.js +0 -10
  46. package/dist/bench/index.d.ts +0 -3
  47. package/dist/bench/index.js +0 -5
  48. package/dist/bench/seeded.d.ts +0 -11
  49. package/dist/bench/seeded.js +0 -37
  50. package/dist/bench/settle.d.ts +0 -2
  51. package/dist/bench/settle.js +0 -49
  52. package/dist/bench/stewards.d.ts +0 -169
  53. package/dist/bench/stewards.js +0 -128
  54. package/dist/bodies/class-list.d.ts +0 -14
  55. package/dist/bodies/class-list.js +0 -33
  56. package/dist/bodies/joined-carry.d.ts +0 -29
  57. package/dist/bodies/joined-carry.js +0 -48
  58. package/dist/bodies/kept.d.ts +0 -44
  59. package/dist/bodies/kept.js +0 -91
  60. package/dist/bodies/noble-crypto.d.ts +0 -22
  61. package/dist/bodies/noble-crypto.js +0 -88
  62. package/dist/bodies/seed-keys.d.ts +0 -10
  63. package/dist/bodies/seed-keys.js +0 -42
  64. package/dist/bodies/strict-tools.d.ts +0 -10
  65. package/dist/bodies/strict-tools.js +0 -306
  66. package/dist/bodies/vouch.d.ts +0 -20
  67. package/dist/bodies/vouch.js +0 -71
  68. package/dist/bodies/web-carry.d.ts +0 -72
  69. package/dist/bodies/web-carry.js +0 -245
  70. package/dist/bodies/web-clock.d.ts +0 -12
  71. package/dist/bodies/web-clock.js +0 -33
  72. package/dist/browser/browser-ground.d.ts +0 -76
  73. package/dist/browser/browser-ground.js +0 -294
  74. package/dist/browser/index.d.ts +0 -4
  75. package/dist/browser/index.js +0 -7
  76. package/dist/browser/indexeddb-memory.d.ts +0 -17
  77. package/dist/browser/indexeddb-memory.js +0 -97
  78. package/dist/browser/locked-unlock.d.ts +0 -24
  79. package/dist/browser/locked-unlock.js +0 -85
  80. package/dist/browser/origin-classes.d.ts +0 -7
  81. package/dist/browser/origin-classes.js +0 -31
  82. package/dist/edge/durable-clock.d.ts +0 -19
  83. package/dist/edge/durable-clock.js +0 -61
  84. package/dist/edge/durable-memory.d.ts +0 -5
  85. package/dist/edge/durable-memory.js +0 -11
  86. package/dist/edge/durable.d.ts +0 -18
  87. package/dist/edge/durable.js +0 -24
  88. package/dist/edge/edge-ground.d.ts +0 -49
  89. package/dist/edge/edge-ground.js +0 -223
  90. package/dist/edge/index.d.ts +0 -7
  91. package/dist/edge/index.js +0 -9
  92. package/dist/edge/native-crypto.d.ts +0 -8
  93. package/dist/edge/native-crypto.js +0 -102
  94. package/dist/edge/secret-unlock.d.ts +0 -7
  95. package/dist/edge/secret-unlock.js +0 -13
  96. package/dist/edge/socket-carry.d.ts +0 -39
  97. package/dist/edge/socket-carry.js +0 -111
  98. package/dist/foundation.d.ts +0 -162
  99. package/dist/foundation.js +0 -4
  100. package/dist/ground/dock.d.ts +0 -1460
  101. package/dist/ground/dock.js +0 -1159
  102. package/dist/ground/ground.d.ts +0 -239
  103. package/dist/ground/ground.js +0 -787
  104. package/dist/ground/views.d.ts +0 -76
  105. package/dist/ground/views.js +0 -208
  106. package/dist/house/crossing.d.ts +0 -50
  107. package/dist/house/crossing.js +0 -153
  108. package/dist/house/house.d.ts +0 -88
  109. package/dist/house/house.js +0 -2069
  110. package/dist/house/rows-shape.d.ts +0 -110
  111. package/dist/house/rows-shape.js +0 -12
  112. package/dist/house/rows.d.ts +0 -27
  113. package/dist/house/rows.js +0 -185
  114. package/dist/index.d.ts +0 -33
  115. package/dist/index.js +0 -29
  116. package/dist/node/bridge.d.ts +0 -20
  117. package/dist/node/bridge.js +0 -284
  118. package/dist/node/cli.d.ts +0 -2
  119. package/dist/node/cli.js +0 -225
  120. package/dist/node/file-memory.d.ts +0 -13
  121. package/dist/node/file-memory.js +0 -86
  122. package/dist/node/folder-classes.d.ts +0 -5
  123. package/dist/node/folder-classes.js +0 -40
  124. package/dist/node/gone.d.ts +0 -2
  125. package/dist/node/gone.js +0 -7
  126. package/dist/node/hand.d.ts +0 -39
  127. package/dist/node/hand.js +0 -107
  128. package/dist/node/http.d.ts +0 -11
  129. package/dist/node/http.js +0 -90
  130. package/dist/node/index.d.ts +0 -11
  131. package/dist/node/index.js +0 -13
  132. package/dist/node/ledger-memory.d.ts +0 -17
  133. package/dist/node/ledger-memory.js +0 -152
  134. package/dist/node/lock.d.ts +0 -10
  135. package/dist/node/lock.js +0 -78
  136. package/dist/node/node-ground.d.ts +0 -26
  137. package/dist/node/node-ground.js +0 -228
  138. package/dist/node/notify.d.ts +0 -1
  139. package/dist/node/notify.js +0 -18
  140. package/dist/node/shell.d.ts +0 -11
  141. package/dist/node/shell.js +0 -35
  142. package/dist/node/sync-folder.d.ts +0 -6
  143. package/dist/node/sync-folder.js +0 -18
  144. package/dist/node/tcp-carry.d.ts +0 -42
  145. package/dist/node/tcp-carry.js +0 -193
  146. package/dist/node/unlock.d.ts +0 -17
  147. package/dist/node/unlock.js +0 -86
  148. package/dist/node/websocket.d.ts +0 -12
  149. package/dist/node/websocket.js +0 -134
  150. package/dist/quo/frame.d.ts +0 -33
  151. package/dist/quo/frame.js +0 -92
  152. package/dist/quo/index.d.ts +0 -1
  153. package/dist/quo/index.js +0 -5
  154. package/dist/quo/room.d.ts +0 -154
  155. package/dist/quo/room.js +0 -362
  156. package/dist/serve/index.d.ts +0 -45
  157. package/dist/serve/index.js +0 -71
package/WORLD.md DELETED
@@ -1,195 +0,0 @@
1
- # Reading a world
2
-
3
- nervur has four pieces: grounds, faculties, houses and beings. They can
4
- model any situation, so they give no order by themselves. This guide
5
- gives the order. It takes a real situation, with its people,
6
- organisations, machines, apps and sensors, and reads it into those four
7
- pieces. It adds nothing to the library. [Writing for
8
- nervur](AUTHORING.md) teaches beings and grounds, and [Writing a
9
- faculty](FACULTIES.md) teaches faculties.
10
-
11
- ## Three questions
12
-
13
- Ask three questions of every real thing, and choose its terrain last.
14
-
15
- 1. **Whose will does it serve?** A will is one owner, a person or an
16
- organisation. Inside one will the owner possesses everything. The
17
- design work is at the borders, where a relation crosses from one will
18
- to another.
19
- 2. **Is it a mind, a thing or a matter?** A mind decides: a human, an AI
20
- agent, an organisation acting through its systems. A thing senses or
21
- acts and decides nothing: a camera, a sensor, a shell, a payment API.
22
- A matter is work several parties share: an order, a booking, a case.
23
- 3. **Can it be asked?** The end of a relation that others ask must stand
24
- on a ground they can reach. So reach decides where a being lives.
25
-
26
- ## Two kinds of being
27
-
28
- **Every being is a twin or a matter.** A twin maps one thing outside the
29
- house into it, through one entry. A matter lives inside the house alone,
30
- and shares work between twins.
31
-
32
- | Twin of | Enters by | Being |
33
- | --- | --- | --- |
34
- | the house's owner | the hand | the steward |
35
- | any stranger | a face with no token, or Quo with no relation | the public being |
36
- | one known will | a face with a token, or Quo | a representative |
37
- | one thing | a faculty | the twin of that thing |
38
-
39
- **The steward is the twin of the house's owner.** The owner is whoever
40
- holds the house's seed.
41
-
42
- **A representative is the twin of one known will.** That will may be a
43
- human on a site, a human with an AI agent over MCP, an organisation's
44
- script over an API, or another house over Quo. Her occupants are that
45
- will's doors in. Her standings are its accounts out.
46
-
47
- **A representative in a shop and an avatar at home are one shape.** At a
48
- shop, Alice's representative holds what the shop's class lets her hold.
49
- In Alice's own house, her avatar is the same shape, and Alice's class
50
- decides.
51
-
52
- **The twin of a thing is the one being granted its faculty.** The
53
- faculty is the process or service that touches the thing. The ground
54
- grants it to the twin's kind alone. The twin holds the thing's policy,
55
- state and history.
56
-
57
- **A matter is shared work.** An order between a customer and a shop, a
58
- case between a lawyer and a court, and a family calendar are matters.
59
- Each is reached only through the representatives and twins of those who
60
- share it.
61
-
62
- ## The rules between them
63
-
64
- - A mind reaches a matter only through its representative.
65
- - A matter or a representative reaches a thing only through its twin.
66
- - A faculty never crosses from one will to another. The other will
67
- holds a standing on the twin, and the twin applies its policy.
68
- - Nothing outside the house touches a matter directly.
69
- - The border of a house is its twins, one for each outside thing. Its
70
- inside is its matters.
71
-
72
- ## How a human enters
73
-
74
- **A human enters in one of two ways.**
75
-
76
- - **Possessing.** She sits at the machine and asks through the hand,
77
- with the `nervur` command or an app's own screens. She is `root` on
78
- every house of that ground.
79
- - **Living.** She enters through a face, a site, an API or an MCP
80
- server, with a token. She is one occupant of one being, and reaches
81
- only what that being's table allows her.
82
-
83
- **Quo is not a human's entry.** Quo carries asks between houses. When
84
- Alice's home asks a shop, her avatar asks for her.
85
-
86
- **The hand never leaves its machine.** A human away from the machine
87
- lives through a face, even in her own house.
88
-
89
- ## A person, seen from two sides
90
-
91
- **A shop sees a person as one being with many doors.** Each occupant of
92
- her representative is one way she reaches it: a browser's token, one of
93
- her devices, or her home. The shop never needs to know that the doors
94
- are one person.
95
-
96
- **One reachable house becomes a person's home.** It holds her standings
97
- on every shop, and each of her devices holds a standing on it. A shop
98
- then sees one door from her, and a lost device is revoked at home,
99
- touching no shop.
100
-
101
- ## Stations and devices
102
-
103
- **Every ground is a station or a device, by whether it can be asked.**
104
-
105
- - **A station can be asked.** Representatives, the public being and
106
- shared matters live there.
107
- - **A device cannot be asked.** The twins of physical things live there,
108
- beside their things. Each device holds a standing on one station.
109
-
110
- | Ground | Family | What lives on it |
111
- | --- | --- | --- |
112
- | NodeGround | a station on a server; a device on a desktop or a Pi behind a router | anything its reach allows |
113
- | EdgeGround | a station with no machine | the public being, representatives, shared matters |
114
- | AppGround | a device, woken by launch and by push | the steward, twins of the phone's things |
115
- | BrowserGround | a device bound to its origin | the steward, twins of the browser's things |
116
- | BenchGround | every family, in memory | a whole world under test |
117
-
118
- **Representatives live on stations alone.** Others must ask them, so
119
- they need a ground that can be reached.
120
-
121
- **The twin of a physical thing lives beside it.** A camera's twin stands
122
- on the Pi or the phone that touches the camera.
123
-
124
- **A device keeps matters only for its own autonomy.** A thermostat rule
125
- between a temperature twin and a heater twin runs on the Pi while the
126
- network is down. Every matter another will shares lives on a station.
127
-
128
- **A device cannot be asked, so it asks.** Its twins send readings up as
129
- effects to a mirror on its station, and it watches the mirror for what
130
- waits for it. Every other will holds a standing on the mirror, and never
131
- on the device.
132
-
133
- ## Four roles
134
-
135
- **Crossing the owner with the family gives four roles.**
136
-
137
- | | Station | Device |
138
- | --- | --- | --- |
139
- | A person's | home | device |
140
- | An organisation's | shop | outpost |
141
-
142
- ## A garage, read whole
143
-
144
- **The garage door is a thing, and its relay is a faculty on a Pi.** One
145
- pulse toggles the door, so a pulse sent twice opens it and closes it
146
- again. The relay's program keeps each call id before it pulses.
147
-
148
- **The door's twin is the one being granted the relay.** She keeps who
149
- opened the door and which pulse did it. The Pi is an outpost of the
150
- family: it only dials, and opens no port.
151
-
152
- **The door's mirror stands on the family's station, and the twin watches
153
- it.** An opening lands on the mirror and reaches the Pi at once, over one
154
- held line.
155
-
156
- **Alice's phone asks the mirror.** Each tap pulses once, across a crash
157
- of the program and a lost reply, since each hop carries one call id. Bob
158
- and a babysitter hold standings on the mirror too, and never reach the
159
- Pi.
160
-
161
- ## Minds that are not human
162
-
163
- **An AI agent is a mind.** One working for a person gets a
164
- representative and lives through an MCP face, or runs from a house of
165
- its own and asks over Quo. It is never a faculty.
166
-
167
- **A model called for a completion is a thing.** A being that asks a
168
- model to help her decide calls a faculty through her twin of it. The
169
- being decides, and the model answers.
170
-
171
- **A script that speaks no Quo is a mind or a thing.** A script that acts
172
- as a client lives through an API face with a token. A program the house
173
- calls is a thing, wrapped as a faculty by the bridge.
174
-
175
- ## The order, step by step
176
-
177
- 1. Draw the wills.
178
- 2. In each will, list its minds, its things and its matters.
179
- 3. Give each mind a representative, each thing a twin, and each matter a
180
- being.
181
- 4. Place each twin of a physical thing at its thing, and every
182
- representative and matter on a station of the will that owns it.
183
- 5. Connect wills only through representatives and twins.
184
- 6. Check that every end others ask stands on a station, and make each
185
- device push up and pull down.
186
- 7. Choose the terrain of each ground last.
187
-
188
- ## What the reading refuses
189
-
190
- - A fifth piece. A twin, a matter, a station and a device are readings
191
- of the four.
192
- - A faculty granted across a will.
193
- - A representative on a device, where no one can ask her.
194
- - A matter shared with another will on a device.
195
- - A human entering by any way but the hand or a face.
@@ -1,18 +0,0 @@
1
- import { type BrowserGround, type BrowserGroundOptions } from '../browser/browser-ground.ts';
2
- import { type NativeSecrets, type NativeStore } from './native.ts';
3
- /** What the shell hands the ground: its secret store and its native store. */
4
- export interface NativeShell {
5
- readonly secrets: NativeSecrets;
6
- readonly store: NativeStore;
7
- }
8
- export interface AppGroundOptions extends Omit<BrowserGroundOptions, 'platform'> {
9
- readonly shell: NativeShell;
10
- /** Loads a module of classes by URL, where the app's build hands its own. */
11
- readonly load?: (href: string) => Promise<unknown>;
12
- /** Where its classes stand; the web view's own origin where omitted. */
13
- readonly origin?: string;
14
- }
15
- export declare const AppGround: Readonly<{
16
- /** The app's ground: a BrowserGround whose unlock and memory are the shell's own. */
17
- open({ shell, load, origin, ...options }: AppGroundOptions): Promise<BrowserGround>;
18
- }>;
@@ -1,23 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // The ground in a phone's app: a BrowserGround in the shell's web view,
3
- // on the two bodies the shell hands in. Its key rests in the platform's
4
- // Keychain or Keystore, and its memory in a native store the system never
5
- // evicts. The code arrives signed in the app's bundle, and one web view
6
- // runs, so the lock is taken at once. A wake by push is the app's own
7
- // registry's faculty, since the library ships no faculty.
8
- import { openOn } from '../browser/browser-ground.js';
9
- import { NativeMemory, NativeUnlock } from './native.js';
10
- export const AppGround = Object.freeze({
11
- /** The app's ground: a BrowserGround whose unlock and memory are the shell's own. */
12
- open({ shell, load, origin, ...options }) {
13
- return openOn({
14
- ...options,
15
- platform: {
16
- // The system keeps an app's own store, so there is nothing to ask.
17
- persist: async () => true,
18
- ...(load === undefined ? {} : { load }),
19
- ...(origin === undefined ? {} : { origin }),
20
- },
21
- }, { unlock: async () => new NativeUnlock(shell.secrets), memory: async (name) => new NativeMemory(shell.store, name) });
22
- },
23
- });
@@ -1,2 +0,0 @@
1
- export { AppGround, type NativeShell } from './app-ground.ts';
2
- export { NativeMemory, NativeUnlock, type NativeSecrets, type NativeStore } from './native.ts';
package/dist/app/index.js DELETED
@@ -1,5 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // `nervur/app`: the ground of a phone's app, a BrowserGround on the bodies
3
- // its shell hands in, and the contracts a shell's native code fills.
4
- export { AppGround } from './app-ground.js';
5
- export { NativeMemory, NativeUnlock } from './native.js';
@@ -1,11 +0,0 @@
1
- import { KeptMemory, KeptUnlock, type Secrets, type Store } from '../bodies/kept.ts';
2
- /** The platform's secret store: text by name, kept by the Keychain or the Keystore, on this device alone. */
3
- export type NativeSecrets = Secrets;
4
- /** A native store of text by key, which the operating system never evicts, with a swap that lands only where nothing moved. */
5
- export type NativeStore = Store;
6
- /** The ground's key in the platform's secret store, drawn on first use. The store is the protection, on this device alone. */
7
- export declare class NativeUnlock extends KeptUnlock {
8
- }
9
- /** Memory in the native store, one for each name, which the system never evicts. */
10
- export declare class NativeMemory extends KeptMemory {
11
- }
@@ -1,13 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // The two native bodies of a phone's ground, over what the shell hands in.
3
- // The shell's secret store is the iOS Keychain or the Android Keystore, and
4
- // its store is a native file or database the operating system never
5
- // evicts. The library holds the contracts' logic; a shell holds only the
6
- // two small interfaces below, in its own native code.
7
- import { KeptMemory, KeptUnlock } from '../bodies/kept.js';
8
- /** The ground's key in the platform's secret store, drawn on first use. The store is the protection, on this device alone. */
9
- export class NativeUnlock extends KeptUnlock {
10
- }
11
- /** Memory in the native store, one for each name, which the system never evicts. */
12
- export class NativeMemory extends KeptMemory {
13
- }
@@ -1,306 +0,0 @@
1
- import type { MethodSpec, Need, BLUEPRINT } from './need.ts';
2
- import type { Handle, Inbound, Infer, Invitation, Outbound } from './schema.ts';
3
- /** A JSON value, as cells and notes hold. */
4
- export type Json = null | boolean | number | string | readonly Json[] | {
5
- readonly [key: string]: Json;
6
- };
7
- /** What a call outward carries: JSON, bytes, and the handles and invitations the callee's schema places. */
8
- export type Passed = Json | Uint8Array | Handle | Invitation | readonly Passed[] | {
9
- readonly [key: string]: Passed;
10
- };
11
- /** Notes on a relation. */
12
- export type Notes = Readonly<Record<string, Json>>;
13
- /** Where the house placed her. */
14
- export type Position = 'steward' | 'public' | 'normal';
15
- /** Who asks now. */
16
- export interface Asker {
17
- readonly id: string;
18
- readonly notes: Notes;
19
- readonly steward: Notes;
20
- readonly signer?: Uint8Array;
21
- }
22
- /** What a role and her state read of her. */
23
- export interface Me<C> {
24
- readonly id: string;
25
- readonly position: Position;
26
- readonly cells: Readonly<C>;
27
- }
28
- type Names = string | readonly string[];
29
- /**
30
- * One example of an ask, run by the bench and nowhere else. `given` is the
31
- * history of her own asks that brings her from her `born` to where the
32
- * example starts.
33
- */
34
- export interface Example {
35
- readonly description?: string;
36
- readonly given?: readonly {
37
- readonly ask: string;
38
- readonly args?: Json;
39
- readonly role?: string;
40
- }[];
41
- readonly role?: string;
42
- readonly args?: Json;
43
- readonly fakes?: Json;
44
- readonly gives?: Json;
45
- }
46
- /** An ask's entry: the method's gate. */
47
- export interface Entry extends MethodSpec {
48
- readonly in?: Names;
49
- readonly for?: Names;
50
- readonly to?: Names;
51
- readonly examples?: readonly Example[];
52
- }
53
- /** What a class declares. */
54
- export interface Declaration<C = Record<string, Json>, N = Record<string, Need>, A = Record<string, Entry>> {
55
- readonly kind: string;
56
- readonly description?: string;
57
- readonly cells?: C;
58
- readonly needs?: N;
59
- readonly roles?: Readonly<Record<string, (asker: Asker, me: Me<C>) => boolean>>;
60
- readonly state?: (me: Me<C>) => string;
61
- readonly asks: A;
62
- /** Markup as text over her asks, which a screen renders. */
63
- readonly view?: string;
64
- }
65
- /** A relation, with her notes and her steward's. */
66
- export interface Relation {
67
- readonly id: string;
68
- readonly notes: Notes;
69
- readonly steward: Notes;
70
- }
71
- type Resolved<S> = S extends {
72
- readonly result: infer R;
73
- } ? Inbound<Infer<R>> : null;
74
- type Sent<S> = S extends {
75
- readonly args: infer A;
76
- } ? Outbound<Infer<A>> : Record<string, never>;
77
- type IsAwaited<S> = S extends {
78
- readonly hints: {
79
- readonly idempotent: true;
80
- };
81
- } ? true : S extends {
82
- readonly hints: {
83
- readonly readOnly: true;
84
- };
85
- } ? true : false;
86
- /** How she calls one method: awaited, or an effect answered through `reply`. */
87
- type Given<S, O extends unknown[]> = {} extends Sent<S> ? [args?: Sent<S>, ...O] : [args: Sent<S>, ...O];
88
- type IsReadOnly<S> = S extends {
89
- readonly hints: {
90
- readonly readOnly: true;
91
- };
92
- } ? true : false;
93
- export type Call<S, R extends string> = IsReadOnly<S> extends true ? ((...given: Given<S, [options: {
94
- after: Resolved<S>;
95
- reply: R;
96
- }]>) => void) & ((...given: Given<S, [options?: {
97
- after?: Resolved<S>;
98
- }]>) => Promise<Resolved<S>>) : IsAwaited<S> extends true ? (...given: Given<S, []>) => Promise<Resolved<S>> : (...given: Given<S, [options?: {
99
- reply?: R;
100
- }]>) => void;
101
- /** The frozen face of a need: its methods and nothing else. */
102
- export type Face<X, R extends string = string> = {
103
- readonly [K in Exclude<keyof X, typeof BLUEPRINT>]: Call<X[K], R>;
104
- };
105
- /** A standing asked with no need matched, such as her steward. */
106
- export type Untyped = Readonly<Record<string, (args?: Passed, options?: {
107
- reply?: string;
108
- }) => Promise<unknown> | void>>;
109
- /** One ask as a far being's describe shows it: its schemas, its hints and its wait. */
110
- export interface Described {
111
- readonly method: string;
112
- readonly description?: string;
113
- readonly in?: readonly string[];
114
- readonly to?: readonly string[];
115
- readonly args?: Json;
116
- readonly result?: Json;
117
- readonly hints?: {
118
- readonly readOnly?: boolean;
119
- readonly idempotent?: boolean;
120
- readonly destructive?: boolean;
121
- };
122
- readonly wait?: number;
123
- }
124
- /**
125
- * A standing asked with no need declared. `describe` reads what it shows
126
- * her now. `ask` names a method from the describe she read in this ask,
127
- * which says whether it is awaited or an effect.
128
- */
129
- export interface Undeclared<R extends string = string> {
130
- describe(): Promise<{
131
- readonly state: string;
132
- readonly asks: readonly Described[];
133
- }>;
134
- ask(method: string, args?: Passed, options?: {
135
- reply?: R;
136
- after?: unknown;
137
- }): Promise<unknown> | undefined;
138
- }
139
- /** What a far public being is reached by: her ward, and her addresses in order. */
140
- export interface Card {
141
- readonly ward: string;
142
- readonly at: readonly string[];
143
- }
144
- /**
145
- * A far public being asked as a stranger with no need declared. `describe`
146
- * reads what she shows a stranger now, and `ask` names a method from it.
147
- */
148
- export interface Strange {
149
- describe(): Promise<{
150
- readonly state: string;
151
- readonly asks: readonly Described[];
152
- }>;
153
- ask(method: string, args?: Passed): Promise<unknown>;
154
- }
155
- /** What `this.house` gives every being. */
156
- export interface HouseReach<R extends string = string> {
157
- now(): number;
158
- random(options: {
159
- length: number;
160
- }): Uint8Array;
161
- alarm(options: {
162
- at: number;
163
- ask: R;
164
- args?: Json;
165
- key: string;
166
- }): void;
167
- cancelAlarm(options: {
168
- key: string;
169
- }): void;
170
- }
171
- /** Her standings. */
172
- export interface Standings {
173
- /** Each standing, with the domains that vouch for a far one's ward. */
174
- list(): readonly (Relation & {
175
- readonly vouched: readonly string[];
176
- })[];
177
- note(id: string, notes: Notes): void;
178
- drop(id: string): void;
179
- }
180
- /** Her occupants and handles. */
181
- export interface Occupants {
182
- list(): readonly Relation[];
183
- note(id: string, notes: Notes): void;
184
- dismiss(id: string): void;
185
- }
186
- /** The steward's six powers. */
187
- export interface Powers {
188
- /** A new occupant of another being, as a handle she may pass on. */
189
- invite(options: {
190
- id: string;
191
- occupant: string;
192
- notes?: Notes;
193
- expires?: number;
194
- }): Handle;
195
- bear(options: {
196
- kind: string;
197
- id: string;
198
- args?: Json;
199
- }): void;
200
- remove(options: {
201
- id: string;
202
- }): void;
203
- /** Every being, her kind, whether she is absent, and the replies her table refused. */
204
- list(): Promise<readonly {
205
- id: string;
206
- kind: string;
207
- absent: boolean;
208
- dead: readonly {
209
- ask: string;
210
- args: Json;
211
- at: number;
212
- why: string;
213
- }[];
214
- }[]>;
215
- /** Her args may carry a handle she holds or an invitation she carries, as any call outward. */
216
- ask(call: {
217
- id: string;
218
- method: string;
219
- args?: Passed;
220
- }, options?: {
221
- reply?: string;
222
- }): Promise<unknown> | void;
223
- /** With no method, the empty ask: what the being shows her steward now. */
224
- ask(call: {
225
- id: string;
226
- }): Promise<{
227
- readonly state: string;
228
- readonly asks: readonly Described[];
229
- }>;
230
- introduce(options: {
231
- from: string;
232
- to: string;
233
- notes?: Notes;
234
- }): void;
235
- }
236
- export declare const DECLARATION: unique symbol;
237
- declare const ASKS: unique symbol;
238
- /** The asks of a class, carried in its type alone. */
239
- export interface Typed<A> {
240
- readonly [ASKS]?: A;
241
- }
242
- type AskOf<T, K> = T extends Typed<infer A> ? (K extends keyof A ? A[K] : never) : never;
243
- /** The args her method `K` receives. */
244
- export type Args<T, K extends string> = AskOf<T, K> extends {
245
- readonly args: infer S;
246
- } ? Inbound<Infer<S>> : Record<string, never>;
247
- /** What her method `K` answers. */
248
- export type Result<T, K extends string> = AskOf<T, K> extends {
249
- readonly result: infer S;
250
- } ? Outbound<Infer<S>> : void;
251
- /** What every being reaches. */
252
- export declare abstract class Being<C = Record<string, Json>, R extends string = string> {
253
- readonly id: string;
254
- readonly position: Position;
255
- readonly asker: Asker;
256
- cells: C;
257
- readonly house: HouseReach<R>;
258
- readonly standings: Standings;
259
- readonly occupants: Occupants;
260
- /** Her steward, asked as a standing, where she is not one. */
261
- readonly steward?: Untyped;
262
- /** The house's powers, where she is the steward. */
263
- readonly powers?: Powers;
264
- /**
265
- * A standing matched to a need; with none, a standing she reads first,
266
- * then asks by any ask its describe showed her.
267
- */
268
- held: (<X extends Need>(id: string, need: X) => Face<X, R>) & ((id: string) => Undeclared<R>);
269
- /**
270
- * A far house's public being, reached by its ward and its addresses and
271
- * asked as a stranger. Every ask is awaited, and signed with a key her
272
- * house keeps for that ward alone. With no need, she reads its describe
273
- * first, then asks by any ask it showed her.
274
- */
275
- stranger: (<X extends Need>(card: Card, need: X) => Face<X, R>) & ((card: Card) => Strange);
276
- /**
277
- * A handle to one of her asks. Each invitation it leaves as is spent within
278
- * `expires` milliseconds of leaving, or never binds.
279
- */
280
- handle: (ask: R, options?: {
281
- bind?: Json;
282
- notes?: Notes;
283
- once?: boolean;
284
- expires?: number;
285
- }) => Handle;
286
- /** A new occupant, as a handle, with `expires` as `handle` has it. */
287
- invite: (id: string, options?: {
288
- notes?: Notes;
289
- expires?: number;
290
- }) => Handle;
291
- /** Throws an error the asker can act on. */
292
- fail: (message: string) => never;
293
- /** A class, declared by one object. */
294
- static of<C extends Record<string, Json> = Record<string, never>, const N extends Record<string, Need> = Record<never, never>, const A extends Record<string, Entry> = Record<string, Entry>>(declaration: Declaration<C, N, A>): BeingClass<C, N, A>;
295
- }
296
- /** What `Being.of` gives: a class to extend. */
297
- export type BeingClass<C, N, A> = (abstract new () => Being<C, keyof A & string> & {
298
- readonly [K in keyof N]: Face<N[K], keyof A & string>;
299
- } & Typed<A>) & {
300
- readonly [DECLARATION]: Declaration<C, N, A>;
301
- };
302
- /** The members of `Being` a class may not name. */
303
- export declare const MEMBERS: ReadonlySet<string>;
304
- /** The declaration a class carries, or nothing where it is no class of `Being.of`. */
305
- export declare const declarationOf: (value: unknown) => Declaration | undefined;
306
- export {};
@@ -1,20 +0,0 @@
1
- export const DECLARATION = Symbol('declaration');
2
- /** What every being reaches. */
3
- export class Being {
4
- /** A class, declared by one object. */
5
- static of(declaration) {
6
- // A class of her own, so the house reads her declaration from it.
7
- class Declared extends Being {
8
- static [DECLARATION] = declaration;
9
- }
10
- return Declared;
11
- }
12
- }
13
- /** The members of `Being` a class may not name. */
14
- export const MEMBERS = new Set(['id', 'position', 'asker', 'cells', 'house', 'standings', 'occupants', 'steward', 'powers', 'held', 'stranger', 'handle', 'invite', 'fail']);
15
- /** The declaration a class carries, or nothing where it is no class of `Being.of`. */
16
- export const declarationOf = (value) => {
17
- if (typeof value !== 'function' || !(value.prototype instanceof Being))
18
- return undefined;
19
- return value[DECLARATION];
20
- };
@@ -1,9 +0,0 @@
1
- import type { Blueprint } from './need.ts';
2
- /** Covered, or the first rule that fails, as a sentence. */
3
- export type Cover = {
4
- readonly covered: true;
5
- } | {
6
- readonly covered: false;
7
- readonly why: string;
8
- };
9
- export declare const covers: (offer: Blueprint, want: Blueprint) => Cover;
@@ -1,21 +0,0 @@
1
- const requiredOf = (schema) => {
2
- const required = schema.required;
3
- return Array.isArray(required) ? required : [];
4
- };
5
- export const covers = (offer, want) => {
6
- if (offer.name !== want.name)
7
- return { covered: false, why: `the offer is ${offer.name}, and the need is ${want.name}` };
8
- for (const [name, wanted] of Object.entries(want.methods)) {
9
- const offered = offer.methods[name];
10
- if (offered === undefined)
11
- return { covered: false, why: `${want.name} offers no ${name}` };
12
- const sent = new Set(requiredOf(wanted.args));
13
- const extra = requiredOf(offered.args).find((key) => !sent.has(key));
14
- if (extra !== undefined)
15
- return { covered: false, why: `${want.name}.${name} requires ${extra}, which the need does not send` };
16
- if (offered.hints.idempotent !== wanted.hints.idempotent) {
17
- return { covered: false, why: `${want.name}.${name} is idempotent in one and not the other` };
18
- }
19
- }
20
- return { covered: true };
21
- };
@@ -1,4 +0,0 @@
1
- export { Being, type Args, type Json, type Result } from './being.ts';
2
- export { need } from './need.ts';
3
- export { s } from './schema.ts';
4
- export { resolve as tableOf, type Table } from './table.ts';
@@ -1,6 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // `nervur/being`: what a being's author imports, and nothing else.
3
- export { Being } from './being.js';
4
- export { need } from './need.js';
5
- export { s } from './schema.js';
6
- export { resolve as tableOf } from './table.js';