nervur 0.22.0 → 0.22.2-3
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 +741 -0
- package/KIT-SPEC.md +286 -0
- package/LICENSE +1 -1
- package/NOTICE +6 -2
- package/README.md +97 -424
- package/dist/app/app-ground.d.ts +18 -0
- package/dist/app/app-ground.js +25 -0
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +5 -0
- package/dist/app/native.d.ts +46 -0
- package/dist/app/native.js +101 -0
- package/dist/being/being.d.ts +229 -0
- package/dist/being/being.js +20 -0
- package/dist/being/covers.d.ts +9 -0
- package/dist/being/covers.js +21 -0
- package/dist/being/index.d.ts +3 -0
- package/dist/being/index.js +5 -0
- package/dist/being/need.d.ts +49 -0
- package/dist/being/need.js +33 -0
- package/dist/being/schema.d.ts +100 -0
- package/dist/being/schema.js +132 -0
- package/dist/being/table.d.ts +42 -0
- package/dist/being/table.js +288 -0
- package/dist/bench/bench-ground.d.ts +55 -0
- package/dist/bench/bench-ground.js +101 -0
- package/dist/bench/bench.d.ts +87 -0
- package/dist/bench/bench.js +260 -0
- package/dist/bench/fake-carry.d.ts +32 -0
- package/dist/bench/fake-carry.js +56 -0
- package/dist/bench/fake-clock.d.ts +17 -0
- package/dist/bench/fake-clock.js +34 -0
- package/dist/bench/fake-custody.d.ts +9 -0
- package/dist/bench/fake-custody.js +10 -0
- package/dist/bench/fake-faculty.d.ts +25 -0
- package/dist/bench/fake-faculty.js +48 -0
- package/dist/bench/fake-keys.d.ts +5 -0
- package/dist/bench/fake-keys.js +9 -0
- package/dist/bench/fake-memory.d.ts +14 -0
- package/dist/bench/fake-memory.js +46 -0
- package/dist/bench/fake-network.d.ts +57 -0
- package/dist/bench/fake-network.js +169 -0
- package/dist/bench/index.d.ts +11 -0
- package/dist/bench/index.js +13 -0
- package/dist/bench/seeded.d.ts +11 -0
- package/dist/bench/seeded.js +37 -0
- package/dist/bench/settle.d.ts +2 -0
- package/dist/bench/settle.js +49 -0
- package/dist/bench/stewards.d.ts +17 -0
- package/dist/bench/stewards.js +20 -0
- package/dist/bodies/class-list.d.ts +14 -0
- package/dist/bodies/class-list.js +33 -0
- package/dist/bodies/joined-carry.d.ts +23 -0
- package/dist/bodies/joined-carry.js +42 -0
- package/dist/bodies/noble-crypto.d.ts +22 -0
- package/dist/bodies/noble-crypto.js +88 -0
- package/dist/bodies/seed-keys.d.ts +10 -0
- package/dist/bodies/seed-keys.js +42 -0
- package/dist/bodies/strict-tools.d.ts +10 -0
- package/dist/bodies/strict-tools.js +306 -0
- package/dist/bodies/web-carry.d.ts +65 -0
- package/dist/bodies/web-carry.js +224 -0
- package/dist/bodies/web-clock.d.ts +12 -0
- package/dist/bodies/web-clock.js +33 -0
- package/dist/browser/browser-ground.d.ts +69 -0
- package/dist/browser/browser-ground.js +219 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +7 -0
- package/dist/browser/indexeddb-memory.d.ts +17 -0
- package/dist/browser/indexeddb-memory.js +97 -0
- package/dist/browser/locked-custody.d.ts +25 -0
- package/dist/browser/locked-custody.js +89 -0
- package/dist/browser/origin-classes.d.ts +7 -0
- package/dist/browser/origin-classes.js +31 -0
- package/dist/foundation.d.ts +150 -0
- package/dist/foundation.js +4 -0
- package/dist/ground/ground.d.ts +177 -0
- package/dist/ground/ground.js +363 -0
- package/dist/house/crossing.d.ts +37 -0
- package/dist/house/crossing.js +131 -0
- package/dist/house/house.d.ts +80 -0
- package/dist/house/house.js +1753 -0
- package/dist/house/rows-shape.d.ts +103 -0
- package/dist/house/rows-shape.js +12 -0
- package/dist/house/rows.d.ts +27 -0
- package/dist/house/rows.js +168 -0
- package/dist/index.d.ts +29 -1
- package/dist/index.js +25 -14
- package/dist/node/bridge.d.ts +17 -0
- package/dist/node/bridge.js +188 -0
- package/dist/node/cli.js +170 -0
- package/dist/node/custody.d.ts +20 -0
- package/dist/node/custody.js +34 -0
- package/dist/node/file-keys.d.ts +7 -0
- package/dist/node/file-keys.js +30 -0
- package/dist/node/file-memory.d.ts +13 -0
- package/dist/node/file-memory.js +91 -0
- package/dist/node/folder-classes.d.ts +5 -0
- package/dist/node/folder-classes.js +40 -0
- package/dist/node/gone.d.ts +2 -0
- package/dist/node/gone.js +7 -0
- package/dist/node/hand.d.ts +29 -0
- package/dist/node/hand.js +85 -0
- package/dist/node/held-keys.d.ts +14 -0
- package/dist/node/held-keys.js +36 -0
- package/dist/node/http.d.ts +11 -0
- package/dist/node/http.js +90 -0
- package/dist/node/index.d.ts +13 -0
- package/dist/node/index.js +15 -0
- package/dist/node/keychain-keys.d.ts +10 -0
- package/dist/node/keychain-keys.js +51 -0
- package/dist/node/ledger-memory.d.ts +17 -0
- package/dist/node/ledger-memory.js +151 -0
- package/dist/node/lock.d.ts +10 -0
- package/dist/node/lock.js +78 -0
- package/dist/node/node-ground.d.ts +33 -0
- package/dist/node/node-ground.js +147 -0
- package/dist/node/notify.d.ts +1 -0
- package/dist/node/notify.js +18 -0
- package/dist/node/tcp-carry.d.ts +39 -0
- package/dist/node/tcp-carry.js +216 -0
- package/dist/node/websocket.d.ts +6 -0
- package/dist/node/websocket.js +118 -0
- package/dist/quo/frame.d.ts +20 -0
- package/dist/quo/frame.js +48 -0
- package/dist/quo/room.d.ts +154 -0
- package/dist/quo/room.js +362 -0
- package/dist/serve/index.d.ts +27 -0
- package/dist/serve/index.js +55 -0
- package/package.json +49 -47
- package/dist/browser.d.ts +0 -1
- package/dist/browser.js +0 -8
- package/dist/cli.js +0 -16
- package/dist/core/being/being.d.ts +0 -17
- package/dist/core/being/being.js +0 -72
- package/dist/core/being/digest.d.ts +0 -3
- package/dist/core/being/digest.js +0 -17
- package/dist/core/being/faculty.d.ts +0 -10
- package/dist/core/being/faculty.js +0 -77
- package/dist/core/being/index.d.ts +0 -6
- package/dist/core/being/index.js +0 -8
- package/dist/core/being/kind.d.ts +0 -6
- package/dist/core/being/kind.js +0 -34
- package/dist/core/being/types.d.ts +0 -61
- package/dist/core/being/types.js +0 -4
- package/dist/core/being/words.d.ts +0 -13
- package/dist/core/being/words.js +0 -14
- package/dist/core/browser/index.d.ts +0 -37
- package/dist/core/browser/index.js +0 -196
- package/dist/core/browser/worker.d.ts +0 -11
- package/dist/core/browser/worker.js +0 -37
- package/dist/core/cli/command.d.ts +0 -13
- package/dist/core/cli/command.js +0 -330
- package/dist/core/cli/edge.d.ts +0 -7
- package/dist/core/cli/edge.js +0 -79
- package/dist/core/cli/harbor.d.ts +0 -25
- package/dist/core/cli/harbor.js +0 -115
- package/dist/core/contract/index.d.ts +0 -42
- package/dist/core/contract/index.js +0 -34
- package/dist/core/contract/link.d.ts +0 -4
- package/dist/core/contract/link.js +0 -45
- package/dist/core/crypto/aes.d.ts +0 -3
- package/dist/core/crypto/aes.js +0 -24
- package/dist/core/crypto/bytes.d.ts +0 -6
- package/dist/core/crypto/bytes.js +0 -33
- package/dist/core/crypto/ed25519.d.ts +0 -3
- package/dist/core/crypto/ed25519.js +0 -93
- package/dist/core/crypto/hash.d.ts +0 -2
- package/dist/core/crypto/hash.js +0 -11
- package/dist/core/crypto/index.d.ts +0 -7
- package/dist/core/crypto/index.js +0 -10
- package/dist/core/crypto/json.d.ts +0 -8
- package/dist/core/crypto/json.js +0 -250
- package/dist/core/crypto/mlkem.d.ts +0 -12
- package/dist/core/crypto/mlkem.js +0 -36
- package/dist/core/crypto/subtle.d.ts +0 -3
- package/dist/core/crypto/subtle.js +0 -11
- package/dist/core/crypto/x25519.d.ts +0 -2
- package/dist/core/crypto/x25519.js +0 -24
- package/dist/core/edge/index.d.ts +0 -164
- package/dist/core/edge/index.js +0 -739
- package/dist/core/edge/kit.d.ts +0 -2
- package/dist/core/edge/kit.js +0 -2
- package/dist/core/folder/index.d.ts +0 -18
- package/dist/core/folder/index.js +0 -130
- package/dist/core/git/http.d.ts +0 -6
- package/dist/core/git/http.js +0 -102
- package/dist/core/git/index.d.ts +0 -5
- package/dist/core/git/index.js +0 -10
- package/dist/core/git/object.d.ts +0 -40
- package/dist/core/git/object.js +0 -103
- package/dist/core/git/pack.d.ts +0 -9
- package/dist/core/git/pack.js +0 -171
- package/dist/core/git/store.d.ts +0 -23
- package/dist/core/git/store.js +0 -120
- package/dist/core/git/zlib.d.ts +0 -6
- package/dist/core/git/zlib.js +0 -210
- package/dist/core/harbor/carrying.d.ts +0 -51
- package/dist/core/harbor/carrying.js +0 -69
- package/dist/core/harbor/catalogue.d.ts +0 -33
- package/dist/core/harbor/catalogue.js +0 -365
- package/dist/core/harbor/dna.d.ts +0 -13
- package/dist/core/harbor/dna.js +0 -120
- package/dist/core/harbor/dock.d.ts +0 -62
- package/dist/core/harbor/dock.js +0 -381
- package/dist/core/harbor/harbor.d.ts +0 -16
- package/dist/core/harbor/harbor.js +0 -438
- package/dist/core/harbor/index.d.ts +0 -11
- package/dist/core/harbor/index.js +0 -14
- package/dist/core/harbor/memory.d.ts +0 -10
- package/dist/core/harbor/memory.js +0 -25
- package/dist/core/harbor/package.d.ts +0 -20
- package/dist/core/harbor/package.js +0 -172
- package/dist/core/harbor/probe.d.ts +0 -22
- package/dist/core/harbor/probe.js +0 -15
- package/dist/core/harbor/registry.d.ts +0 -15
- package/dist/core/harbor/registry.js +0 -110
- package/dist/core/harbor/root-line.d.ts +0 -7
- package/dist/core/harbor/root-line.js +0 -9
- package/dist/core/harbor/terrain.d.ts +0 -25
- package/dist/core/harbor/terrain.js +0 -28
- package/dist/core/http/index.d.ts +0 -2
- package/dist/core/http/index.js +0 -154
- package/dist/core/http/websocket.d.ts +0 -29
- package/dist/core/http/websocket.js +0 -133
- package/dist/core/line/answer.d.ts +0 -8
- package/dist/core/line/answer.js +0 -60
- package/dist/core/line/frame.d.ts +0 -29
- package/dist/core/line/frame.js +0 -77
- package/dist/core/line/ground.d.ts +0 -3
- package/dist/core/line/ground.js +0 -7
- package/dist/core/line/index.d.ts +0 -4
- package/dist/core/line/index.js +0 -8
- package/dist/core/line/web.d.ts +0 -12
- package/dist/core/line/web.js +0 -117
- package/dist/core/node/index.d.ts +0 -23
- package/dist/core/node/index.js +0 -124
- package/dist/core/pointer/bodies.d.ts +0 -31
- package/dist/core/pointer/bodies.js +0 -118
- package/dist/core/pointer/index.d.ts +0 -2
- package/dist/core/pointer/index.js +0 -4
- package/dist/core/pointer/world.d.ts +0 -45
- package/dist/core/pointer/world.js +0 -106
- package/dist/core/proof/contracts.d.ts +0 -19
- package/dist/core/proof/contracts.js +0 -116
- package/dist/core/proof/expect.d.ts +0 -6
- package/dist/core/proof/expect.js +0 -18
- package/dist/core/proof/index.d.ts +0 -3
- package/dist/core/proof/index.js +0 -14
- package/dist/core/proof/law.d.ts +0 -25
- package/dist/core/proof/law.js +0 -715
- package/dist/core/quo/address.d.ts +0 -19
- package/dist/core/quo/address.js +0 -84
- package/dist/core/quo/door.d.ts +0 -34
- package/dist/core/quo/door.js +0 -174
- package/dist/core/quo/index.d.ts +0 -9
- package/dist/core/quo/index.js +0 -12
- package/dist/core/quo/invitation.d.ts +0 -8
- package/dist/core/quo/invitation.js +0 -19
- package/dist/core/quo/keys.d.ts +0 -40
- package/dist/core/quo/keys.js +0 -79
- package/dist/core/quo/payload.d.ts +0 -15
- package/dist/core/quo/payload.js +0 -55
- package/dist/core/quo/relations.d.ts +0 -40
- package/dist/core/quo/relations.js +0 -33
- package/dist/core/quo/reply.d.ts +0 -13
- package/dist/core/quo/reply.js +0 -35
- package/dist/core/quo/seal.d.ts +0 -42
- package/dist/core/quo/seal.js +0 -78
- package/dist/core/quo/standing.d.ts +0 -39
- package/dist/core/quo/standing.js +0 -90
- package/dist/core/tcp/index.d.ts +0 -27
- package/dist/core/tcp/index.js +0 -209
- package/dist/core/ward/allowance.d.ts +0 -14
- package/dist/core/ward/allowance.js +0 -32
- package/dist/core/ward/cells.d.ts +0 -7
- package/dist/core/ward/cells.js +0 -74
- package/dist/core/ward/house.d.ts +0 -67
- package/dist/core/ward/house.js +0 -473
- package/dist/core/ward/index.d.ts +0 -5
- package/dist/core/ward/index.js +0 -7
- package/dist/core/ward/partition.d.ts +0 -50
- package/dist/core/ward/partition.js +0 -66
- package/dist/core/ward/stance.d.ts +0 -29
- package/dist/core/ward/stance.js +0 -186
- package/dist/core/ward/ward.d.ts +0 -44
- package/dist/core/ward/ward.js +0 -140
- package/dist/core.d.ts +0 -10
- package/dist/core.js +0 -19
- package/dist/defaults/dock/index.d.ts +0 -4
- package/dist/defaults/dock/index.js +0 -11
- package/dist/defaults/index.d.ts +0 -5
- package/dist/defaults/index.js +0 -10
- package/dist/defaults/memory/index.d.ts +0 -12
- package/dist/defaults/memory/index.js +0 -39
- package/dist/defaults/tcp/index.d.ts +0 -16
- package/dist/defaults/tcp/index.js +0 -82
- package/dist/defaults/ward/index.d.ts +0 -4
- package/dist/defaults/ward/index.js +0 -11
- package/dist/defaults/web/index.d.ts +0 -15
- package/dist/defaults/web/index.js +0 -90
- package/dist/edge.d.ts +0 -1
- package/dist/edge.js +0 -9
- package/dist/kit.d.ts +0 -4
- package/dist/kit.js +0 -12
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -8
- package/src/browser.ts +0 -10
- package/src/cli.ts +0 -15
- package/src/core/being/being.ts +0 -84
- package/src/core/being/digest.ts +0 -18
- package/src/core/being/faculty.ts +0 -76
- package/src/core/being/index.ts +0 -8
- package/src/core/being/kind.ts +0 -37
- package/src/core/being/types.ts +0 -74
- package/src/core/being/words.ts +0 -31
- package/src/core/browser/index.ts +0 -219
- package/src/core/browser/worker.ts +0 -63
- package/src/core/cli/command.ts +0 -311
- package/src/core/cli/edge.ts +0 -86
- package/src/core/cli/harbor.ts +0 -120
- package/src/core/contract/index.ts +0 -82
- package/src/core/contract/link.ts +0 -58
- package/src/core/crypto/aes.ts +0 -26
- package/src/core/crypto/bytes.ts +0 -37
- package/src/core/crypto/ed25519.ts +0 -92
- package/src/core/crypto/hash.ts +0 -14
- package/src/core/crypto/index.ts +0 -10
- package/src/core/crypto/json.ts +0 -241
- package/src/core/crypto/mlkem.ts +0 -38
- package/src/core/crypto/subtle.ts +0 -13
- package/src/core/crypto/x25519.ts +0 -23
- package/src/core/edge/index.ts +0 -865
- package/src/core/folder/index.ts +0 -137
- package/src/core/git/http.ts +0 -103
- package/src/core/git/index.ts +0 -10
- package/src/core/git/object.ts +0 -116
- package/src/core/git/pack.ts +0 -147
- package/src/core/git/store.ts +0 -122
- package/src/core/git/zlib.ts +0 -197
- package/src/core/harbor/carrying.ts +0 -124
- package/src/core/harbor/catalogue.ts +0 -386
- package/src/core/harbor/dna.ts +0 -116
- package/src/core/harbor/dock.ts +0 -420
- package/src/core/harbor/harbor.ts +0 -433
- package/src/core/harbor/index.ts +0 -14
- package/src/core/harbor/memory.ts +0 -31
- package/src/core/harbor/package.ts +0 -195
- package/src/core/harbor/probe.ts +0 -39
- package/src/core/harbor/registry.ts +0 -107
- package/src/core/harbor/root-line.ts +0 -19
- package/src/core/harbor/terrain.ts +0 -54
- package/src/core/http/index.ts +0 -147
- package/src/core/http/websocket.ts +0 -124
- package/src/core/line/answer.ts +0 -60
- package/src/core/line/frame.ts +0 -83
- package/src/core/line/ground.ts +0 -18
- package/src/core/line/index.ts +0 -8
- package/src/core/line/web.ts +0 -123
- package/src/core/node/index.ts +0 -139
- package/src/core/pointer/bodies.ts +0 -122
- package/src/core/pointer/index.ts +0 -4
- package/src/core/pointer/world.ts +0 -134
- package/src/core/proof/contracts.ts +0 -134
- package/src/core/proof/expect.ts +0 -25
- package/src/core/proof/index.ts +0 -14
- package/src/core/proof/law.ts +0 -742
- package/src/core/quo/address.ts +0 -87
- package/src/core/quo/door.ts +0 -180
- package/src/core/quo/index.ts +0 -12
- package/src/core/quo/invitation.ts +0 -19
- package/src/core/quo/keys.ts +0 -91
- package/src/core/quo/payload.ts +0 -61
- package/src/core/quo/relations.ts +0 -62
- package/src/core/quo/reply.ts +0 -38
- package/src/core/quo/seal.ts +0 -101
- package/src/core/quo/standing.ts +0 -111
- package/src/core/stand/main.ts +0 -20
- package/src/core/stand/stand.ts +0 -259
- package/src/core/tcp/index.ts +0 -227
- package/src/core/ward/allowance.ts +0 -47
- package/src/core/ward/cells.ts +0 -77
- package/src/core/ward/house.ts +0 -524
- package/src/core/ward/index.ts +0 -7
- package/src/core/ward/partition.ts +0 -117
- package/src/core/ward/stance.ts +0 -207
- package/src/core/ward/ward.ts +0 -166
- package/src/core.ts +0 -55
- package/src/defaults/dock/index.ts +0 -12
- package/src/defaults/index.ts +0 -10
- package/src/defaults/memory/index.ts +0 -50
- package/src/defaults/tcp/index.ts +0 -89
- package/src/defaults/ward/index.ts +0 -12
- package/src/defaults/web/index.ts +0 -97
- package/src/edge.ts +0 -11
- package/src/index.ts +0 -18
- package/src/kit.ts +0 -15
- package/src/node.ts +0 -10
- /package/dist/{cli.d.ts → node/cli.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,449 +1,122 @@
|
|
|
1
1
|
# nervur
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## A
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
out, speaks the web where you open it, and opens in one run at a time.
|
|
46
|
-
On Cloudflare Workers it is one Durable Object of many a worker carries,
|
|
47
|
-
running in a child worker the object loads for the commit `live` names,
|
|
48
|
-
answering Quo at `/<name>/quo` on whatever host reaches it, and asking
|
|
49
|
-
over TCP and the web. Anywhere else it lives as long as its process and
|
|
50
|
-
speaks the web where you open it. Hand in a terrain, as below, and that
|
|
51
|
-
one is used.
|
|
52
|
-
|
|
53
|
-
Nothing enters a harbor unasked. A new harbor holds its catalogue alone,
|
|
54
|
-
and a carrier stands only once the root opens it:
|
|
55
|
-
|
|
56
|
-
```js
|
|
57
|
-
await harbor.ask({ method: 'open', args: { key: 'web', class: 'org.nervur.web' } });
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## A harbor on the edge
|
|
61
|
-
|
|
62
|
-
An edge harbor is born on your machine and carried there, so you pilot it
|
|
63
|
-
from your own harbor, as you pilot one on a server, and you move its code
|
|
64
|
-
the same way, with no deploy. One worker carries as many harbors as you
|
|
65
|
-
pack into it, each a Durable Object by its name, answering at
|
|
66
|
-
`/<name>/quo`. The worker is a shell: it keeps each harbor's storage and
|
|
67
|
-
its web door, and runs the harbor, the kit and the modules its `live`
|
|
68
|
-
commit holds, in a child worker Cloudflare's Worker Loader makes of them.
|
|
69
|
-
The worker is a folder of its own, an ES module project (`"type":
|
|
70
|
-
"module"` in its `package.json`), holding the worker and its
|
|
71
|
-
`wrangler.toml`:
|
|
72
|
-
|
|
73
|
-
```js
|
|
74
|
-
// worker.js
|
|
75
|
-
import { harborShell, harborWorker } from 'nervur/edge';
|
|
76
|
-
import kit from 'nervur/edge/kit';
|
|
77
|
-
import pack from './pack.edge.json';
|
|
78
|
-
|
|
79
|
-
export const Harbor = harborShell({ kit, pack });
|
|
80
|
-
export default harborWorker();
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
```toml
|
|
84
|
-
# wrangler.toml
|
|
85
|
-
name = "harbor"
|
|
86
|
-
main = "worker.js"
|
|
87
|
-
compatibility_date = "2026-09-01"
|
|
88
|
-
|
|
89
|
-
[[durable_objects.bindings]]
|
|
90
|
-
name = "HARBOR"
|
|
91
|
-
class_name = "Harbor"
|
|
92
|
-
|
|
93
|
-
[[migrations]]
|
|
94
|
-
tag = "v1"
|
|
95
|
-
new_sqlite_classes = ["Harbor"]
|
|
96
|
-
|
|
97
|
-
[[worker_loaders]]
|
|
98
|
-
binding = "LOADER"
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
The Worker Loader is in beta, and on Cloudflare it needs the Workers Paid
|
|
102
|
-
plan. `wrangler dev` runs it on your machine at no cost.
|
|
103
|
-
|
|
104
|
-
Make the harbor and set it up with the command, from that folder, naming
|
|
105
|
-
where the edge will reach it:
|
|
106
|
-
|
|
107
|
-
```sh
|
|
108
|
-
nervur init --dir ./harbor
|
|
109
|
-
nervur module add ./greetings.js --dir ./harbor
|
|
110
|
-
nervur reach http://127.0.0.1:8787/main/quo --dir ./harbor
|
|
111
|
-
nervur own me --dir ./harbor
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
`own` prints the owner invitation, which never leaves your machine. Run
|
|
115
|
-
it on this machine first:
|
|
116
|
-
|
|
117
|
-
```sh
|
|
118
|
-
nervur edge dev ./pack.edge.json main --dir ./harbor
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
`edge dev` packs the harbor as `main` into `pack.edge.json`, beside any
|
|
122
|
-
harbor packed there before, and runs your `wrangler dev`, keeping the
|
|
123
|
-
objects' storage and a secret of its own in `.nervur-edge`, so the
|
|
124
|
-
harbor stands again each time you run it. The harbor's code travels in
|
|
125
|
-
its package, as its DNA. The first time its object starts, the harbor
|
|
126
|
-
lands in its storage; after that the storage is the harbor, and a new
|
|
127
|
-
deploy leaves it be. Then, from your own harbor:
|
|
128
|
-
|
|
129
|
-
```sh
|
|
130
|
-
nervur pilot edge '<the owner invitation>' --dir ./mine
|
|
131
|
-
nervur host shop --via edge --dir ./mine
|
|
132
|
-
nervur module add ./greetings.js --via edge --dir ./mine
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
A module added, or `live` moved back, runs on the edge at once: the
|
|
136
|
-
worker loads the next child for the commit `live` names, with no deploy.
|
|
137
|
-
A module that does not load there is refused with its reason, and `live`
|
|
138
|
-
stays where it was.
|
|
139
|
-
|
|
140
|
-
For Cloudflare, keep one secret for the worker, `wrangler secret put
|
|
141
|
-
NERVUR_SECRET`, and hold the same one as `NERVUR_SECRET` in your shell.
|
|
142
|
-
Name each harbor's address with `reach`, pack each with
|
|
143
|
-
`nervur edge pack ./pack.edge.json <name> --dir <its folder>`, and
|
|
144
|
-
`wrangler deploy`. A pack holds every seed sealed under that secret, so
|
|
145
|
-
it ships in the bundle and opens nowhere else, and a new harbor is a new
|
|
146
|
-
deploy, never a new secret. `pilot` opens the web carrier where the
|
|
147
|
-
invitation names a web address. A name the pack does not hold answers
|
|
148
|
-
404, so a stranger's request mints nothing.
|
|
149
|
-
|
|
150
|
-
## A world in one process
|
|
151
|
-
|
|
152
|
-
A module is one file of JavaScript that imports nothing but `nervur`:
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
// greetings.js
|
|
156
|
-
import { Being, Faculty } from 'nervur';
|
|
157
|
-
|
|
158
|
-
// Its name, as a kind is named, and its version.
|
|
159
|
-
export const module = 'org.example.greetings';
|
|
160
|
-
export const version = '1.0.0';
|
|
161
|
-
|
|
162
|
-
// A contract, and a faculty that fulfils it. Every class names its kind.
|
|
163
|
-
class Clock extends Faculty {
|
|
164
|
-
static kind = 'org.example.clock';
|
|
165
|
-
}
|
|
166
|
-
class SystemTime extends Clock {
|
|
167
|
-
static kind = 'org.example.system-time';
|
|
168
|
-
static asks = { now: {} };
|
|
169
|
-
now() {
|
|
170
|
-
return { now: Date.now() };
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// A being, who lends a clock by its contract.
|
|
175
|
-
class Greeter extends Being {
|
|
176
|
-
static kind = 'org.example.greeter';
|
|
177
|
-
static asks = { hello: {} };
|
|
178
|
-
async hello(args, asker) {
|
|
179
|
-
if (!this.stance.standings.get('clock')) await this.stance.lend(Clock, 'clock');
|
|
180
|
-
const time = await this.stance.standings.get('clock')?.ask('now');
|
|
181
|
-
return { hello: asker.id ?? 'stranger', time };
|
|
3
|
+
`nervur` is a library for writing beings and opening the house that holds
|
|
4
|
+
them. It is the first kit of [Quo](https://quo.systems), a protocol where
|
|
5
|
+
a door is one function: bytes in, bytes or nothing out.
|
|
6
|
+
|
|
7
|
+
This version is a prerelease, and the API moves until 1.0.0. Install it
|
|
8
|
+
with `npm i nervur@next`. It runs on Node 22.18 or later.
|
|
9
|
+
[AUTHORING.md](AUTHORING.md) teaches beings, faculties and grounds.
|
|
10
|
+
[KIT-SPEC.md](KIT-SPEC.md) answers every choice Quo leaves to a kit.
|
|
11
|
+
|
|
12
|
+
## Words
|
|
13
|
+
|
|
14
|
+
A **being** is an instance of a class you write. She keeps **cells**,
|
|
15
|
+
which are JSON values, and answers **asks**, which are the methods others
|
|
16
|
+
may call. The **house** holds beings, keeps their cells, and seals every
|
|
17
|
+
ask that crosses its door. A **ground** is the process houses run in. It
|
|
18
|
+
hands each house a seed, somewhere to keep rows, its classes, a way to
|
|
19
|
+
carry bytes, and the **faculties** its beings may call.
|
|
20
|
+
|
|
21
|
+
## A being
|
|
22
|
+
|
|
23
|
+
Every ask declares its arguments and its result, and may carry examples.
|
|
24
|
+
The house refuses arguments that do not match.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// greeter.ts
|
|
28
|
+
import { Being, s, type Args } from 'nervur/being';
|
|
29
|
+
|
|
30
|
+
export class Greeter extends Being.of({
|
|
31
|
+
kind: 'org.example.greeter',
|
|
32
|
+
description: 'Greets whoever asks, and counts them.',
|
|
33
|
+
cells: { greeted: 0 },
|
|
34
|
+
asks: {
|
|
35
|
+
hello: {
|
|
36
|
+
args: s.object({ name: s.string() }),
|
|
37
|
+
result: s.string(),
|
|
38
|
+
examples: [{ cells: { greeted: 2 }, args: { name: 'Ada' }, gives: { result: 'Hello, Ada. You are number 3.' } }],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
}) {
|
|
42
|
+
hello({ name }: Args<Greeter, 'hello'>) {
|
|
43
|
+
this.cells.greeted += 1;
|
|
44
|
+
return `Hello, ${name}. You are number ${this.cells.greeted}.`;
|
|
182
45
|
}
|
|
183
46
|
}
|
|
184
|
-
|
|
185
|
-
export const classes = [SystemTime, Greeter];
|
|
186
47
|
```
|
|
187
48
|
|
|
188
|
-
A
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
49
|
+
## A test
|
|
50
|
+
|
|
51
|
+
The bench opens two houses in one process, so every ask crosses a door
|
|
52
|
+
as it would in production. `Bench.check` runs every example twice and
|
|
53
|
+
describes every state to every role.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// greeter.test.ts
|
|
57
|
+
import assert from 'node:assert/strict';
|
|
58
|
+
import { test } from 'node:test';
|
|
59
|
+
import { Bench } from 'nervur/bench';
|
|
60
|
+
import { Greeter } from './greeter.ts';
|
|
61
|
+
|
|
62
|
+
test('Greeter keeps her examples and her table', async () => {
|
|
63
|
+
await Bench.check(Greeter);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('Greeter counts whoever she greets', async () => {
|
|
67
|
+
const bench = await Bench.open({ classes: [Greeter] });
|
|
68
|
+
const greeter = await bench.place(Greeter);
|
|
69
|
+
assert.deepEqual(await greeter.ask('hello', { name: 'Ada' }), { result: 'Hello, Ada. You are number 1.' });
|
|
70
|
+
assert.deepEqual(await greeter.cells(), { greeted: 1 });
|
|
71
|
+
});
|
|
201
72
|
```
|
|
202
73
|
|
|
203
|
-
A
|
|
204
|
-
asks it through the world, sealed as Quo's bytes. `world.restart('home')`
|
|
205
|
-
opens the harbor again from what its memory kept.
|
|
206
|
-
|
|
207
|
-
## Kinds
|
|
208
|
-
|
|
209
|
-
A row keeps the kind of the class a being is born of, and a being lends
|
|
210
|
-
by a contract's kind. A kind is declared on the class, because a bundler
|
|
211
|
-
renames classes. It is a domain you own, reversed, then a name, as Apple
|
|
212
|
-
and Matrix name things: `com.acme.shop`. Every segment is lowercase
|
|
213
|
-
letters, digits and `-`, and there are three at least. Each class
|
|
214
|
-
declares its own: a subclass that stands, and every contract between a
|
|
215
|
-
faculty and `Faculty`. `org.nervur.` is the kit's, and `org.example.` is
|
|
216
|
-
for examples like the one above. A module's classes stand under its own
|
|
217
|
-
domain: `com.acme.shop` stands `com.acme.*` kinds. A harbor refuses a
|
|
218
|
-
module in which one kind names two classes or two contracts, or names a
|
|
219
|
-
class and a contract.
|
|
220
|
-
|
|
221
|
-
## The DNA
|
|
222
|
-
|
|
223
|
-
Your classes come in modules, each one file exporting `module`, `version`
|
|
224
|
-
and `classes`, a module named as a kind is. A harbor's catalogue keeps
|
|
225
|
-
its code as a git repository, its DNA, from its first moment: a commit
|
|
226
|
-
holds `modules/<module>.js` for every module the harbor runs, and `live`
|
|
227
|
-
names the commit that stands. Her asks, the root's and an owner's:
|
|
228
|
-
|
|
229
|
-
- `add { source, name? }` commits a module's source on `live` and moves
|
|
230
|
-
`live` to it; the same module again takes its new version.
|
|
231
|
-
- `remove { module }` commits its file away, refused while a being or a
|
|
232
|
-
ward stands on its kinds.
|
|
233
|
-
- `live { commit? }` moves `live` to a commit or a fetched ref, or, with
|
|
234
|
-
none, names the commit that stands. Moving `live` back is a rollback.
|
|
235
|
-
- `log` walks back from `live`. `modules` shows what `live` runs, and why
|
|
236
|
-
a module does not.
|
|
237
|
-
- `origin { url }` names a git repository over HTTP, and `fetch` reads
|
|
238
|
-
every ref it has and all they reach into the harbor, touching nothing
|
|
239
|
-
there.
|
|
240
|
-
|
|
241
|
-
Moving `live` runs the commit's modules together, or refuses them with
|
|
242
|
-
the reason and leaves `live` where it was. Once they run, every being a
|
|
243
|
-
new class resolves is born again of it, on the cells she keeps. A
|
|
244
|
-
restart stands `live` from what the harbor keeps, with no network. The
|
|
245
|
-
objects live in the harbor's memory, sealed as everything else is, so a
|
|
246
|
-
harbor carried to another ground carries its DNA. Real `git` reads a
|
|
247
|
-
harbor's objects, and a harbor reads what `git` serves.
|
|
74
|
+
## A ground
|
|
248
75
|
|
|
249
|
-
|
|
76
|
+
A ground is the process houses run in, and you write none. `nervur up`
|
|
77
|
+
runs one on a folder. Each house's code is a folder of its own, whose
|
|
78
|
+
index names its steward. Here the greeter is the steward.
|
|
250
79
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
1. **The boot**, the harbor's own, from the library's core alone. The
|
|
256
|
-
terrain gives the seed, which opens its memory; the terrain keeps that
|
|
257
|
-
memory as sealed bytes and reads none of it. The box ward unpacks, the
|
|
258
|
-
catalogue stands and runs every module `live` holds, every registry the
|
|
259
|
-
catalogue resolves stands, and then the dock, of her class. The door is
|
|
260
|
-
hers from here, and `Harbor.open()` returns. It is one call, and no ask
|
|
261
|
-
makes it.
|
|
262
|
-
2. **The dock's**, on her `stand` ask. She stands every other faculty,
|
|
263
|
-
registries first, then memory faculties, then the rest; hands her
|
|
264
|
-
routes to the carrier; and stands every ward she hosts, under the seed
|
|
265
|
-
she keeps for it.
|
|
266
|
-
3. **Each ward's beings**, stood by nothing. A being's cells, occupants
|
|
267
|
-
and standings are her ward's rows, so she is born from her row when an
|
|
268
|
-
ask reaches her, once for the asks in flight on her, and dropped after.
|
|
269
|
-
A harbor holds in memory its faculties, its wards and the beings
|
|
270
|
-
answering now.
|
|
271
|
-
|
|
272
|
-
After the boot a harbor takes asks alone. Whoever holds it asks `stand`:
|
|
273
|
-
|
|
274
|
-
```js
|
|
275
|
-
const harbor = await Harbor.open();
|
|
276
|
-
await harbor.ask({ method: 'stand' });
|
|
80
|
+
```ts
|
|
81
|
+
// house/index.ts
|
|
82
|
+
export { Greeter as steward } from '../greeter.ts';
|
|
277
83
|
```
|
|
278
84
|
|
|
279
|
-
|
|
280
|
-
The command asks it of every harbor it opens.
|
|
281
|
-
|
|
282
|
-
Cells decide what stands. The modules only resolve a kind a row keeps.
|
|
283
|
-
Opening a harbor on empty memory is its genesis: the harbor writes the
|
|
284
|
-
catalogue and the default dock, and the root's asks write the rest: `add`
|
|
285
|
-
on the catalogue, `open`, `host`, `route`, and `boot` on a ward.
|
|
286
|
-
`host { ward, seed? }` stands a ward under a seed you name, or a drawn
|
|
287
|
-
one.
|
|
288
|
-
|
|
289
|
-
A ward is a being too, and her row keeps her class's kind. `Ward` and
|
|
290
|
-
`Dock` are contracts, and `DefaultWard` and `DefaultDock` the library's
|
|
291
|
-
defaults of them. A class of yours extending either, in a module the
|
|
292
|
-
catalogue runs, is a ward of your own: `host { ward, class }` stands a
|
|
293
|
-
hosted ward of it, and `become { class }` on any ward, the box ward's
|
|
294
|
-
dock among them, has her born again of it on the same cells and
|
|
295
|
-
relations. A dock of yours stands on every open, since she stands once
|
|
296
|
-
the catalogue runs.
|
|
297
|
-
|
|
298
|
-
Every class comes from a registry. The catalogue is the library's, and a
|
|
299
|
-
class of yours extending `RegistryFaculty` is another: open it as any
|
|
300
|
-
faculty, and name it where a class is named. `open { key, class,
|
|
301
|
-
registry }` stands a faculty through it, `host { ward, registry }` stands
|
|
302
|
-
a ward and every class of it through it, and `become { class, registry }`
|
|
303
|
-
stands the dock through it, where the catalogue stands that registry. A
|
|
304
|
-
registry may stand through another.
|
|
305
|
-
|
|
306
|
-
A ward's place is kept by the root memory unless you name a memory
|
|
307
|
-
faculty. `open { key: 'vault', class: 'org.nervur.ground-memory' }` opens
|
|
308
|
-
the memory faculty every ground ships, and `host { ward, memory: 'vault' }`
|
|
309
|
-
keeps the ward there. A class of yours extending `MemoryFaculty` keeps a
|
|
310
|
-
ward in a bucket or a database the same way, and `move { ward, memory }`
|
|
311
|
-
carries a ward between keepers whole.
|
|
312
|
-
|
|
313
|
-
## What it holds
|
|
314
|
-
|
|
315
|
-
- **Being, Faculty, Ward, Dock.** What you extend, each a contract.
|
|
316
|
-
A faculty's contract is its class and every class between it and
|
|
317
|
-
`Faculty`. `DefaultWard` and `DefaultDock` are the kit's ward and dock.
|
|
318
|
-
- **Entropy, Clock, Custody, Memory, Carrier, Loader.** The contracts a
|
|
319
|
-
terrain fulfils. Each has one suite, and every body that fulfils it
|
|
320
|
-
passes it. `nervur/proof` hands you those suites and the unpacking
|
|
321
|
-
law's as scenes, a title and a function each, so a body of your own,
|
|
322
|
-
a memory in a cloud or a secret of your platform's, runs them under
|
|
323
|
-
your own runner: `for (const [title, scene] of memoryScenes('Mine',
|
|
324
|
-
make, expect)) test(title, scene)`. `@nervur-org/s3` is one such body.
|
|
325
|
-
- **Harbor, Terrain, Catalogue, Registry.** The onion.
|
|
326
|
-
- **World, PointerTerrain** and the pointer bodies. A whole world with
|
|
327
|
-
this package alone.
|
|
328
|
-
- **SourceLoader, BundleLoader.** A module's source run by the engine's
|
|
329
|
-
own import, its `nervur` linked to the kit running, and the modules a
|
|
330
|
-
bundle carries, found by their git blob, for a service worker, which
|
|
331
|
-
imports nothing once it runs.
|
|
332
|
-
- **addGround, grounds**: the grounds `Harbor.open()` tries, and a way to
|
|
333
|
-
add your own.
|
|
334
|
-
- **NodeTerrain**, from `nervur/node`: the Node ground's terrain, for a
|
|
335
|
-
folder you name in code.
|
|
336
|
-
- **BrowserTerrain, IdbMemory, IdbCustody**, from `nervur/browser`: the
|
|
337
|
-
browser ground's terrain and bodies. `serveWorker(Harbor.open())` at
|
|
338
|
-
the top of a shared or service worker holds one harbor for every tab,
|
|
339
|
-
each tab asks it with `rootOf(worker)`, and a push the service worker
|
|
340
|
-
hears is the dock's `heard`, told to every carrier.
|
|
341
|
-
- **harborShell, harborWorker, EdgeMemory, EdgeCustody, EdgeLoader**,
|
|
342
|
-
from `nervur/edge`, and the kit as one module's text, from
|
|
343
|
-
`nervur/edge/kit`: the edge's shell and the bodies its children stand
|
|
344
|
-
on.
|
|
345
|
-
- **FolderMemory, FolderCustody**, from `nervur/folder`.
|
|
346
|
-
- **TcpCarrier, TcpListener, NodeSockets**, from `nervur/tcp`: Quo over
|
|
347
|
-
TCP. Route a ward pk to its `tcp://host:port` addresses on the carrier,
|
|
348
|
-
hand the listener your harbor, and harbors in two processes, or a
|
|
349
|
-
harbor and another kit, speak. `TcpFaculty` is the same carrier as a
|
|
350
|
-
faculty of a harbor, on the sockets its terrain hands it:
|
|
351
|
-
`NodeSockets` on Node, a worker's own on the edge.
|
|
352
|
-
- **WebDialer, WebFaculty**: Quo over the web, a post to `https://` or a
|
|
353
|
-
held line to `wss://`, in any engine with `fetch` and WebSocket.
|
|
354
|
-
`webServe`, from `nervur/http`, is the listener a Node terrain hands
|
|
355
|
-
the web carrier. `answerPost(harbor, listen, request)` answers one post
|
|
356
|
-
and nothing more, for a function that opens a harbor per request and
|
|
357
|
-
closes it.
|
|
358
|
-
- **DEFAULTS**: the one list of beings and faculties every ground runs
|
|
359
|
-
where you write none, handed to a terrain as `defaults`.
|
|
85
|
+
Run the ground in the folder, and leave it running.
|
|
360
86
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
serve their clients, a UI in a browser, an MCP client, a caller holding
|
|
364
|
-
a bearer token, on one side, and stand as an ordinary being on the
|
|
365
|
-
other, offering standings, holding occupants and speaking Quo inbound
|
|
366
|
-
and outbound. They and every screen
|
|
367
|
-
are `@nervur-org/*`'s.
|
|
368
|
-
|
|
369
|
-
## The command
|
|
370
|
-
|
|
371
|
-
`nervur` stands a harbor on this machine: its seed and sealed memory in a
|
|
372
|
-
folder, Quo over TCP as its carrier. A module is a file that exports
|
|
373
|
-
`module`, `version` and `classes`.
|
|
374
|
-
|
|
375
|
-
```sh
|
|
376
|
-
nervur init --dir ./harbor
|
|
377
|
-
nervur module add ./greetings.js --dir ./harbor
|
|
378
|
-
nervur serve --dir ./harbor --port 7000
|
|
379
|
-
nervur reach tcp://harbor.example:7000 --dir ./harbor
|
|
380
|
-
nervur open web org.nervur.web --dir ./harbor
|
|
381
|
-
nervur ask web listen '{"port":8080,"path":"/quo"}' --dir ./harbor
|
|
382
|
-
nervur host alice --dir ./harbor
|
|
383
|
-
nervur boot --ward alice greeter org.example.greeter --dir ./harbor
|
|
384
|
-
nervur ask --ward alice greeter hello --dir ./harbor
|
|
87
|
+
```bash
|
|
88
|
+
npx nervur up .
|
|
385
89
|
```
|
|
386
90
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
where the harbor listens, which serves a harbor callers reach directly;
|
|
390
|
-
behind a router or a proxy, name the public address with `reach`. A
|
|
391
|
-
harbor that takes such an invitation keeps them as that ward's route,
|
|
392
|
-
so nobody routes it by hand. Where an invitation carries no `at`,
|
|
393
|
-
`nervur route <ward pk> tcp://host:port` names the route, and a route
|
|
394
|
-
named this way is trusted first.
|
|
395
|
-
|
|
396
|
-
`init` makes the harbor, opens its TCP carrier unless you pass
|
|
397
|
-
`--no-tcp`, and prints its pk and an owner invitation. `serve` listens for
|
|
398
|
-
Quo on that carrier and for the root's asks on a local socket, open to
|
|
399
|
-
you alone, and adds nothing to the harbor: one with no TCP carrier is not
|
|
400
|
-
served. Every other command is one root ask, sent to the served
|
|
401
|
-
harbor, or answered from the folder when none is served. Each prints one
|
|
402
|
-
JSON line. `--dir` defaults to `$NERVUR_DIR`, then `~/.nervur`.
|
|
403
|
-
`module add` reads the file and commits its text into the harbor's DNA,
|
|
404
|
-
so the harbor holds its own code on any ground. Routes live in the
|
|
405
|
-
harbor like everything else, so a restart finds both. `nervur modules`
|
|
406
|
-
shows what runs, `nervur module remove <module>` stops one, `nervur log`
|
|
407
|
-
walks the commits, `nervur live <commit>` moves `live`, and `nervur
|
|
408
|
-
origin <url>` with `nervur fetch` reads a git repository into the
|
|
409
|
-
harbor.
|
|
91
|
+
In a second shell, add the house once. The ground keeps it in its record,
|
|
92
|
+
and opens it again at every start.
|
|
410
93
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
```sh
|
|
415
|
-
nervur pilot far '<owner invitation>' --dir ./mine
|
|
416
|
-
nervur host shop --via far --dir ./mine
|
|
94
|
+
```bash
|
|
95
|
+
npx nervur houses add name=main memory='{"body":"ledger"}' classes='{"body":"folder","at":"house"}'
|
|
417
96
|
```
|
|
418
97
|
|
|
419
|
-
|
|
420
|
-
`far` as an ordinary Quo relation, kept in your harbor's memory, and
|
|
421
|
-
reaches the far harbor where its invitation's `at` says; where it says
|
|
422
|
-
nothing, name the address after the invitation. With
|
|
423
|
-
`--via far`, any command is asked of the far harbor as its owner, sealed
|
|
424
|
-
over TCP, except `own` and `disown`, which stay the far root's. Every ward
|
|
425
|
-
holds far beings this way, a ward or any other being whose invitation
|
|
426
|
-
carries the notes `{ owner: true }`, each under a name, asked with
|
|
427
|
-
`pilot { name, method, args }` and let go with `drop { name }`.
|
|
428
|
-
|
|
429
|
-
`harbor.ask(request)` is the same request in code, for any other front:
|
|
430
|
-
`{ ward?, method?, args? }` in, one JSON answer out.
|
|
98
|
+
Then ask the steward through the ground's hand.
|
|
431
99
|
|
|
432
|
-
|
|
100
|
+
```bash
|
|
101
|
+
npx nervur ask main hello name=Ada
|
|
102
|
+
```
|
|
433
103
|
|
|
434
|
-
|
|
104
|
+
Each ask greets Ada once more, since the count lands in the house's
|
|
105
|
+
ledger before the answer, and it outlives a restart. The ground keeps
|
|
106
|
+
the house's seed, its ledger and its record in `state/`, readable by
|
|
107
|
+
you alone. Keep that folder secret: a house opens on no other seed.
|
|
108
|
+
`npx nervur help` lists everything the ground offers.
|
|
435
109
|
|
|
436
|
-
|
|
437
|
-
nervur export --with-seed --dir ./harbor > harbor.json
|
|
438
|
-
nervur import harbor.json --dir ./elsewhere
|
|
439
|
-
```
|
|
110
|
+
## Entries
|
|
440
111
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
112
|
+
| Entry | For |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `nervur/being` | writing a being: `Being`, `s`, `need`, `Args`, `Result` |
|
|
115
|
+
| `nervur` | any engine: `Ground`, `House` and the bodies they take |
|
|
116
|
+
| `nervur/node` | a ground on Node: `NodeGround`, the `nervur` command, and its bodies |
|
|
117
|
+
| `nervur/bench` | tests: `Bench`, `BenchGround`, `FakeNetwork` and the fakes of every body |
|
|
446
118
|
|
|
447
119
|
## License
|
|
448
120
|
|
|
449
|
-
Apache-2.0.
|
|
121
|
+
Apache-2.0, © Bookarest Digital SRL. Quo is a separate work, under its
|
|
122
|
+
own license. See `NOTICE`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { 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 custody and memory are the shell's own. */
|
|
17
|
+
open({ shell, load, origin, ...options }: AppGroundOptions): Promise<BrowserGround>;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
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 seeds rest 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
|
+
// recipe's faculty, since the library ships no faculty.
|
|
8
|
+
import { BrowserGround } from '../browser/browser-ground.js';
|
|
9
|
+
import { NativeCustody, NativeMemory } from './native.js';
|
|
10
|
+
export const AppGround = Object.freeze({
|
|
11
|
+
/** The app's ground: a BrowserGround whose custody and memory are the shell's own. */
|
|
12
|
+
open({ shell, load, origin, ...options }) {
|
|
13
|
+
return BrowserGround.open({
|
|
14
|
+
...options,
|
|
15
|
+
platform: {
|
|
16
|
+
custody: async () => new NativeCustody(shell.secrets),
|
|
17
|
+
memory: async (name) => new NativeMemory(shell.store, name),
|
|
18
|
+
// The system keeps an app's own store, so there is nothing to ask.
|
|
19
|
+
persist: async () => true,
|
|
20
|
+
...(load === undefined ? {} : { load }),
|
|
21
|
+
...(origin === undefined ? {} : { origin }),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
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 { NativeCustody, NativeMemory } from './native.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Keys, Memory, PlaceRead } from '../foundation.ts';
|
|
2
|
+
import type { Custody } from '../ground/ground.ts';
|
|
3
|
+
/** The platform's secret store: text by name, kept by the Keychain or the Keystore, on this device alone. */
|
|
4
|
+
export interface NativeSecrets {
|
|
5
|
+
get(name: string): Promise<string | null>;
|
|
6
|
+
set(name: string, value: string): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
/** A native store of text by key, which the operating system never evicts. */
|
|
9
|
+
export interface NativeStore {
|
|
10
|
+
get(key: string): Promise<string | null>;
|
|
11
|
+
/** Every key that begins with `prefix`. */
|
|
12
|
+
keys(prefix: string): Promise<readonly string[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Lands every write together, where every key in `expect` still holds
|
|
15
|
+
* what it names, `null` for absent; otherwise lands nothing. A write of
|
|
16
|
+
* `null` removes its key. Answers whether it landed.
|
|
17
|
+
*/
|
|
18
|
+
swap(writes: Readonly<Record<string, string | null>>, expect: Readonly<Record<string, string | null>>): Promise<boolean>;
|
|
19
|
+
}
|
|
20
|
+
/** One seed for each house in the platform's secret store, drawn on first use. */
|
|
21
|
+
export declare class NativeCustody implements Custody {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(secrets: NativeSecrets);
|
|
24
|
+
keys({ house }: {
|
|
25
|
+
house: string;
|
|
26
|
+
}): Promise<Keys>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Memory over a native store, one memory for each name. Each place is one
|
|
30
|
+
* key, its entries as hex beside its version. Versions come from one
|
|
31
|
+
* counter for the memory, so a place removed and written again never
|
|
32
|
+
* shows a version it showed before. A write reads every place it names
|
|
33
|
+
* and swaps them all against what it read.
|
|
34
|
+
*/
|
|
35
|
+
export declare class NativeMemory implements Memory {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(store: NativeStore, name: string);
|
|
38
|
+
read({ place }: {
|
|
39
|
+
place: string;
|
|
40
|
+
}): Promise<PlaceRead>;
|
|
41
|
+
list(): Promise<readonly string[]>;
|
|
42
|
+
write({ writes, expect, }: {
|
|
43
|
+
writes: Readonly<Record<string, Readonly<Record<string, Uint8Array | null>>>>;
|
|
44
|
+
expect: Readonly<Record<string, string | null>>;
|
|
45
|
+
}): Promise<Readonly<Record<string, string | null>> | null>;
|
|
46
|
+
}
|