nervur 0.22.2-6 → 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 +81 -45
- package/COMMAND.md +27 -10
- package/FACES.md +29 -12
- package/FACULTIES.md +178 -94
- package/GROUNDS.md +144 -66
- package/KIT-SPEC.md +10 -7
- package/README.md +16 -14
- package/dist/app/app-ground.d.ts +1 -1
- package/dist/app/app-ground.js +5 -5
- package/dist/app/index.d.ts +1 -1
- package/dist/app/index.js +1 -1
- package/dist/app/native.d.ts +3 -3
- package/dist/app/native.js +3 -3
- package/dist/bench/bench-ground.d.ts +18 -14
- package/dist/bench/bench-ground.js +61 -46
- package/dist/bench/fake-unlock.d.ts +6 -0
- package/dist/bench/fake-unlock.js +10 -0
- package/dist/bodies/kept.d.ts +5 -16
- package/dist/bodies/kept.js +17 -36
- package/dist/browser/browser-ground.d.ts +8 -16
- package/dist/browser/browser-ground.js +47 -38
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/locked-unlock.d.ts +24 -0
- package/dist/browser/locked-unlock.js +85 -0
- package/dist/edge/edge-ground.d.ts +8 -17
- package/dist/edge/edge-ground.js +57 -48
- package/dist/edge/index.d.ts +2 -2
- package/dist/edge/index.js +1 -1
- package/dist/edge/secret-unlock.d.ts +7 -0
- package/dist/edge/secret-unlock.js +13 -0
- package/dist/ground/ground.d.ts +249 -111
- package/dist/ground/ground.js +864 -357
- package/dist/ground/views.d.ts +59 -0
- package/dist/ground/views.js +188 -0
- package/dist/house/house.d.ts +8 -0
- package/dist/house/house.js +12 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/node/bridge.d.ts +6 -3
- package/dist/node/bridge.js +68 -7
- package/dist/node/cli.js +32 -19
- package/dist/node/index.d.ts +2 -4
- package/dist/node/index.js +1 -3
- package/dist/node/node-ground.d.ts +11 -20
- package/dist/node/node-ground.js +200 -92
- package/dist/node/tcp-carry.d.ts +2 -2
- package/dist/node/tcp-carry.js +6 -4
- package/dist/node/unlock.d.ts +17 -0
- package/dist/node/unlock.js +86 -0
- package/dist/serve/index.d.ts +20 -7
- package/dist/serve/index.js +21 -9
- package/package.json +1 -1
- package/dist/bench/fake-custody.d.ts +0 -15
- package/dist/bench/fake-custody.js +0 -39
- package/dist/bench/fake-keys.d.ts +0 -4
- package/dist/bench/fake-keys.js +0 -9
- package/dist/browser/locked-custody.d.ts +0 -36
- package/dist/browser/locked-custody.js +0 -114
- package/dist/edge/secret-custody.d.ts +0 -6
- package/dist/edge/secret-custody.js +0 -40
- package/dist/node/custody.d.ts +0 -34
- package/dist/node/custody.js +0 -58
- package/dist/node/file-keys.d.ts +0 -11
- package/dist/node/file-keys.js +0 -44
- package/dist/node/held-keys.d.ts +0 -14
- package/dist/node/held-keys.js +0 -36
- package/dist/node/keychain-keys.d.ts +0 -12
- package/dist/node/keychain-keys.js +0 -55
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
|
|
|
@@ -31,7 +31,9 @@ The shop has three classes and one faculty.
|
|
|
31
31
|
| role | a named test over the asker and her cells |
|
|
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
|
-
| ground | the process houses run in, holding their seeds, faculties and
|
|
34
|
+
| ground | the process houses run in, holding one key and sealing their seeds, faculties and secrets under it |
|
|
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 |
|
|
35
37
|
|
|
36
38
|
## A being
|
|
37
39
|
|
|
@@ -587,7 +589,8 @@ type Answer = { result: { pending: boolean } } | { error: { message: string } };
|
|
|
587
589
|
/**
|
|
588
590
|
* A payment provider in the ground's process. It answers a call id it has
|
|
589
591
|
* seen with the answer it gave, so an effect sent twice charges once. A
|
|
590
|
-
* provider that changes the world keeps these
|
|
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.
|
|
591
594
|
*/
|
|
592
595
|
export class Payments {
|
|
593
596
|
readonly #answered = new Map<string, Answer>();
|
|
@@ -615,28 +618,31 @@ export class Payments {
|
|
|
615
618
|
export const paymentsOffer = (payments: Payments): Offer => ({ blueprint: PaymentsBlueprint, object: payments, window: 7 * 86_400_000 });
|
|
616
619
|
```
|
|
617
620
|
|
|
618
|
-
An offer is `{ blueprint, object, kinds?, window
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
621
|
+
An offer is `{ blueprint, object, kinds?, window? }`. The object answers
|
|
622
|
+
each call with its call id, and one that changes the world answers a
|
|
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.
|
|
624
628
|
|
|
625
629
|
```ts
|
|
626
630
|
// recipe.ts
|
|
627
631
|
import { Payments, paymentsOffer } from './payments.ts';
|
|
628
632
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}
|
|
633
|
+
// A registry: the ground raises each faculty an entry names by its `up` here.
|
|
634
|
+
export const faculties = {
|
|
635
|
+
payments: { up: () => paymentsOffer(new Payments()) },
|
|
636
|
+
};
|
|
632
637
|
```
|
|
633
638
|
|
|
634
639
|
## A ground
|
|
635
640
|
|
|
636
641
|
A ground is the process houses run in, and you write none. `nervur up`
|
|
637
|
-
runs one on a folder:
|
|
638
|
-
|
|
639
|
-
|
|
642
|
+
runs one on a folder of code: a folder for each house, and each module
|
|
643
|
+
your entries name. It holds one key in `state/`, and keeps every entry
|
|
644
|
+
sealed in its drawer: which faculties stand, and which houses open on
|
|
645
|
+
which bodies.
|
|
640
646
|
|
|
641
647
|
### The shop's folder
|
|
642
648
|
|
|
@@ -676,11 +682,16 @@ The ground boots in one order, and a stop is that order reversed, on an
|
|
|
676
682
|
interrupt and on `SIGTERM`.
|
|
677
683
|
|
|
678
684
|
1. **Lock.** One ground to its state.
|
|
679
|
-
2. **
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
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.
|
|
684
695
|
|
|
685
696
|
It is set by its environment.
|
|
686
697
|
|
|
@@ -693,26 +704,47 @@ It is set by its environment.
|
|
|
693
704
|
| `NERVUR_ALLOW_PRIVATE` | `1` to dial private and loopback addresses, as two grounds on one machine do |
|
|
694
705
|
| `NERVUR_BIND` | the address it listens on, `0.0.0.0` where unset |
|
|
695
706
|
| `NERVUR_STATE` | its state, `state/` in its folder where unset |
|
|
696
|
-
| `
|
|
707
|
+
| `NERVUR_UNLOCK` | `keychain:<account>` keeps its key in the macOS keychain, in place of `state/key` |
|
|
697
708
|
| `NERVUR_WAIT` | its bound on every ask, in milliseconds |
|
|
698
709
|
|
|
699
|
-
The state holds
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
710
|
+
The state holds the key in a file its owner alone reads, and the
|
|
711
|
+
ground's ledger. Every house keeps its rows in that ledger, sealed. A
|
|
712
|
+
ledger appends every write and never rewrites one. Its witness keeps
|
|
713
|
+
where it last stood, and a ledger behind its witness is refused. So a
|
|
714
|
+
ledger restored alone cannot replay what a house already answered,
|
|
715
|
+
though a whole state folder restored with its witness is not seen. A
|
|
716
|
+
lost key is a lost ground.
|
|
717
|
+
|
|
718
|
+
The ladder stands once, and the ground stands it again at every start.
|
|
719
|
+
The first entry stands the folder's `recipe.ts` as a registry, by the
|
|
720
|
+
ground's own faculty `module`. The second raises the payments from it.
|
|
721
|
+
|
|
722
|
+
```bash
|
|
723
|
+
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
```bash
|
|
727
|
+
npx nervur faculties add name=payments from=recipe make=payments
|
|
728
|
+
```
|
|
705
729
|
|
|
706
730
|
A house is added once, and the ground opens it again at every start.
|
|
707
731
|
|
|
708
732
|
```bash
|
|
709
|
-
npx nervur houses add name=shop
|
|
733
|
+
npx nervur houses add name=shop classes='{"faculty":"folder","at":"classes"}' faculties='["payments"]'
|
|
710
734
|
```
|
|
711
735
|
|
|
712
|
-
`
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
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.
|
|
743
|
+
|
|
744
|
+
A secret reaches a faculty the same way, and never through the
|
|
745
|
+
environment. `npx nervur secrets set -` reads `{ name, value }` from
|
|
746
|
+
standard input into the ground's sealed drawer. A faculty's entry names
|
|
747
|
+
the secrets its `up` receives in `secrets`.
|
|
716
748
|
|
|
717
749
|
### The hand
|
|
718
750
|
|
|
@@ -774,7 +806,7 @@ with `loginctl enable-linger`. On macOS, the agent goes to
|
|
|
774
806
|
|
|
775
807
|
### In a page
|
|
776
808
|
|
|
777
|
-
`BrowserGround.open({
|
|
809
|
+
`BrowserGround.open({ registry })` from `nervur/browser` runs the same
|
|
778
810
|
houses in a page. Every tab and the service worker of one origin share
|
|
779
811
|
one ground: the one holding the Web Lock runs it, and the others reach
|
|
780
812
|
its hand over a `BroadcastChannel`. When it closes, the next opens the
|
|
@@ -782,12 +814,12 @@ ground from the same storage. `hand` answers the same three requests
|
|
|
782
814
|
the command sends: `describe`, a faculty's method, and an ask of a being
|
|
783
815
|
in a named house.
|
|
784
816
|
|
|
785
|
-
Its bodies are the browser's.
|
|
786
|
-
IndexedDB holds unextractable, and memory is IndexedDB
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
817
|
+
Its bodies are the browser's. The ground's key is sealed under an AES
|
|
818
|
+
key that IndexedDB holds unextractable, and its memory is IndexedDB.
|
|
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.
|
|
791
823
|
|
|
792
824
|
Any script on the origin can use the ground's keys, so the ground is
|
|
793
825
|
whoever serves the origin's script. Give it an origin of its own, serve
|
|
@@ -811,10 +843,10 @@ app's web view, on two interfaces the shell fills in native code:
|
|
|
811
843
|
which lands every write only where each key in `expect` still holds
|
|
812
844
|
what it names, and answers whether it landed.
|
|
813
845
|
|
|
814
|
-
The library holds the rest.
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
846
|
+
The library holds the rest. The ground's key goes into the secret store,
|
|
847
|
+
and its memory into the native store, which the system never evicts as
|
|
848
|
+
it may a web view's storage. A push token reaches the ground through a
|
|
849
|
+
faculty your registry holds.
|
|
818
850
|
|
|
819
851
|
## What the house guarantees
|
|
820
852
|
|
|
@@ -871,5 +903,9 @@ at her call, or where an ask arrives.
|
|
|
871
903
|
- A send to a private address, unless its ground allows it.
|
|
872
904
|
- A call on the house beside `House.open`, `door` and `ask`.
|
|
873
905
|
- A faculty in a house's code. Faculties are the ground's.
|
|
874
|
-
- A
|
|
906
|
+
- A drawer opened with a key that did not seal it.
|
|
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.
|
|
910
|
+
- A faculty entry for `secrets` or `moves`, which the hand alone reaches.
|
|
875
911
|
- A ground an owner must write. Each terrain's ships.
|
package/COMMAND.md
CHANGED
|
@@ -7,17 +7,21 @@ have read [the package's start](README.md), which runs a first ground.
|
|
|
7
7
|
|
|
8
8
|
## Starting a ground
|
|
9
9
|
|
|
10
|
-
`nervur up` runs a NodeGround on a folder until it is stopped. The
|
|
11
|
-
holds
|
|
12
|
-
|
|
10
|
+
`nervur up` runs a NodeGround on a folder until it is stopped. The
|
|
11
|
+
folder holds your code: a folder for each house, and each module or
|
|
12
|
+
program your entries name. `state/` holds the ground's key, its ledger
|
|
13
|
+
and its hand. The key is drawn on the first start, into a file your user
|
|
14
|
+
alone reads.
|
|
13
15
|
|
|
14
16
|
```bash
|
|
15
17
|
npx nervur up .
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
The ground stops cleanly on an interrupt and on `SIGTERM`. It takes a
|
|
19
|
-
lock on its
|
|
20
|
-
start.
|
|
21
|
+
lock on its state, so a second `nervur up` on the same folder refuses to
|
|
22
|
+
start. Keep `state/` as you keep an ssh key: whoever holds its key and
|
|
23
|
+
its ledger holds the ground, and without the key the ledger opens
|
|
24
|
+
nothing.
|
|
21
25
|
|
|
22
26
|
`nervur service` prints what keeps the ground running across reboots: a
|
|
23
27
|
systemd unit on Linux, a launchd job on macOS. Nothing is installed; you
|
|
@@ -40,7 +44,7 @@ A ground reads its settings from the environment.
|
|
|
40
44
|
| `NERVUR_ADDRESSES` | the public addresses written into invitations, by commas |
|
|
41
45
|
| `NERVUR_ORIGINS` | the page origins the web listener answers, by commas |
|
|
42
46
|
| `NERVUR_ALLOW_PRIVATE` | `1` to let the ground dial a private or loopback address |
|
|
43
|
-
| `
|
|
47
|
+
| `NERVUR_UNLOCK` | on macOS, `keychain:<account>` keeps the key in the keychain in place of `state/key` |
|
|
44
48
|
| `NERVUR_HAND` | where the hand's socket is, `state/hand` where unset; a relative path is read from where the command runs |
|
|
45
49
|
| `NERVUR_WAIT` | the longest any ask may run, in milliseconds |
|
|
46
50
|
|
|
@@ -58,18 +62,24 @@ Every other word goes to the ground's hand, a socket in `state/` that
|
|
|
58
62
|
your user alone may open. Run the command in the ground's folder, or
|
|
59
63
|
name the socket with `--at <socket>` or `NERVUR_HAND`.
|
|
60
64
|
|
|
61
|
-
`help` prints what the ground holds: each faculty with its methods,
|
|
62
|
-
each house.
|
|
65
|
+
`help` prints what the ground holds: each faculty with its methods, or
|
|
66
|
+
why it is down, and each house.
|
|
63
67
|
|
|
64
68
|
```bash
|
|
65
69
|
npx nervur help
|
|
66
70
|
```
|
|
67
71
|
|
|
68
72
|
A faculty is called by its name and a method. Named alone, it prints its
|
|
69
|
-
methods.
|
|
73
|
+
methods. Four faculties are the ground's own. `secrets` keeps a secret
|
|
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.
|
|
70
78
|
|
|
71
79
|
```bash
|
|
72
|
-
npx nervur
|
|
80
|
+
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
81
|
+
npx nervur faculties add name=payments from=recipe make=payments secrets='["stripe-key"]'
|
|
82
|
+
npx nervur houses add name=main classes='{"faculty":"folder","at":"house"}' faculties='["payments"]'
|
|
73
83
|
```
|
|
74
84
|
|
|
75
85
|
`ask` asks a being of a house, as the house's owner. `--id <being>` names
|
|
@@ -101,6 +111,13 @@ JSON where it reads as JSON, and as text where it does not, so
|
|
|
101
111
|
npx nervur ask main hello '{"name":"Ada"}'
|
|
102
112
|
```
|
|
103
113
|
|
|
114
|
+
A lone `-` reads the one JSON object from standard input instead. So a
|
|
115
|
+
secret never stands on a command line or in a shell's history.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx nervur secrets set - < stripe-key.json
|
|
119
|
+
```
|
|
120
|
+
|
|
104
121
|
Each word prints one JSON value, the answer, and its exit code says what
|
|
105
122
|
came back.
|
|
106
123
|
|
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
|
|
@@ -188,9 +194,11 @@ method the tool's name, its args schema the tool's input schema, and its
|
|
|
188
194
|
hints the tool's annotations. A moved describe is a changed list of
|
|
189
195
|
tools.
|
|
190
196
|
|
|
191
|
-
## The
|
|
197
|
+
## The registry
|
|
192
198
|
|
|
193
|
-
The ground
|
|
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
|
|
194
202
|
house's entry names `face` among its faculties, and the steward's `arm`
|
|
195
203
|
hands the face its signup.
|
|
196
204
|
|
|
@@ -198,15 +206,23 @@ hands the face its signup.
|
|
|
198
206
|
// recipe.ts
|
|
199
207
|
import { Api, apiOffer } from './api.ts';
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
209
|
+
// A registry: the ground raises the face by its `up` when an entry names it.
|
|
210
|
+
export const faculties = {
|
|
211
|
+
face: { up: () => apiOffer(new Api()) },
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
npx nervur faculties add name=recipe make=module args='{"at":"recipe.ts"}'
|
|
217
|
+
npx nervur faculties add name=face from=recipe make=face
|
|
204
218
|
```
|
|
205
219
|
|
|
206
220
|
## Testing it
|
|
207
221
|
|
|
208
222
|
A BenchGround answers a request with its faculties' handlers in turn, as
|
|
209
|
-
a ground's one listener does, so the face is tested with no socket.
|
|
223
|
+
a ground's one listener does, so the face is tested with no socket. The
|
|
224
|
+
test hands the bench the registry, and stands the face through the
|
|
225
|
+
ground's hand, as an owner does.
|
|
210
226
|
|
|
211
227
|
```ts
|
|
212
228
|
// api.test.ts
|
|
@@ -217,8 +233,9 @@ import * as desk from './desk.ts';
|
|
|
217
233
|
import { faculties } from './recipe.ts';
|
|
218
234
|
|
|
219
235
|
test('A person signs up at the face, and reaches their member as an API and as tools', async (t) => {
|
|
220
|
-
const ground = await BenchGround.open({ network: new FakeNetwork(), host: 'desk', modules: { desk },
|
|
236
|
+
const ground = await BenchGround.open({ network: new FakeNetwork(), host: 'desk', modules: { desk }, registry: { faculties } });
|
|
221
237
|
t.after(() => ground.down());
|
|
238
|
+
await ground.hand({ faculty: 'faculties', method: 'add', args: { name: 'face', make: 'face' } });
|
|
222
239
|
await ground.add('desk', 'desk', { faculties: ['face'] });
|
|
223
240
|
await ground.ask({ house: 'desk', method: 'arm' });
|
|
224
241
|
const web = async (path: string, body?: unknown, token?: string) =>
|