nervur 0.22.1 → 0.22.2-4
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 +814 -0
- package/KIT-SPEC.md +286 -0
- package/README.md +128 -431
- 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 +229 -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 +27 -0
- package/dist/browser/locked-custody.js +93 -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 +40 -56
- 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 -50
- package/dist/core/harbor/carrying.js +0 -66
- 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 -448
- 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 -70
- package/dist/core/ward/house.js +0 -499
- 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 -51
- package/dist/core/ward/partition.js +0 -66
- package/dist/core/ward/stance.d.ts +0 -31
- package/dist/core/ward/stance.js +0 -193
- 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 -121
- 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 -441
- 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 -550
- package/src/core/ward/index.ts +0 -7
- package/src/core/ward/partition.ts +0 -120
- package/src/core/ward/stance.ts +0 -215
- 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,461 +1,158 @@
|
|
|
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
|
-
|
|
46
|
-
|
|
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' } });
|
|
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}.`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
58
47
|
```
|
|
59
48
|
|
|
60
|
-
## A
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
+
});
|
|
81
72
|
```
|
|
82
73
|
|
|
83
|
-
|
|
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"
|
|
74
|
+
## A ground
|
|
92
75
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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.
|
|
96
79
|
|
|
97
|
-
|
|
98
|
-
|
|
80
|
+
```ts
|
|
81
|
+
// house/index.ts
|
|
82
|
+
export { Greeter as steward } from '../greeter.ts';
|
|
99
83
|
```
|
|
100
84
|
|
|
101
|
-
|
|
102
|
-
plan. `wrangler dev` runs it on your machine at no cost.
|
|
85
|
+
Run the ground in the folder, and leave it running.
|
|
103
86
|
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
87
|
+
```bash
|
|
88
|
+
npx nervur up .
|
|
112
89
|
```
|
|
113
90
|
|
|
114
|
-
|
|
115
|
-
it
|
|
91
|
+
In a second shell, add the house once. The ground keeps it in its record,
|
|
92
|
+
and opens it again at every start.
|
|
116
93
|
|
|
117
|
-
```
|
|
118
|
-
nervur
|
|
94
|
+
```bash
|
|
95
|
+
npx nervur houses add name=main memory='{"body":"ledger"}' classes='{"body":"folder","at":"house"}'
|
|
119
96
|
```
|
|
120
97
|
|
|
121
|
-
|
|
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`:
|
|
98
|
+
Then ask the steward through the ground's hand.
|
|
153
99
|
|
|
154
|
-
```
|
|
155
|
-
|
|
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 };
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export const classes = [SystemTime, Greeter];
|
|
100
|
+
```bash
|
|
101
|
+
npx nervur ask main hello name=Ada
|
|
186
102
|
```
|
|
187
103
|
|
|
188
|
-
|
|
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.
|
|
189
109
|
|
|
190
|
-
|
|
191
|
-
import { readFile } from 'node:fs/promises';
|
|
192
|
-
import { DEFAULTS, World } from 'nervur';
|
|
110
|
+
## A ground in a page
|
|
193
111
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const source = await readFile('./greetings.js', 'utf8');
|
|
197
|
-
await harbor.ask({ method: 'ask', args: { being: 'catalogue', method: 'add', args: { source } } });
|
|
198
|
-
await harbor.ask({ method: 'open', args: { key: 'clock', class: 'org.example.system-time' } });
|
|
199
|
-
await harbor.ask({ method: 'host', args: { ward: 'alice' } });
|
|
200
|
-
await harbor.ask({ ward: 'alice', method: 'boot', args: { key: 'greeter', class: 'org.example.greeter' } });
|
|
201
|
-
```
|
|
112
|
+
The same house runs in a browser. Bundle the house's module and serve it
|
|
113
|
+
on your origin, beside a page that opens the ground.
|
|
202
114
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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.
|
|
248
|
-
|
|
249
|
-
## The onion
|
|
250
|
-
|
|
251
|
-
A harbor is one package. Only the seed and the terrain's bodies, its
|
|
252
|
-
loader among them, stand outside it. It stands in three levels, and each
|
|
253
|
-
level stands the next and leaves it alone.
|
|
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' });
|
|
277
|
-
```
|
|
115
|
+
```ts
|
|
116
|
+
// page.ts
|
|
117
|
+
import { BrowserGround } from 'nervur/browser';
|
|
278
118
|
|
|
279
|
-
|
|
280
|
-
|
|
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)`.
|
|
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`.
|
|
360
|
-
- **CarrierFaculty**: a carrier of your own. It says which addresses it
|
|
361
|
-
accepts, dials them, and says the carrier of Quo it `carries`, `tcp`
|
|
362
|
-
or `web`, so the command finds it. One that answers `relay` for a ward
|
|
363
|
-
pk no door holds is handed that pk's boxes, and every carrier hears
|
|
364
|
-
the dock's `heard` when a device hears a push.
|
|
365
|
-
|
|
366
|
-
Quo crosses two carriers, TCP and the web, and no third. MCP, an HTTP API
|
|
367
|
-
and every other outside protocol are gateway faculties: classes that
|
|
368
|
-
serve their clients, a UI in a browser, an MCP client, a caller holding
|
|
369
|
-
a bearer token, on one side, and stand as an ordinary being on the
|
|
370
|
-
other, offering standings, holding occupants and speaking Quo inbound
|
|
371
|
-
and outbound. They and every screen
|
|
372
|
-
are classes written over this package, and none ships in it.
|
|
373
|
-
|
|
374
|
-
## The command
|
|
375
|
-
|
|
376
|
-
`nervur` stands a harbor on this machine: its seed and sealed memory in a
|
|
377
|
-
folder, Quo over TCP as its carrier. A module is a file that exports
|
|
378
|
-
`module`, `version` and `classes`.
|
|
379
|
-
|
|
380
|
-
```sh
|
|
381
|
-
nervur init --dir ./harbor
|
|
382
|
-
nervur module add ./greetings.js --dir ./harbor
|
|
383
|
-
nervur serve --dir ./harbor --port 7000
|
|
384
|
-
nervur reach tcp://harbor.example:7000 --dir ./harbor
|
|
385
|
-
nervur open web org.nervur.web --dir ./harbor
|
|
386
|
-
nervur ask web listen '{"port":8080,"path":"/quo"}' --dir ./harbor
|
|
387
|
-
nervur host alice --dir ./harbor
|
|
388
|
-
nervur boot --ward alice greeter org.example.greeter --dir ./harbor
|
|
389
|
-
nervur ask --ward alice greeter hello --dir ./harbor
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
`reach` names where the harbor is reached, and every invitation it gives
|
|
393
|
-
carries those addresses in `at`. With no `reach`, an invitation carries
|
|
394
|
-
where the harbor listens, which serves a harbor callers reach directly;
|
|
395
|
-
behind a router or a proxy, name the public address with `reach`. A
|
|
396
|
-
harbor that takes such an invitation keeps them as that ward's route,
|
|
397
|
-
so nobody routes it by hand. Where an invitation carries no `at`,
|
|
398
|
-
`nervur route <ward pk> tcp://host:port` names the route, and a route
|
|
399
|
-
named this way is trusted first.
|
|
400
|
-
|
|
401
|
-
`init` makes the harbor, opens its TCP carrier unless you pass
|
|
402
|
-
`--no-tcp`, and prints its pk and an owner invitation. `serve` listens for
|
|
403
|
-
Quo on that carrier and for the root's asks on a local socket, open to
|
|
404
|
-
you alone, and adds nothing to the harbor: one with no TCP carrier is not
|
|
405
|
-
served. Every other command is one root ask, `pilot` at most two, sent
|
|
406
|
-
to the served harbor, or answered from the folder when none is served.
|
|
407
|
-
Each prints one JSON line. `--dir` defaults to `$NERVUR_DIR`, then `~/.nervur`.
|
|
408
|
-
`module add` reads the file and commits its text into the harbor's DNA,
|
|
409
|
-
so the harbor holds its own code on any ground. Routes live in the
|
|
410
|
-
harbor like everything else, so a restart finds both. `nervur modules`
|
|
411
|
-
shows what runs, `nervur module remove <module>` stops one, `nervur log`
|
|
412
|
-
walks the commits, `nervur live <commit>` moves `live`, and `nervur
|
|
413
|
-
origin <url>` with `nervur fetch` reads a git repository into the
|
|
414
|
-
harbor.
|
|
415
|
-
|
|
416
|
-
A harbor elsewhere is piloted with the owner invitation its `init`
|
|
417
|
-
printed, from a harbor of your own:
|
|
418
|
-
|
|
419
|
-
```sh
|
|
420
|
-
nervur pilot far '<owner invitation>' --dir ./mine
|
|
421
|
-
nervur host shop --via far --dir ./mine
|
|
422
|
-
```
|
|
119
|
+
// Every tab of this origin joins one ground, and the tab holding its lock runs it.
|
|
120
|
+
const ground = await BrowserGround.open();
|
|
423
121
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
owner, sealed over its carrier, except `own` and `disown`, which stay
|
|
431
|
-
the far root's. Every ward holds far beings this way, a ward or any
|
|
432
|
-
other being whose invitation
|
|
433
|
-
carries the notes `{ owner: true }`, each under a name, asked with
|
|
434
|
-
`pilot { name, method, args }` and let go with `drop { name }`.
|
|
122
|
+
// The house's code is a module on this origin, and its rows live in IndexedDB.
|
|
123
|
+
await ground.hand({
|
|
124
|
+
faculty: 'houses',
|
|
125
|
+
method: 'add',
|
|
126
|
+
args: { name: 'main', memory: { body: 'indexeddb' }, classes: { body: 'origin', at: '/house/index.js' } },
|
|
127
|
+
});
|
|
435
128
|
|
|
436
|
-
|
|
437
|
-
`{ ward?, method?, args? }` in, one JSON answer out.
|
|
438
|
-
|
|
439
|
-
## Moving a harbor
|
|
440
|
-
|
|
441
|
-
A harbor moves to another machine by its bytes, with no harbor open:
|
|
442
|
-
|
|
443
|
-
```sh
|
|
444
|
-
nervur export --with-seed --dir ./harbor > harbor.json
|
|
445
|
-
nervur import harbor.json --dir ./elsewhere
|
|
129
|
+
console.log(await ground.hand({ house: 'main', method: 'hello', args: { name: 'Ada' } }));
|
|
446
130
|
```
|
|
447
131
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
132
|
+
Every tab of the origin reaches the one ground, and when the tab running
|
|
133
|
+
it closes, the next opens it from the same storage. Its seeds are sealed
|
|
134
|
+
under a key the browser never hands out. Any script on the origin can
|
|
135
|
+
use them, so give the ground an origin of its own, with a strict content
|
|
136
|
+
security policy. The page and the house's module must share one copy of
|
|
137
|
+
`nervur/being`, as a bundler's shared chunk gives.
|
|
138
|
+
|
|
139
|
+
An app on a phone opens the same ground with `AppGround` from
|
|
140
|
+
`nervur/app`, on the Keychain or the Keystore and a store the system
|
|
141
|
+
keeps. `AUTHORING.md` shows both.
|
|
142
|
+
|
|
143
|
+
## Entries
|
|
144
|
+
|
|
145
|
+
| Entry | For |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `nervur/being` | writing a being: `Being`, `s`, `need`, `Args`, `Result` |
|
|
148
|
+
| `nervur` | any engine: `Ground`, `House` and the bodies they take |
|
|
149
|
+
| `nervur/node` | a ground on Node: `NodeGround`, the `nervur` command, and its bodies |
|
|
150
|
+
| `nervur/browser` | a ground in a page or its service worker: `BrowserGround` and its bodies |
|
|
151
|
+
| `nervur/app` | a ground in a phone's app: `AppGround`, and the two interfaces its shell fills |
|
|
152
|
+
| `nervur/serve` | a faculty's program in JavaScript: `serve` |
|
|
153
|
+
| `nervur/bench` | tests: `Bench`, `BenchGround`, `FakeNetwork` and the fakes of every body |
|
|
453
154
|
|
|
454
155
|
## License
|
|
455
156
|
|
|
456
|
-
Apache-2.0
|
|
457
|
-
|
|
458
|
-
[Quo](https://quo.systems) is a separate work, Razvan Gherghina's, also
|
|
459
|
-
under Apache-2.0, and its spec names no kit. `nervur` is Quo's first
|
|
460
|
-
implementation and says so gladly: the protocol owes this package
|
|
461
|
-
nothing, and where the two disagree the spec wins.
|
|
157
|
+
Apache-2.0, © Bookarest Digital SRL. Quo is a separate work, under its
|
|
158
|
+
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';
|