nervur 0.22.2-7 → 0.22.2-8
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/AUTHORING.md +41 -35
- package/COMMAND.md +5 -3
- package/FACES.md +18 -12
- package/FACULTIES.md +39 -26
- package/GROUNDS.md +52 -27
- package/README.md +2 -2
- package/dist/bench/bench-ground.d.ts +3 -3
- package/dist/bench/bench-ground.js +40 -26
- package/dist/browser/browser-ground.js +42 -22
- package/dist/edge/edge-ground.js +48 -27
- package/dist/ground/ground.d.ts +145 -59
- package/dist/ground/ground.js +498 -225
- package/dist/house/house.d.ts +8 -0
- package/dist/house/house.js +12 -3
- package/dist/index.d.ts +1 -1
- package/dist/node/bridge.d.ts +3 -3
- package/dist/node/bridge.js +2 -2
- package/dist/node/node-ground.d.ts +6 -5
- package/dist/node/node-ground.js +164 -62
- package/dist/node/tcp-carry.d.ts +2 -2
- package/dist/node/tcp-carry.js +6 -4
- package/package.json +1 -1
package/AUTHORING.md
CHANGED
|
@@ -11,8 +11,8 @@ The shop has three classes and one faculty.
|
|
|
11
11
|
- `Order` is one order, from its first item to its shipping.
|
|
12
12
|
- `Shop` is the steward, the being that runs the house.
|
|
13
13
|
- `Lobby` is the public being, which strangers may ask.
|
|
14
|
-
- `Payments` is a faculty that charges money, which
|
|
15
|
-
|
|
14
|
+
- `Payments` is a faculty that charges money, which `recipe.ts` holds
|
|
15
|
+
by name.
|
|
16
16
|
|
|
17
17
|
## Words
|
|
18
18
|
|
|
@@ -32,7 +32,8 @@ The shop has three classes and one faculty.
|
|
|
32
32
|
| state | a name read from her cells that decides which asks exist |
|
|
33
33
|
| house | what holds beings, keeps their cells, and seals every ask |
|
|
34
34
|
| ground | the process houses run in, holding one key and sealing their seeds, faculties and secrets under it |
|
|
35
|
-
| registry | code that
|
|
35
|
+
| registry | code that holds faculties by name, for the ground to stand |
|
|
36
|
+
| body | a faculty stood: the living instance houses and bodies use |
|
|
36
37
|
|
|
37
38
|
## A being
|
|
38
39
|
|
|
@@ -588,8 +589,8 @@ type Answer = { result: { pending: boolean } } | { error: { message: string } };
|
|
|
588
589
|
/**
|
|
589
590
|
* A payment provider in the ground's process. It answers a call id it has
|
|
590
591
|
* seen with the answer it gave, so an effect sent twice charges once. A
|
|
591
|
-
* provider that changes the world keeps these in the memory its
|
|
592
|
-
* receives, where a restart and a move keep them.
|
|
592
|
+
* provider that changes the world keeps these in the memory its faculty's
|
|
593
|
+
* `up` receives, where a restart and a move keep them.
|
|
593
594
|
*/
|
|
594
595
|
export class Payments {
|
|
595
596
|
readonly #answered = new Map<string, Answer>();
|
|
@@ -619,19 +620,19 @@ export const paymentsOffer = (payments: Payments): Offer => ({ blueprint: Paymen
|
|
|
619
620
|
|
|
620
621
|
An offer is `{ blueprint, object, kinds?, window? }`. The object answers
|
|
621
622
|
each call with its call id, and one that changes the world answers a
|
|
622
|
-
call id it has seen with the answer it gave. A registry holds
|
|
623
|
-
|
|
624
|
-
its
|
|
625
|
-
[Writing a faculty](FACULTIES.md) teaches the
|
|
626
|
-
written in Python.
|
|
623
|
+
call id it has seen with the answer it gave. A registry holds each
|
|
624
|
+
faculty by name, as `{ up, install? }`. The ground raises a faculty by
|
|
625
|
+
its `up` when an entry names it, and the entry's `kinds` grants it to
|
|
626
|
+
the classes it names. [Writing a faculty](FACULTIES.md) teaches the
|
|
627
|
+
craft whole, with a faculty written in Python.
|
|
627
628
|
|
|
628
629
|
```ts
|
|
629
630
|
// recipe.ts
|
|
630
631
|
import { Payments, paymentsOffer } from './payments.ts';
|
|
631
632
|
|
|
632
|
-
// A registry: the ground
|
|
633
|
+
// A registry: the ground raises each faculty an entry names by its `up` here.
|
|
633
634
|
export const faculties = {
|
|
634
|
-
payments: () => paymentsOffer(new Payments()),
|
|
635
|
+
payments: { up: () => paymentsOffer(new Payments()) },
|
|
635
636
|
};
|
|
636
637
|
```
|
|
637
638
|
|
|
@@ -681,14 +682,16 @@ The ground boots in one order, and a stop is that order reversed, on an
|
|
|
681
682
|
interrupt and on `SIGTERM`.
|
|
682
683
|
|
|
683
684
|
1. **Lock.** One ground to its state.
|
|
684
|
-
2. **
|
|
685
|
-
start.
|
|
686
|
-
3. **Drawer.**
|
|
687
|
-
4. **
|
|
688
|
-
|
|
689
|
-
5. **
|
|
690
|
-
|
|
691
|
-
|
|
685
|
+
2. **Primordial.** Its unlock, its ledger, crypto and tools go up. Its
|
|
686
|
+
key is read from `state/key`, drawn there on the first start.
|
|
687
|
+
3. **Drawer.** The key opens its drawer in the ledger.
|
|
688
|
+
4. **Entries.** The drawer's entries join the defaults its environment
|
|
689
|
+
gives, the drawer's winning by name.
|
|
690
|
+
5. **Ladder.** Each body is installed where its entry is new, and goes
|
|
691
|
+
up. One that fails stays down, and says why.
|
|
692
|
+
6. **Houses.** Each house of the drawer opens on its bodies, and its
|
|
693
|
+
door joins the carry.
|
|
694
|
+
7. **Ready.** The hand takes its socket, and it tells systemd it is up.
|
|
692
695
|
|
|
693
696
|
It is set by its environment.
|
|
694
697
|
|
|
@@ -714,7 +717,7 @@ lost key is a lost ground.
|
|
|
714
717
|
|
|
715
718
|
The ladder stands once, and the ground stands it again at every start.
|
|
716
719
|
The first entry stands the folder's `recipe.ts` as a registry, by the
|
|
717
|
-
ground's own
|
|
720
|
+
ground's own faculty `module`. The second raises the payments from it.
|
|
718
721
|
|
|
719
722
|
```bash
|
|
720
723
|
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
@@ -727,19 +730,21 @@ npx nervur faculties add name=payments from=recipe make=payments
|
|
|
727
730
|
A house is added once, and the ground opens it again at every start.
|
|
728
731
|
|
|
729
732
|
```bash
|
|
730
|
-
npx nervur houses add name=shop classes='{"
|
|
733
|
+
npx nervur houses add name=shop classes='{"faculty":"folder","at":"classes"}' faculties='["payments"]'
|
|
731
734
|
```
|
|
732
735
|
|
|
733
|
-
`classes` names the body
|
|
734
|
-
own, and a registry may add more, a git repository among
|
|
735
|
-
keeps its rows in the ground's ledger unless its entry
|
|
736
|
-
|
|
737
|
-
faculty's entry names in `kinds` the classes that hold
|
|
736
|
+
`classes` names the faculty whose body serves the house's code. `folder`
|
|
737
|
+
is the ground's own, and a registry may add more, a git repository among
|
|
738
|
+
them. A house keeps its rows in the ground's ledger unless its entry
|
|
739
|
+
names a `memory` faculty. `faculties` names what the house receives, and
|
|
740
|
+
within it each faculty's entry names in `kinds` the classes that hold
|
|
741
|
+
it. `houses update` and `faculties update` land a new entry in one
|
|
742
|
+
write, and `faculties restart` takes a body down and up again.
|
|
738
743
|
|
|
739
744
|
A secret reaches a faculty the same way, and never through the
|
|
740
745
|
environment. `npx nervur secrets set -` reads `{ name, value }` from
|
|
741
746
|
standard input into the ground's sealed drawer. A faculty's entry names
|
|
742
|
-
the secrets its
|
|
747
|
+
the secrets its `up` receives in `secrets`.
|
|
743
748
|
|
|
744
749
|
### The hand
|
|
745
750
|
|
|
@@ -811,10 +816,10 @@ in a named house.
|
|
|
811
816
|
|
|
812
817
|
Its bodies are the browser's. The ground's key is sealed under an AES
|
|
813
818
|
key that IndexedDB holds unextractable, and its memory is IndexedDB.
|
|
814
|
-
Classes load from the page's own origin through the `origin`
|
|
815
|
-
|
|
816
|
-
refused. The registry is the object you pass:
|
|
817
|
-
|
|
819
|
+
Classes load from the page's own origin through the `origin` faculty, `{
|
|
820
|
+
faculty: 'origin', at: '/house/index.js' }`, and a path off the origin
|
|
821
|
+
is refused. The registry is the object you pass: faculties by name,
|
|
822
|
+
foundation and custom alike, beside the terrain's own.
|
|
818
823
|
|
|
819
824
|
Any script on the origin can use the ground's keys, so the ground is
|
|
820
825
|
whoever serves the origin's script. Give it an origin of its own, serve
|
|
@@ -841,7 +846,7 @@ app's web view, on two interfaces the shell fills in native code:
|
|
|
841
846
|
The library holds the rest. The ground's key goes into the secret store,
|
|
842
847
|
and its memory into the native store, which the system never evicts as
|
|
843
848
|
it may a web view's storage. A push token reaches the ground through a
|
|
844
|
-
faculty your registry
|
|
849
|
+
faculty your registry holds.
|
|
845
850
|
|
|
846
851
|
## What the house guarantees
|
|
847
852
|
|
|
@@ -899,7 +904,8 @@ at her call, or where an ask arrives.
|
|
|
899
904
|
- A call on the house beside `House.open`, `door` and `ask`.
|
|
900
905
|
- A faculty in a house's code. Faculties are the ground's.
|
|
901
906
|
- A drawer opened with a key that did not seal it.
|
|
902
|
-
- A secret read by a being, a describe or anyone but a
|
|
903
|
-
names.
|
|
907
|
+
- A secret read by a being, a describe or anyone but a faculty whose
|
|
908
|
+
entry names it.
|
|
909
|
+
- A faculty raised any way but its `up`, foundation or custom.
|
|
904
910
|
- A faculty entry for `secrets` or `moves`, which the hand alone reaches.
|
|
905
911
|
- A ground an owner must write. Each terrain's ships.
|
package/COMMAND.md
CHANGED
|
@@ -71,13 +71,15 @@ npx nervur help
|
|
|
71
71
|
|
|
72
72
|
A faculty is called by its name and a method. Named alone, it prints its
|
|
73
73
|
methods. Four faculties are the ground's own. `secrets` keeps a secret
|
|
74
|
-
in the ground's sealed drawer. `faculties`
|
|
75
|
-
its entry names, and `houses` opens a house on its entry.
|
|
74
|
+
in the ground's sealed drawer. `faculties` raises a faculty by the `up`
|
|
75
|
+
its entry names, and `houses` opens a house on its entry. Each takes
|
|
76
|
+
`update` to land a new entry in one write, and `faculties restart`
|
|
77
|
+
takes a body down and up again.
|
|
76
78
|
|
|
77
79
|
```bash
|
|
78
80
|
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
79
81
|
npx nervur faculties add name=payments from=recipe make=payments secrets='["stripe-key"]'
|
|
80
|
-
npx nervur houses add name=main classes='{"
|
|
82
|
+
npx nervur houses add name=main classes='{"faculty":"folder","at":"house"}' faculties='["payments"]'
|
|
81
83
|
```
|
|
82
84
|
|
|
83
85
|
`ask` asks a being of a house, as the house's owner. `--id <being>` names
|
package/FACES.md
CHANGED
|
@@ -106,11 +106,12 @@ tries again acts once.
|
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
108
|
// api.ts
|
|
109
|
-
import type {
|
|
109
|
+
import type { Body, FacultyContext, Handler } from 'nervur';
|
|
110
110
|
import { need, s, type Json } from 'nervur/being';
|
|
111
111
|
|
|
112
112
|
type Answer = Awaited<ReturnType<FacultyContext['call']>>;
|
|
113
113
|
type Entry = { method: string; description?: string; args?: Json; hints?: Json };
|
|
114
|
+
type Calls = Pick<FacultyContext, 'call' | 'describe'>;
|
|
114
115
|
|
|
115
116
|
/** What the steward arms the face with. */
|
|
116
117
|
export const FaceBlueprint = need('face', {
|
|
@@ -124,7 +125,7 @@ export const FaceBlueprint = need('face', {
|
|
|
124
125
|
* asks to an agent as tools.
|
|
125
126
|
*/
|
|
126
127
|
export class Api {
|
|
127
|
-
#context:
|
|
128
|
+
#context: Calls | undefined;
|
|
128
129
|
#signup = '';
|
|
129
130
|
#calls = 0;
|
|
130
131
|
|
|
@@ -134,7 +135,12 @@ export class Api {
|
|
|
134
135
|
return Promise.resolve({ result: null });
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
// Told its house opened: every door's token answers from the first request, after any restart.
|
|
139
|
+
opened(context: Calls): void {
|
|
140
|
+
this.#context = context;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#held(): Calls {
|
|
138
144
|
if (this.#context === undefined) throw new Error('the face is not armed');
|
|
139
145
|
return this.#context;
|
|
140
146
|
}
|
|
@@ -179,8 +185,8 @@ export class Api {
|
|
|
179
185
|
};
|
|
180
186
|
}
|
|
181
187
|
|
|
182
|
-
/** The
|
|
183
|
-
export const apiOffer = (api: Api):
|
|
188
|
+
/** The face as a body. */
|
|
189
|
+
export const apiOffer = (api: Api): Body => ({ blueprint: FaceBlueprint, object: api, handler: api.handler, opened: (context) => api.opened(context) });
|
|
184
190
|
```
|
|
185
191
|
|
|
186
192
|
**The describe maps onto tools by renaming.** An ask is a tool, its
|
|
@@ -190,19 +196,19 @@ tools.
|
|
|
190
196
|
|
|
191
197
|
## The registry
|
|
192
198
|
|
|
193
|
-
The ground
|
|
194
|
-
NodeGround stands the module below with the
|
|
195
|
-
face from it by an entry that names `from`. The
|
|
196
|
-
`face` among its faculties, and the steward's `arm`
|
|
197
|
-
signup.
|
|
199
|
+
The ground raises the face from a registry by its `up`, as it raises any
|
|
200
|
+
faculty. A NodeGround stands the module below with the faculty
|
|
201
|
+
`module`, and the face from it by an entry that names `from`. The
|
|
202
|
+
house's entry names `face` among its faculties, and the steward's `arm`
|
|
203
|
+
hands the face its signup.
|
|
198
204
|
|
|
199
205
|
```ts
|
|
200
206
|
// recipe.ts
|
|
201
207
|
import { Api, apiOffer } from './api.ts';
|
|
202
208
|
|
|
203
|
-
// A registry: the ground
|
|
209
|
+
// A registry: the ground raises the face by its `up` when an entry names it.
|
|
204
210
|
export const faculties = {
|
|
205
|
-
face: () => apiOffer(new Api()),
|
|
211
|
+
face: { up: () => apiOffer(new Api()) },
|
|
206
212
|
};
|
|
207
213
|
```
|
|
208
214
|
|
package/FACULTIES.md
CHANGED
|
@@ -15,11 +15,13 @@ the package's own tests run.
|
|
|
15
15
|
## What a faculty owes
|
|
16
16
|
|
|
17
17
|
A faculty answers a blueprint: a name, and methods with their schemas.
|
|
18
|
-
A
|
|
19
|
-
|
|
18
|
+
A registry holds it by name as `{ up, install? }`. The ground raises it
|
|
19
|
+
by its `up` into a body, and hands the body to its houses as an offer,
|
|
20
|
+
with the kinds its entry grants.
|
|
20
21
|
|
|
21
22
|
```text
|
|
22
|
-
faculty = {
|
|
23
|
+
faculty = { install?, up }
|
|
24
|
+
body = { blueprint?, object?, window?, handler?, registry?, down? }
|
|
23
25
|
offer = { blueprint, object, kinds?, window? }
|
|
24
26
|
```
|
|
25
27
|
|
|
@@ -45,7 +47,7 @@ answered, with the same call id every time.
|
|
|
45
47
|
So one call arrives more than once. A reply lost on its way back brings
|
|
46
48
|
it again, and so does a program that died before it answered. A faculty
|
|
47
49
|
that changes the world keeps each call id with the answer it gave, in
|
|
48
|
-
the memory its
|
|
50
|
+
the memory its `up` receives, where a restart and a move keep it. It
|
|
49
51
|
answers a call id it has seen with that answer, and acts once.
|
|
50
52
|
|
|
51
53
|
It keeps them for its `window`, seven days where the offer names none.
|
|
@@ -84,10 +86,10 @@ reaches her through a standing, so policy is written as a being.
|
|
|
84
86
|
|
|
85
87
|
### It lives in the ground
|
|
86
88
|
|
|
87
|
-
The object arrives living. The ground
|
|
88
|
-
name, awaiting its
|
|
89
|
-
it. Every being whose need it covers holds the same object.
|
|
90
|
-
receives
|
|
89
|
+
The object arrives living. The ground raises each faculty its entries
|
|
90
|
+
name, awaiting its `up`, and the house never starts, stops or restarts
|
|
91
|
+
it. Every being whose need it covers holds the same object. Its `up`
|
|
92
|
+
receives four things beside the faculty's name.
|
|
91
93
|
|
|
92
94
|
- **`args`** are its entry's, as the owner wrote them.
|
|
93
95
|
- **`secrets`** are the secrets its entry names, set through the hand
|
|
@@ -95,20 +97,31 @@ receives three things beside the faculty's name.
|
|
|
95
97
|
- **`memory`** is the faculty's own, a view of the ground's memory
|
|
96
98
|
sealed under a key the ground derives for it. Its call ids live there,
|
|
97
99
|
so they move with the ground.
|
|
100
|
+
- **`faculties`** holds the object of each body its entry names in
|
|
101
|
+
`faculties`, so one body calls another directly. It goes up after
|
|
102
|
+
each of them.
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
`install` receives the same, and does the slow work once for each entry.
|
|
105
|
+
A program's packages and a repository's checkout are installed there, so
|
|
106
|
+
going up again installs nothing.
|
|
107
|
+
|
|
108
|
+
A body answers four things beside its methods, each where it has one.
|
|
101
109
|
|
|
102
110
|
- **`handler`** answers HTTP on the ground's one listener. It takes a
|
|
103
111
|
`Request` and answers a `Response`, or `null` where the request is not
|
|
104
|
-
its own. A site, an API or an MCP server is a
|
|
105
|
-
- **`
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
its own. A site, an API or an MCP server is a body with a handler.
|
|
113
|
+
- **`down`** lets go of what its `up` opened. The ground calls it when
|
|
114
|
+
the body is updated, restarted or removed, and when the ground stops,
|
|
115
|
+
bodies in the reverse of the order they stood.
|
|
116
|
+
- **`registry`** holds more faculties, for every entry that names this
|
|
117
|
+
body in `from`. A module of code, a git repository and a program's
|
|
118
|
+
catalogue are each a registry.
|
|
110
119
|
- **`window`** is how long it remembers a call id.
|
|
111
120
|
|
|
121
|
+
The hand changes a body. `faculties update` lands a new entry, and the
|
|
122
|
+
body goes down and up on it. `faculties restart` takes it down and up on
|
|
123
|
+
the same entry. Each house that names it opens again.
|
|
124
|
+
|
|
112
125
|
## Three ways to wrap a program
|
|
113
126
|
|
|
114
127
|
| Way | What the object is | What a crash takes |
|
|
@@ -120,7 +133,7 @@ one.
|
|
|
120
133
|
## The bridge
|
|
121
134
|
|
|
122
135
|
`bridge({ command, args, env, cwd, memory })` from `nervur/node` starts
|
|
123
|
-
a program and answers a
|
|
136
|
+
a program and answers a body. A NodeGround raises one by its faculty
|
|
124
137
|
`bridge`, from its entry alone. The program may be written in any
|
|
125
138
|
language. It speaks one JSON value a line on its standard streams.
|
|
126
139
|
|
|
@@ -143,7 +156,7 @@ in { id, result } | { id, error } the ground's answer to that
|
|
|
143
156
|
the same every time that call is sent, in every life of the program.
|
|
144
157
|
A handle called with no `call` is refused.
|
|
145
158
|
- **It starts with an empty environment.** It holds only what `env`
|
|
146
|
-
names, so it never reads the ground's key. The
|
|
159
|
+
names, so it never reads the ground's key. The faculty `bridge` names
|
|
147
160
|
there the secrets of its entry, each under its name.
|
|
148
161
|
- **It keeps its state in the faculty's memory.** A memory line names
|
|
149
162
|
`read`, `list` or `write` and the memory's args, every entry's bytes
|
|
@@ -365,8 +378,8 @@ it later, once.
|
|
|
365
378
|
|
|
366
379
|
The Pi's folder holds the program and a folder of classes for its
|
|
367
380
|
house, and no code of the ground's. The relay stands from its entry,
|
|
368
|
-
|
|
369
|
-
class alone.
|
|
381
|
+
raised by the NodeGround's own faculty `bridge`, and granted to the
|
|
382
|
+
twin's class alone.
|
|
370
383
|
|
|
371
384
|
```bash
|
|
372
385
|
npx nervur faculties add name=relay make=bridge args='{"command":"python3","args":["relay.py"]}' kinds='["org.example.garage"]'
|
|
@@ -376,7 +389,7 @@ The house is added once, and names the relay among the faculties it
|
|
|
376
389
|
receives.
|
|
377
390
|
|
|
378
391
|
```bash
|
|
379
|
-
npx nervur houses add name=garage classes='{"
|
|
392
|
+
npx nervur houses add name=garage classes='{"faculty":"folder","at":"classes"}' faculties='["relay"]'
|
|
380
393
|
```
|
|
381
394
|
|
|
382
395
|
Both entries rest sealed in the ground's drawer, so the ground stands
|
|
@@ -423,16 +436,16 @@ serve(Doorbell, {
|
|
|
423
436
|
});
|
|
424
437
|
```
|
|
425
438
|
|
|
426
|
-
Its entry
|
|
427
|
-
args `["doorbell.js"]`. A faculty that needs no process of its own
|
|
428
|
-
plain object
|
|
439
|
+
Its entry raises it with the faculty `bridge`, its command `node` and
|
|
440
|
+
its args `["doorbell.js"]`. A faculty that needs no process of its own
|
|
441
|
+
is a plain object its `up` answers instead, as the shop's payments
|
|
429
442
|
are in [Writing for nervur](AUTHORING.md).
|
|
430
443
|
|
|
431
444
|
## Testing a faculty
|
|
432
445
|
|
|
433
446
|
A faculty is tested on BenchGround, the ground in memory from
|
|
434
447
|
`nervur/bench`, with the program itself behind the bridge. The test
|
|
435
|
-
hands the bench a registry whose
|
|
448
|
+
hands the bench a registry whose `bridge` faculty bridges the program, as a
|
|
436
449
|
NodeGround's own does, and stands the relay through the ground's hand,
|
|
437
450
|
as an owner does. A `FakeNetwork` joins
|
|
438
451
|
grounds and loses what the test tells it to lose, and its one clock
|
|
@@ -476,7 +489,7 @@ test('Each tap on the phone pulses the relay once, whatever fails between', { ti
|
|
|
476
489
|
host: 'pi',
|
|
477
490
|
names: ['garage.local'],
|
|
478
491
|
modules: { pi },
|
|
479
|
-
registry: { faculties: { bridge: ({ memory }) => bridge({ command: 'python3', args: [relay], cwd: pin, memory }) } },
|
|
492
|
+
registry: { faculties: { bridge: { up: ({ memory }) => bridge({ command: 'python3', args: [relay], cwd: pin, memory }) } } },
|
|
480
493
|
});
|
|
481
494
|
t.after(() => garage.down());
|
|
482
495
|
// The relay, granted to the twin's class alone.
|
package/GROUNDS.md
CHANGED
|
@@ -26,35 +26,52 @@ house seals its own rows, and the ground seals each faculty's. So what
|
|
|
26
26
|
rests on the disk is ciphertext, and copying the key, the memory and the
|
|
27
27
|
code moves the whole ground.
|
|
28
28
|
|
|
29
|
-
**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
**Every faculty has one lifecycle.** A registry holds faculties by name,
|
|
30
|
+
each an object `{ up, install? }`. Standing a faculty raises it by its
|
|
31
|
+
`up` into a body, the living instance houses and other bodies use.
|
|
32
|
+
`install` does the slow work once for each entry. A body's `down` lets
|
|
33
|
+
go of what its `up` opened. A foundation body says what it `serves`: a
|
|
34
|
+
carry, the clock, or each house's memory or code.
|
|
35
|
+
|
|
36
|
+
**It stands its bodies on a ladder.** The ground's own registry is its
|
|
37
|
+
terrain's. A body may carry a registry of its own, and the faculties an
|
|
38
|
+
entry raises `from` it stand after it. A body stands after each body its
|
|
39
|
+
entry names in `faculties`, whose objects its `up` receives. A body that
|
|
40
|
+
fails to stand stays down and says why, and the ground boots beside it.
|
|
41
|
+
|
|
42
|
+
**Its terrain names default entries, and the drawer's win.** Each ground
|
|
43
|
+
stands its clock, its carries and its bodies of code from entries of its
|
|
44
|
+
own. An entry of the same name in the drawer stands in its place.
|
|
34
45
|
|
|
35
46
|
```text
|
|
36
47
|
recipe { make: 'module', args: { at: 'recipe.ts' } }
|
|
37
48
|
payments { from: 'recipe', make: 'payments', secrets: ['stripe-key'], kinds: ['com.acme.order'] }
|
|
38
49
|
```
|
|
39
50
|
|
|
40
|
-
**It opens each house on its entry.** An entry names the body
|
|
41
|
-
house's code, the custom faculties it may use, and the
|
|
42
|
-
its asks may run. It names a body
|
|
43
|
-
its places apart from the ground's memory.
|
|
51
|
+
**It opens each house on its entry.** An entry names the body that
|
|
52
|
+
serves the house's code, the custom faculties it may use, and the
|
|
53
|
+
longest any of its asks may run. It names a body serving memory only
|
|
54
|
+
where the house keeps its places apart from the ground's memory. Beside
|
|
55
|
+
each body's name, it holds the args that body hands this house.
|
|
44
56
|
|
|
45
57
|
```text
|
|
46
|
-
shop { classes: {
|
|
58
|
+
shop { classes: { faculty: 'folder', at: 'shop' }, faculties: ['payments'], wait: 60000 }
|
|
47
59
|
```
|
|
48
60
|
|
|
61
|
+
**It updates an entry in one write.** `update` lands the new entry over
|
|
62
|
+
the old. A house closes and opens again on it, as the same ward. A body
|
|
63
|
+
goes down, installs where its entry moved, and goes up, and each house
|
|
64
|
+
naming it opens again. `restart` takes a body down and up on its entry.
|
|
65
|
+
|
|
49
66
|
**It grants a faculty in two steps.** A house uses only the faculties its
|
|
50
67
|
entry names. Inside it, a being holds one only where the faculty's entry
|
|
51
68
|
names her class in `kinds`, or where it names none. So a raw shell
|
|
52
69
|
reaches one house and one class inside it.
|
|
53
70
|
|
|
54
|
-
**It hands each
|
|
55
|
-
and kept in the drawer. A faculty's entry names the secrets its
|
|
71
|
+
**It hands each faculty its secrets.** A secret is set through the hand
|
|
72
|
+
and kept in the drawer. A faculty's entry names the secrets its `up`
|
|
56
73
|
receives, and no other code reads one. The hand lists their names, and
|
|
57
|
-
never a value.
|
|
74
|
+
never a value. A changed secret reaches a body when it goes up again.
|
|
58
75
|
|
|
59
76
|
**It hooks every door and runs one listener.** Each house's door goes to
|
|
60
77
|
the ground's carry, which also delivers between the ground's own houses
|
|
@@ -68,8 +85,8 @@ as the house's owner. Four faculties are the ground's own.
|
|
|
68
85
|
|
|
69
86
|
| Faculty | Its methods | Who reaches it |
|
|
70
87
|
| --- | --- | --- |
|
|
71
|
-
| `houses` | `add`, `remove`, `list` | the hand, and the kinds its entry grants |
|
|
72
|
-
| `faculties` | `add`, `remove`, `list` | the hand, and the kinds its entry grants |
|
|
88
|
+
| `houses` | `add`, `update`, `remove`, `list` | the hand, and the kinds its entry grants |
|
|
89
|
+
| `faculties` | `add`, `update`, `restart`, `remove`, `list` | the hand, and the kinds its entry grants |
|
|
73
90
|
| `secrets` | `set`, `remove`, `list` | the hand alone |
|
|
74
91
|
| `moves` | `out`, `in` | the hand alone |
|
|
75
92
|
|
|
@@ -108,11 +125,18 @@ shows. The ground's folder is an ES module package, so its
|
|
|
108
125
|
port is set, on the web. [The command](COMMAND.md) lists its settings
|
|
109
126
|
and runs its hand.
|
|
110
127
|
|
|
111
|
-
**Its registry
|
|
112
|
-
classes from a folder inside it.
|
|
113
|
-
inside it as a registry, whose `faculties
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
**Its registry holds its terrain's faculties.** `folder` serves each
|
|
129
|
+
house its classes from a folder inside it. `module` imports a module
|
|
130
|
+
inside it as a registry, whose `faculties` export holds `{ up, install? }`
|
|
131
|
+
by name. `bridge` starts a program, in any language, and hands it the
|
|
132
|
+
secrets its entry names as its environment. `tcp` and `web` are its
|
|
133
|
+
carries, and `clock` its clock.
|
|
134
|
+
|
|
135
|
+
**Its environment gives the default entries.** `clock`, `folder`, `tcp`
|
|
136
|
+
and `web` stand from entries its settings write. An entry of the same
|
|
137
|
+
name in the drawer stands in their place, so a port changes through the
|
|
138
|
+
hand. A `tcp` entry whose args name no port only dials, and its
|
|
139
|
+
invitations name no TCP address.
|
|
116
140
|
|
|
117
141
|
**Its key rests in `state/key`, its owner's alone.** A key file others
|
|
118
142
|
may read is refused, as ssh refuses a key. On macOS,
|
|
@@ -151,9 +175,9 @@ export default EdgeGround.worker();
|
|
|
151
175
|
```
|
|
152
176
|
|
|
153
177
|
The Worker binds the object's class as `GROUND`, with SQLite storage.
|
|
154
|
-
`registry` joins the terrain's own, so an entry
|
|
155
|
-
`from`. A house's entry names its code with `classes: {
|
|
156
|
-
at: 'shop' }`.
|
|
178
|
+
`registry` joins the terrain's own, so an entry raises `payments` with
|
|
179
|
+
no `from`. A house's entry names its code with `classes: { faculty:
|
|
180
|
+
'bundle', at: 'shop' }`.
|
|
157
181
|
|
|
158
182
|
**Its settings are the Worker's.**
|
|
159
183
|
|
|
@@ -167,8 +191,9 @@ at: 'shop' }`.
|
|
|
167
191
|
| `NERVUR_WAIT` | the longest any ask may run, a minute where unset |
|
|
168
192
|
|
|
169
193
|
A Worker learns no name it is reached by, so it writes only the
|
|
170
|
-
addresses `NERVUR_ADDRESSES` names.
|
|
171
|
-
|
|
194
|
+
addresses `NERVUR_ADDRESSES` names. These settings give the default
|
|
195
|
+
entry of its web carry, and an entry in the drawer stands in its place.
|
|
196
|
+
Its faculties take their secrets from its drawer, as on every ground.
|
|
172
197
|
|
|
173
198
|
**Its hand answers its key alone.** The hand is `POST /nervur/hand`, with
|
|
174
199
|
the key as a bearer token and one request as the body. Every other
|
|
@@ -196,8 +221,8 @@ ground, so its origin serves nothing else.
|
|
|
196
221
|
[The package's start](README.md) opens one in a page.
|
|
197
222
|
|
|
198
223
|
**Its registry is the one the page hands.** `BrowserGround.open({
|
|
199
|
-
registry })` joins it to the terrain's own, whose
|
|
200
|
-
house
|
|
224
|
+
registry })` joins it to the terrain's own, whose faculty `origin`
|
|
225
|
+
serves each house its classes from the origin.
|
|
201
226
|
|
|
202
227
|
**An AppGround is a BrowserGround with the shell's bodies.** The shell
|
|
203
228
|
hands in two small interfaces, one for secrets and one for a store, and
|
package/README.md
CHANGED
|
@@ -100,7 +100,7 @@ In a second shell, add the house once. The ground keeps its entry in its
|
|
|
100
100
|
sealed drawer, and opens it again at every start.
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
|
-
npx nervur houses add name=main classes='{"
|
|
103
|
+
npx nervur houses add name=main classes='{"faculty":"folder","at":"house"}'
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
Then ask the steward through the ground's hand.
|
|
@@ -132,7 +132,7 @@ const ground = await BrowserGround.open();
|
|
|
132
132
|
await ground.hand({
|
|
133
133
|
faculty: 'houses',
|
|
134
134
|
method: 'add',
|
|
135
|
-
args: { name: 'main', classes: {
|
|
135
|
+
args: { name: 'main', classes: { faculty: 'origin', at: '/house/index.js' } },
|
|
136
136
|
});
|
|
137
137
|
|
|
138
138
|
console.log(await ground.hand({ house: 'main', method: 'hello', args: { name: 'Ada' } }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClassList, Ground, type
|
|
1
|
+
import { ClassList, Ground, type Body, type Registry } from '../index.ts';
|
|
2
2
|
import { FakeMemory } from './fake-memory.ts';
|
|
3
3
|
import { type FakeNetwork } from './fake-network.ts';
|
|
4
4
|
import { FakeUnlock } from './fake-unlock.ts';
|
|
@@ -13,8 +13,8 @@ export interface HouseModule {
|
|
|
13
13
|
readonly public?: BeingClass;
|
|
14
14
|
readonly beings?: readonly BeingClass[];
|
|
15
15
|
}
|
|
16
|
-
/** A
|
|
17
|
-
export type Living =
|
|
16
|
+
/** A body the test writes, living, with the kinds it is granted. */
|
|
17
|
+
export type Living = Body & {
|
|
18
18
|
readonly kinds?: readonly string[];
|
|
19
19
|
};
|
|
20
20
|
/** What a ground keeps across its lives: its key, its randomness, its memory, and each house's own where it names the `fake` body. */
|