nervur 0.22.2-5 → 0.22.2-6
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 +129 -68
- package/COMMAND.md +113 -0
- package/FACES.md +264 -0
- package/FACULTIES.md +487 -0
- package/GROUNDS.md +159 -0
- package/KIT-SPEC.md +16 -1
- package/README.md +16 -9
- package/WORLD.md +195 -0
- package/dist/app/app-ground.d.ts +1 -1
- package/dist/app/app-ground.js +3 -5
- package/dist/app/index.d.ts +1 -1
- package/dist/app/native.d.ts +9 -44
- package/dist/app/native.js +7 -95
- package/dist/being/being.d.ts +84 -7
- package/dist/being/being.js +1 -1
- package/dist/being/index.d.ts +2 -1
- package/dist/being/index.js +1 -0
- package/dist/being/table.d.ts +6 -0
- package/dist/being/table.js +72 -16
- package/dist/bench/bench-ground.d.ts +22 -8
- package/dist/bench/bench-ground.js +29 -6
- package/dist/bench/bench.d.ts +43 -29
- package/dist/bench/bench.js +240 -132
- package/dist/bench/fake-clock.d.ts +1 -1
- package/dist/bench/fake-custody.d.ts +8 -2
- package/dist/bench/fake-custody.js +30 -1
- package/dist/bench/fake-keys.d.ts +1 -2
- package/dist/bench/fake-keys.js +1 -1
- package/dist/bench/fake-memory.d.ts +3 -1
- package/dist/bench/fake-network.d.ts +16 -7
- package/dist/bench/fake-network.js +67 -14
- package/dist/bench/index.d.ts +3 -11
- package/dist/bench/index.js +2 -10
- package/dist/bench/seeded.d.ts +1 -1
- package/dist/bench/seeded.js +1 -1
- package/dist/bench/stewards.d.ts +157 -5
- package/dist/bench/stewards.js +115 -7
- package/dist/bodies/joined-carry.d.ts +7 -1
- package/dist/bodies/joined-carry.js +9 -3
- package/dist/bodies/kept.d.ts +55 -0
- package/dist/bodies/kept.js +110 -0
- package/dist/bodies/vouch.d.ts +20 -0
- package/dist/bodies/vouch.js +71 -0
- package/dist/bodies/web-carry.d.ts +9 -2
- package/dist/bodies/web-carry.js +30 -9
- package/dist/browser/browser-ground.d.ts +17 -2
- package/dist/browser/browser-ground.js +25 -13
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/locked-custody.d.ts +9 -0
- package/dist/browser/locked-custody.js +25 -4
- package/dist/edge/durable-clock.d.ts +19 -0
- package/dist/edge/durable-clock.js +61 -0
- package/dist/edge/durable-memory.d.ts +5 -0
- package/dist/edge/durable-memory.js +11 -0
- package/dist/edge/durable.d.ts +18 -0
- package/dist/edge/durable.js +24 -0
- package/dist/edge/edge-ground.d.ts +58 -0
- package/dist/edge/edge-ground.js +211 -0
- package/dist/edge/index.d.ts +7 -0
- package/dist/edge/index.js +9 -0
- package/dist/edge/native-crypto.d.ts +8 -0
- package/dist/edge/native-crypto.js +102 -0
- package/dist/edge/secret-custody.d.ts +6 -0
- package/dist/edge/secret-custody.js +40 -0
- package/dist/edge/socket-carry.d.ts +39 -0
- package/dist/edge/socket-carry.js +111 -0
- package/dist/foundation.d.ts +12 -0
- package/dist/ground/ground.d.ts +110 -3
- package/dist/ground/ground.js +299 -58
- package/dist/house/crossing.d.ts +18 -6
- package/dist/house/crossing.js +35 -14
- package/dist/house/house.d.ts +26 -28
- package/dist/house/house.js +405 -167
- package/dist/house/rows-shape.d.ts +8 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.js +1 -0
- package/dist/node/bridge.js +49 -14
- package/dist/node/cli.js +13 -4
- package/dist/node/custody.d.ts +14 -0
- package/dist/node/custody.js +28 -4
- package/dist/node/file-keys.d.ts +4 -0
- package/dist/node/file-keys.js +26 -12
- package/dist/node/hand.d.ts +2 -0
- package/dist/node/hand.js +4 -2
- package/dist/node/index.d.ts +5 -5
- package/dist/node/keychain-keys.d.ts +2 -0
- package/dist/node/keychain-keys.js +11 -7
- package/dist/node/node-ground.d.ts +5 -1
- package/dist/node/node-ground.js +19 -10
- package/dist/node/tcp-carry.d.ts +8 -7
- package/dist/node/tcp-carry.js +21 -53
- package/dist/node/websocket.d.ts +8 -2
- package/dist/node/websocket.js +20 -4
- package/dist/quo/frame.d.ts +13 -0
- package/dist/quo/frame.js +44 -0
- package/dist/quo/index.d.ts +1 -0
- package/dist/quo/index.js +5 -0
- package/dist/serve/index.d.ts +8 -3
- package/dist/serve/index.js +9 -5
- package/package.json +12 -2
- package/dist/bench/fake-carry.d.ts +0 -32
- package/dist/bench/fake-carry.js +0 -56
- package/dist/bench/fake-faculty.d.ts +0 -25
- package/dist/bench/fake-faculty.js +0 -48
package/AUTHORING.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Writing for nervur
|
|
2
2
|
|
|
3
3
|
This guide teaches the two things you write with `nervur`. A **being**
|
|
4
|
-
holds logic and state. A **faculty** reaches the world outside
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
package's own tests run.
|
|
4
|
+
holds logic and state. A **faculty** reaches the world outside, and
|
|
5
|
+
[Writing a faculty](FACULTIES.md) teaches it whole. A **ground** runs them on
|
|
6
|
+
a machine, and the library ships it. The examples build one small shop,
|
|
7
|
+
and every file here is a file the package's own tests run.
|
|
8
8
|
|
|
9
9
|
The shop has three classes and one faculty.
|
|
10
10
|
|
|
@@ -169,7 +169,7 @@ JavaScript writes nothing.
|
|
|
169
169
|
| `args` | the schema of what it takes; omitted, the empty object alone |
|
|
170
170
|
| `result` | the schema of what it answers; omitted, nothing |
|
|
171
171
|
| `hints` | `readOnly`, `idempotent`, `destructive` |
|
|
172
|
-
| `examples` |
|
|
172
|
+
| `examples` | a history of her asks, a role, args, fakes, and what it gives |
|
|
173
173
|
| `description` | one line for readers and agents |
|
|
174
174
|
| `wait` | milliseconds she may run; omitted, thirty seconds |
|
|
175
175
|
|
|
@@ -202,6 +202,9 @@ nothing lands.
|
|
|
202
202
|
| `this.house.cancelAlarm({ key })` | an alarm removed |
|
|
203
203
|
| `this.<need>.<method>({…}, { reply? })` | an awaited call, or an effect |
|
|
204
204
|
| `this.held(id, Need).<ask>({…}, { reply?, after? })` | the same, on a standing, and a watch where `after` is given |
|
|
205
|
+
| `this.held(id).describe()`, `.ask(method, {…}, options)` | a standing with no need: what it shows her, then any ask it showed |
|
|
206
|
+
| `this.stranger({ ward, at }, Need).<ask>({…})` | a far house's public being, asked as a stranger, every ask awaited |
|
|
207
|
+
| `this.stranger({ ward, at }).describe()`, `.ask(method, {…})` | the same with no need: what she shows a stranger, then any ask it showed |
|
|
205
208
|
| `this.standings` | `list()`, `note(id, notes)` and `drop(id)` |
|
|
206
209
|
| `this.handle(ask, { bind?, notes?, once?, expires? })` | a handle to one of her asks |
|
|
207
210
|
| `this.invite(id, { notes?, expires? })` | a new occupant, as a handle |
|
|
@@ -261,6 +264,12 @@ hold: `{ result: [...] }`. From a being, pass the result she holds:
|
|
|
261
264
|
`readOnly` ask is watched, and a watch on anything else is refused where
|
|
262
265
|
she makes it.
|
|
263
266
|
|
|
267
|
+
A watch may land as a reply instead: `{ after: seen, reply: 'heard' }`.
|
|
268
|
+
It leaves once her ask lands, as an effect does, and its answer asks her
|
|
269
|
+
`heard`, where she writes what she heard and watches again. So a device
|
|
270
|
+
that only dials, a phone or a Pi behind a router, hears its station the
|
|
271
|
+
moment something changes there, and opens no port.
|
|
272
|
+
|
|
264
273
|
A watch moves only on what its asker could read, since it runs as that
|
|
265
274
|
asker. One asker holds one watch on one ask with the same args, and a
|
|
266
275
|
second answers the first at once. A watch across a door holds its
|
|
@@ -277,7 +286,11 @@ An **occupant** is someone who may ask her. She mints one with
|
|
|
277
286
|
A **standing** is someone she may ask. She receives one where an ask's
|
|
278
287
|
args carry an invitation under `s.handle`, or where her steward
|
|
279
288
|
introduces one. She asks through it with `this.held(id, Need)`, which
|
|
280
|
-
checks the standing's describe covers the need.
|
|
289
|
+
checks the standing's describe covers the need. A standing from an
|
|
290
|
+
invitation is named `standing:` and sixteen hex digits, and the id is
|
|
291
|
+
what her ask receives. One her steward introduced is named by the being
|
|
292
|
+
it reaches. She asks a far standing from the ask after the one that took
|
|
293
|
+
it.
|
|
281
294
|
|
|
282
295
|
Every relation carries two sets of notes. `notes` are hers alone.
|
|
283
296
|
`steward` are her steward's, written when the steward made the relation,
|
|
@@ -365,13 +378,14 @@ export class Shop extends Being.of({
|
|
|
365
378
|
| `bear({ kind, id, args })` | places a new being; the same id twice answers the first |
|
|
366
379
|
| `remove({ id })` | removes a being and everything of hers |
|
|
367
380
|
| `list()` | every being, her kind, whether she is absent, and her dead letters |
|
|
368
|
-
| `ask({ id, method, args }, { reply? })` | asks any being as her occupant `steward
|
|
381
|
+
| `ask({ id, method, args }, { reply? })` | asks any being as her occupant `steward`; with no method, reads what she shows the steward |
|
|
369
382
|
| `introduce({ from, to, notes })` | gives `from` a standing on `to`, and `to` an occupant |
|
|
370
383
|
| `invite({ id, occupant, notes, expires? })` | gives a being a new occupant, and the steward its handle |
|
|
371
384
|
|
|
372
385
|
`bear`, `remove`, `introduce` and `invite` land in the steward's own
|
|
373
386
|
write. If her ask fails, none of them happened. A being borne runs her
|
|
374
|
-
`born` ask first, where her class declares one
|
|
387
|
+
`born` ask first, where her class declares one, asked as the occupant
|
|
388
|
+
`steward`, so its entry says `for: 'steward'`.
|
|
375
389
|
|
|
376
390
|
Every other being is placed as `normal`. She holds the standing
|
|
377
391
|
`steward` and the occupant `steward`, and can drop neither.
|
|
@@ -469,10 +483,19 @@ hold.
|
|
|
469
483
|
Every need is covered, or she is absent. An absent being answers silence
|
|
470
484
|
and keeps her cells, and answers again once an offer covers her needs.
|
|
471
485
|
|
|
486
|
+
A standing is matched to a need by rules two to four alone. A describe
|
|
487
|
+
names no blueprint, so the need's name is hers to choose there.
|
|
488
|
+
|
|
489
|
+
A need she forgot to declare is a member she does not hold, and the call
|
|
490
|
+
throws inside her ask, which answers only `the ask failed`. So check your
|
|
491
|
+
classes with `npx tsc --noEmit` beside your tests, which run with
|
|
492
|
+
`node --test`.
|
|
493
|
+
|
|
472
494
|
### Testing on the bench
|
|
473
495
|
|
|
474
|
-
The bench opens two houses
|
|
475
|
-
and
|
|
496
|
+
The bench opens two houses on one ground in memory, on fake memory,
|
|
497
|
+
keys and clock. A being of the bench's own house asks hers through a
|
|
498
|
+
door, so every ask crosses as it would in production.
|
|
476
499
|
|
|
477
500
|
```ts
|
|
478
501
|
// order.test.ts
|
|
@@ -495,38 +518,49 @@ test('An order is paid once the provider calls the handle it was given', async (
|
|
|
495
518
|
assert.deepEqual(await order.ask('add', { sku: 'tea', price: 4 }), { result: { total: 4 } });
|
|
496
519
|
assert.deepEqual(await order.ask('checkout'), { result: null });
|
|
497
520
|
await bench.settle();
|
|
498
|
-
assert.equal((await order.
|
|
521
|
+
assert.equal((await order.describe())?.state, 'paying', 'the charge left once checkout landed, and answered pending');
|
|
499
522
|
|
|
500
523
|
assert.deepEqual(await payments.settle('first'), { result: null });
|
|
501
524
|
await bench.settle();
|
|
502
|
-
assert.equal((await order.
|
|
525
|
+
assert.equal((await order.describe())?.state, 'paid');
|
|
503
526
|
assert.deepEqual(await order.ask('add', { sku: 'jam', price: 1 }), { error: { message: 'not in this state' } });
|
|
504
527
|
});
|
|
505
528
|
```
|
|
506
529
|
|
|
507
|
-
`place(Class, { id,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
530
|
+
`place(Class, { id, born })` has the bench's steward bear a being. A
|
|
531
|
+
placed being is asked with `ask(method, args, { role })` and described
|
|
532
|
+
with `describe({ role })`. Test her through her asks first, as every
|
|
533
|
+
asker meets her. `cells()` reads her cells through the hand, as her owner
|
|
534
|
+
inspects them. An effect answers with the reply it brings once it lands.
|
|
535
|
+
`settle()` lets every effect and reply run, and `advance(ms)` moves the
|
|
536
|
+
fake clock.
|
|
537
|
+
|
|
538
|
+
The bench plays a role as an owner could, judged on her cells as they
|
|
539
|
+
stand. `root`, and a role root holds, is the hand. `steward` is the
|
|
540
|
+
bench's steward, and `being` a being it introduces to her. Any other
|
|
541
|
+
role is an occupant the bench's steward invites, with the role `true` in
|
|
542
|
+
its steward notes. A role read from her own notes is hers to grant, and
|
|
543
|
+
a handle only her own ask mints.
|
|
514
544
|
|
|
515
545
|
A steward and a public being are placed where the house places them.
|
|
516
546
|
`Bench.open({ steward: Shop, public: Lobby, classes: [Order] })` opens the
|
|
517
547
|
author's house with them there, and `place(Shop)` and `place(Lobby)` find
|
|
518
|
-
them.
|
|
519
|
-
the
|
|
520
|
-
|
|
548
|
+
them. On the public being, a role a stranger holds is played by a being
|
|
549
|
+
of the bench's own house, asking as a stranger. Beside a steward the test
|
|
550
|
+
brings, the bench plays `root` and `stranger` alone, and places no other
|
|
551
|
+
being. A world of your steward and the beings she bears is tested on a
|
|
552
|
+
BenchGround, as [Faces](FACES.md) tests its desk.
|
|
521
553
|
`Bench.check(Shop, { position: 'steward' })` and `Bench.check(Lobby, {
|
|
522
|
-
position: 'public'
|
|
554
|
+
position: 'public' })` check them.
|
|
523
555
|
|
|
524
|
-
An entry's `examples` are tests the bench runs. Each is
|
|
525
|
-
fresh bench
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
556
|
+
An entry's `examples` are tests the bench runs. Each is a history, then
|
|
557
|
+
one ask, on a fresh bench. `given` lists the asks of hers that bring her
|
|
558
|
+
from her `born` to where the example starts. `role` asks, `args` are the
|
|
559
|
+
ask's, `fakes` answer her needs, and `gives` is the answer owed.
|
|
560
|
+
`Bench.check` runs every example twice from one seed and flags a class
|
|
561
|
+
that answers differently, or leaves her cells differently. It then
|
|
562
|
+
describes every state to every role it plays, and names every finding
|
|
563
|
+
that failed.
|
|
530
564
|
|
|
531
565
|
## A faculty
|
|
532
566
|
|
|
@@ -582,34 +616,11 @@ export const paymentsOffer = (payments: Payments): Offer => ({ blueprint: Paymen
|
|
|
582
616
|
```
|
|
583
617
|
|
|
584
618
|
An offer is `{ blueprint, object, kinds?, window?, handler?, stop? }`.
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
call id when an answer was lost. A faculty that changes the world
|
|
591
|
-
answers a call id it has seen with the answer it gave.
|
|
592
|
-
- **A handle arrives as a token.** The faculty calls it with
|
|
593
|
-
`context.call({ token, args, id })`. Its own `id` makes that call run
|
|
594
|
-
once, however often it is sent.
|
|
595
|
-
- **`kinds` is the ground's grant.** It lists the classes that may hold
|
|
596
|
-
the offer. Without it, every class whose need it covers holds it.
|
|
597
|
-
- **`window` is how long the faculty remembers a call id.** It is seven
|
|
598
|
-
days where omitted, and the house gives up on an effect at it.
|
|
599
|
-
- **`handler` answers HTTP on the ground's one listener.** It takes a
|
|
600
|
-
`Request` and answers a `Response`, or `null` where the request is not
|
|
601
|
-
its own. A site, an API or an MCP server is a faculty with a handler.
|
|
602
|
-
- **`stop` is called when the ground stops**, faculties in the reverse of
|
|
603
|
-
the order they were made.
|
|
604
|
-
|
|
605
|
-
The object arrives living. The ground makes and starts the faculty, and
|
|
606
|
-
the house never starts, stops or restarts it. Every being whose need it
|
|
607
|
-
covers holds the same object.
|
|
608
|
-
|
|
609
|
-
A faculty is the ground's, never a house's. The ground's recipe makes
|
|
610
|
-
each one by name, from the settings the ground hands it. `env` is the
|
|
611
|
-
ground's environment, so a secret stays on its machine and out of the
|
|
612
|
-
code. `dir(name)` answers a folder of the faculty's own.
|
|
619
|
+
The object answers each call with its call id, and one that changes the
|
|
620
|
+
world answers a call id it has seen with the answer it gave. The ground's
|
|
621
|
+
recipe makes each faculty by name, and `kinds` grants it to the classes
|
|
622
|
+
it names. [Writing a faculty](FACULTIES.md) teaches the craft whole, with a
|
|
623
|
+
faculty written in Python.
|
|
613
624
|
|
|
614
625
|
```ts
|
|
615
626
|
// recipe.ts
|
|
@@ -620,10 +631,6 @@ export const faculties = () => ({
|
|
|
620
631
|
});
|
|
621
632
|
```
|
|
622
633
|
|
|
623
|
-
Policy over a faculty is written as a being. Limits, approvals and
|
|
624
|
-
quotas are not the faculty's. One being holds the raw faculty through
|
|
625
|
-
`kinds`, and every other being reaches her through a standing.
|
|
626
|
-
|
|
627
634
|
## A ground
|
|
628
635
|
|
|
629
636
|
A ground is the process houses run in, and you write none. `nervur up`
|
|
@@ -641,6 +648,13 @@ nervur-ground/
|
|
|
641
648
|
state/ made by the ground, its owner's alone
|
|
642
649
|
```
|
|
643
650
|
|
|
651
|
+
The folder is a package of ECMAScript modules, so Node reads its
|
|
652
|
+
TypeScript as it is written, with no build step.
|
|
653
|
+
|
|
654
|
+
```bash
|
|
655
|
+
npm init -y && npm pkg set type=module && npm install nervur
|
|
656
|
+
```
|
|
657
|
+
|
|
644
658
|
A house's folder names what the house holds.
|
|
645
659
|
|
|
646
660
|
```ts
|
|
@@ -672,9 +686,11 @@ It is set by its environment.
|
|
|
672
686
|
|
|
673
687
|
| Setting | What it sets |
|
|
674
688
|
| --- | --- |
|
|
675
|
-
| `NERVUR_TCP_PORT` | its TCP port,
|
|
689
|
+
| `NERVUR_TCP_PORT` | its TCP port, 9110 where unset |
|
|
676
690
|
| `NERVUR_HTTP_PORT` | its HTTP port, for Quo over the web and every handler; no HTTP where unset |
|
|
677
|
-
| `NERVUR_ADDRESSES` | the public addresses it writes into invitations, by commas |
|
|
691
|
+
| `NERVUR_ADDRESSES` | the public addresses it writes into invitations, by commas: `tcp`, `https`, `http`, `wss` or `ws` |
|
|
692
|
+
| `NERVUR_ORIGINS` | the pages of other origins it answers on the web, by commas; a page of its own host needs none |
|
|
693
|
+
| `NERVUR_ALLOW_PRIVATE` | `1` to dial private and loopback addresses, as two grounds on one machine do |
|
|
678
694
|
| `NERVUR_BIND` | the address it listens on, `0.0.0.0` where unset |
|
|
679
695
|
| `NERVUR_STATE` | its state, `state/` in its folder where unset |
|
|
680
696
|
| `NERVUR_KEYCHAIN` | a keychain service holding its seeds on macOS, in place of files |
|
|
@@ -682,8 +698,10 @@ It is set by its environment.
|
|
|
682
698
|
|
|
683
699
|
The state holds each house's seed in a file its owner alone reads, and
|
|
684
700
|
each house's ledger. A ledger appends every write and never rewrites
|
|
685
|
-
one
|
|
686
|
-
|
|
701
|
+
one. Its witness keeps where it last stood, and a ledger behind its
|
|
702
|
+
witness is refused. So a ledger restored alone cannot replay what a
|
|
703
|
+
house already answered, though a whole state folder restored with its
|
|
704
|
+
witnesses is not seen. A lost seed is a lost house.
|
|
687
705
|
|
|
688
706
|
A house is added once, and the ground opens it again at every start.
|
|
689
707
|
|
|
@@ -714,17 +732,23 @@ npx nervur houses list
|
|
|
714
732
|
```
|
|
715
733
|
|
|
716
734
|
`ask` asks a being in a house as `root`: the steward, or the being
|
|
717
|
-
`--id` names. The owner
|
|
718
|
-
|
|
735
|
+
`--id` names. The owner opens an order through the steward, and hands a
|
|
736
|
+
courier's paper to it the same way. The steward's `hire` carries the
|
|
737
|
+
paper unopened, and the order takes it.
|
|
719
738
|
|
|
720
739
|
```bash
|
|
721
740
|
npx nervur ask shop open id=first
|
|
722
741
|
```
|
|
723
742
|
|
|
724
743
|
```bash
|
|
725
|
-
npx nervur ask shop
|
|
744
|
+
npx nervur ask shop hire order=first courier=7b22…
|
|
726
745
|
```
|
|
727
746
|
|
|
747
|
+
`--id` names the being asked in the steward's place, as `npx nervur ask
|
|
748
|
+
shop --id first` shows the order's describe. `--cells` reads her cells
|
|
749
|
+
and asks nothing, as `npx nervur ask shop --id first --cells`. No one
|
|
750
|
+
but the owner reads them, and only her own asks write them.
|
|
751
|
+
|
|
728
752
|
Each prints one JSON value. It exits 0 on a result and 1 on an error
|
|
729
753
|
answered. It exits 2 where nothing was asked, so a script tells a
|
|
730
754
|
refusal from a ground that is down. The hand is `state/hand` in the
|
|
@@ -812,3 +836,40 @@ through a faculty your recipe makes.
|
|
|
812
836
|
leaves her absent, and the refusal says why.
|
|
813
837
|
|
|
814
838
|
A failed ask changed nothing she owns, so asking again is safe.
|
|
839
|
+
|
|
840
|
+
## What the house refuses
|
|
841
|
+
|
|
842
|
+
Each refusal answers why, where it is met: at her class's first resolve,
|
|
843
|
+
at her call, or where an ask arrives.
|
|
844
|
+
|
|
845
|
+
- A being reaching anything her position, her needs and `this.house` do
|
|
846
|
+
not give.
|
|
847
|
+
- A ground's own references handed to a being, or offered to her as a
|
|
848
|
+
faculty.
|
|
849
|
+
- A handle or an invitation in her cells.
|
|
850
|
+
- Her cells read by anyone but the owner's hand.
|
|
851
|
+
- A standing she mints herself. Standings arrive from the house.
|
|
852
|
+
- A far standing asked in the ask that took it. She asks it from her next
|
|
853
|
+
ask.
|
|
854
|
+
- A write by anyone else to her notes, and by her to her steward's.
|
|
855
|
+
- An occupant id the house reserves, and one she already holds.
|
|
856
|
+
- Two member names that clash.
|
|
857
|
+
- An ask with no entry.
|
|
858
|
+
- A state no ask reaches, an ask no role reaches, and a role unused.
|
|
859
|
+
- A method landing in a state its `to` does not name.
|
|
860
|
+
- A `readOnly` ask that writes.
|
|
861
|
+
- A need and an offer that disagree on `idempotent`.
|
|
862
|
+
- A schema keyword outside the subset `s` writes.
|
|
863
|
+
- Two offers covering one need for one kind, and a kind two sources
|
|
864
|
+
claim.
|
|
865
|
+
- An effect sent before its ask landed, or sent again while a call for
|
|
866
|
+
it is pending.
|
|
867
|
+
- An ask a stranger reaches that is not idempotent.
|
|
868
|
+
- An invite from a public being.
|
|
869
|
+
- A seed inside the house, and a seed that is not sixty-four hex digits.
|
|
870
|
+
- A memory opened with keys that derive another bound.
|
|
871
|
+
- A send to a private address, unless its ground allows it.
|
|
872
|
+
- A call on the house beside `House.open`, `door` and `ask`.
|
|
873
|
+
- A faculty in a house's code. Faculties are the ground's.
|
|
874
|
+
- A custom body for a ground's own custody or memory.
|
|
875
|
+
- A ground an owner must write. Each terrain's ships.
|
package/COMMAND.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# The command
|
|
2
|
+
|
|
3
|
+
`nervur` is the command the package installs. It holds no business of
|
|
4
|
+
its own. Two words start things on your machine, and every other word is
|
|
5
|
+
read from what the running ground says it holds. This guide assumes you
|
|
6
|
+
have read [the package's start](README.md), which runs a first ground.
|
|
7
|
+
|
|
8
|
+
## Starting a ground
|
|
9
|
+
|
|
10
|
+
`nervur up` runs a NodeGround on a folder until it is stopped. The folder
|
|
11
|
+
holds the ground's recipe, a folder of code for each house, and `state/`,
|
|
12
|
+
where the ground keeps its seeds, its record and its hand.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx nervur up .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The ground stops cleanly on an interrupt and on `SIGTERM`. It takes a
|
|
19
|
+
lock on its folder, so a second `nervur up` on the same folder refuses to
|
|
20
|
+
start.
|
|
21
|
+
|
|
22
|
+
`nervur service` prints what keeps the ground running across reboots: a
|
|
23
|
+
systemd unit on Linux, a launchd job on macOS. Nothing is installed; you
|
|
24
|
+
place what it prints.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx nervur service /srv/shop
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Settings
|
|
31
|
+
|
|
32
|
+
A ground reads its settings from the environment.
|
|
33
|
+
|
|
34
|
+
| Setting | What it sets |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `NERVUR_STATE` | the state folder, `state/` in the ground's folder where unset |
|
|
37
|
+
| `NERVUR_TCP_PORT` | the TCP port Quo listens on, 9110 where unset |
|
|
38
|
+
| `NERVUR_HTTP_PORT` | the port of the web listener, which faces and Quo over the web share; none where unset |
|
|
39
|
+
| `NERVUR_BIND` | the address both listen on, every interface where unset |
|
|
40
|
+
| `NERVUR_ADDRESSES` | the public addresses written into invitations, by commas |
|
|
41
|
+
| `NERVUR_ORIGINS` | the page origins the web listener answers, by commas |
|
|
42
|
+
| `NERVUR_ALLOW_PRIVATE` | `1` to let the ground dial a private or loopback address |
|
|
43
|
+
| `NERVUR_KEYCHAIN` | on macOS, a keychain service that keeps the seeds in place of files |
|
|
44
|
+
| `NERVUR_HAND` | where the hand's socket is, `state/hand` where unset; a relative path is read from where the command runs |
|
|
45
|
+
| `NERVUR_WAIT` | the longest any ask may run, in milliseconds |
|
|
46
|
+
|
|
47
|
+
A ground that people reach names its public addresses. Without them, it
|
|
48
|
+
writes only the addresses it listens on, which a stranger cannot reach.
|
|
49
|
+
|
|
50
|
+
A socket's path fits 103 bytes on macOS and 107 on Linux, and a longer
|
|
51
|
+
one refuses to start by name. A ground in a deep folder names a shorter
|
|
52
|
+
path in `NERVUR_HAND`, such as `state/hand` run from the folder, and every
|
|
53
|
+
command that reaches it names the same.
|
|
54
|
+
|
|
55
|
+
## Asking the ground
|
|
56
|
+
|
|
57
|
+
Every other word goes to the ground's hand, a socket in `state/` that
|
|
58
|
+
your user alone may open. Run the command in the ground's folder, or
|
|
59
|
+
name the socket with `--at <socket>` or `NERVUR_HAND`.
|
|
60
|
+
|
|
61
|
+
`help` prints what the ground holds: each faculty with its methods, and
|
|
62
|
+
each house.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx nervur help
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A faculty is called by its name and a method. Named alone, it prints its
|
|
69
|
+
methods. The ground's own `houses` faculty adds, removes and lists houses.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx nervur houses add name=main memory='{"body":"ledger"}' classes='{"body":"folder","at":"house"}'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`ask` asks a being of a house, as the house's owner. `--id <being>` names
|
|
76
|
+
her, and with none it asks the steward. With no method, it prints what
|
|
77
|
+
she shows.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx nervur ask main
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`--cells` reads a being's cells as they last landed, and asks nothing.
|
|
84
|
+
Nothing but the hand reads cells, which makes it the tool for a test, a
|
|
85
|
+
repair, or a look at what her asks do not show.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx nervur ask main --cells
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The command asks no watch. A watch is held by a being on her standing,
|
|
92
|
+
or by a page through a face, where something waits on its answer.
|
|
93
|
+
|
|
94
|
+
## Arguments and answers
|
|
95
|
+
|
|
96
|
+
Arguments are one JSON object, or words `key=value`. A value is read as
|
|
97
|
+
JSON where it reads as JSON, and as text where it does not, so
|
|
98
|
+
`count=3` is a number and `name=Ada` is text.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx nervur ask main hello '{"name":"Ada"}'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Each word prints one JSON value, the answer, and its exit code says what
|
|
105
|
+
came back.
|
|
106
|
+
|
|
107
|
+
| Exit | What it means |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| 0 | a result, or what she shows |
|
|
110
|
+
| 1 | an error the ground or the being answered |
|
|
111
|
+
| 2 | nothing was asked: a word the command does not know, or a hand that does not answer |
|
|
112
|
+
|
|
113
|
+
So a script tells a refusal from a ground that is down.
|