refactor(api): l'app nomme une personne ou un document, jamais une adresse d'inbox
L'app d'exemple a servi de juge, et elle a immédiatement montré ce que l'inventaire ne montrait pas : pour partager une note elle résolvait l'inbox du destinataire, pour lire ses messages elle résolvait l'adresse de la sienne. Deux gestes qu'aucune application n'aura à faire une fois la chose native — donc deux gestes qu'elle ne doit pas apprendre. - `shareCap(cap, toUser)` remplace `shareCap(cap, toInbox)`. Partager est un acte envers quelqu'un ; où est son inbox regarde la bibliothèque. - `inbox.readForDocument(doc)` : le propriétaire lit ses messages en nommant la note, comme le déposant la nomme pour en laisser un. - `storeRegistry.userInbox` et `documentInboxAddress` sortent de la surface publiée. Ils restent joignables en interne, où le shim en a besoin. Sortent aussi de `/polyfill`, chacun parce qu'une app qui code contre apprend ce qu'il faudra désapprendre : - `getCaps` / `CapRegistry` — la salle des machines. La question du consommateur est `capFor(doc)` : est-ce que je le détiens ? Le registre n'a ni successeur ni forme inerte ; ce qui s'appuie dessus sera à réécrire, pas à laisser en place. - `getCurrentUser` — une app sait qui elle a connecté ; le redemander à la bibliothèque est une commodité du wallet partagé. - `virtualUsers` / `IdentityStore` — se souvenir d'une identité entre deux sessions est aussi le travail de l'app en amont. L'écran d'accès persiste ce dont IL a besoin ; rien d'autre n'a à être exposé. Reste sur `/polyfill` ce qu'une app appelle vraiment : `configure` et `setCurrentUser`. Le reste y est du test ou de l'injection interne. 170 tests unitaires, e2e 42/42 contre le broker, typecheck vert sur la bibliothèque, l'exemple et le harnais.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
* The difference between Bob and Charlie is ONLY each of them holds. There is
|
||||
* no authorization list anywhere, and nobody was named to the registry.
|
||||
*/
|
||||
import { getCaps } from "../src/shared-wallet/bootstrap";
|
||||
import { test, expect, mock, afterAll } from "bun:test";
|
||||
import {
|
||||
createEntityDoc,
|
||||
@@ -25,18 +26,7 @@ import {
|
||||
} from "../src/shared-wallet/account-registry";
|
||||
import { documentInboxAddress, openDocumentInbox } from "../src/emulated-verifier/branch-registers";
|
||||
import type { RegistrySession } from "../src/shared-wallet/account-registry";
|
||||
import {
|
||||
configure,
|
||||
configureStoreRegistry,
|
||||
resetStoreRegistry,
|
||||
resetConfig,
|
||||
capFor,
|
||||
getCaps,
|
||||
resetCaps,
|
||||
setCurrentUser,
|
||||
shareCap,
|
||||
connectedUser,
|
||||
} from "../src/polyfill";
|
||||
import {configure,configureStoreRegistry,resetStoreRegistry,resetConfig,capFor,resetCaps,setCurrentUser,shareCap,connectedUser} from "../src/polyfill";
|
||||
import { post, postToDocument, read as readInbox } from "../src/surface/inbox";
|
||||
import { readUnion } from "../src/surface/read-model";
|
||||
import { sparqlUpdate } from "../src/surface/docs";
|
||||
@@ -267,7 +257,7 @@ test("Charlie: same public document, same reference — and he reads through it"
|
||||
// Alice decides Charlie may read that ONE document, and delivers its cap to his
|
||||
// inbox. She names no principal to the registry; she addresses an inbox.
|
||||
setCurrentUser("alice");
|
||||
await shareCap(protCap, CHARLIE_INBOX);
|
||||
await shareCap(protCap, "charlie");
|
||||
|
||||
setCurrentUser("charlie");
|
||||
getCaps().learn(pubLink);
|
||||
@@ -285,7 +275,7 @@ test("the ONLY difference between Bob and Charlie is each of them holds", async
|
||||
const CHARLIE_INBOX = await userInbox("charlie", "protected");
|
||||
|
||||
setCurrentUser("alice");
|
||||
await shareCap(protCap, CHARLIE_INBOX);
|
||||
await shareCap(protCap, "charlie");
|
||||
|
||||
setCurrentUser("bob");
|
||||
getCaps().learn(pubLink);
|
||||
@@ -326,7 +316,7 @@ test("dynamic: a cap delivered to Bob's inbox makes the refused document readabl
|
||||
// Alice delivers the cap. Bob's client processes his inbox — the only thing that
|
||||
// happens; no "receive" call exists.
|
||||
setCurrentUser("alice");
|
||||
await shareCap(protCap, BOB_INBOX);
|
||||
await shareCap(protCap, "bob");
|
||||
setCurrentUser("bob");
|
||||
await readInbox(BOB_INBOX);
|
||||
|
||||
@@ -364,7 +354,7 @@ test("a Link is APPLIED durably: the cap survives with the inbox emptied", async
|
||||
const bobInbox = await userInbox("bob", "protected");
|
||||
|
||||
setCurrentUser("alice");
|
||||
await shareCap(protCap, bobInbox);
|
||||
await shareCap(protCap, "bob");
|
||||
|
||||
// Bob connects: the library restores + drains, with nothing asked of the app.
|
||||
setCurrentUser("bob");
|
||||
@@ -502,7 +492,7 @@ test("connecting drains BOTH levels: the user's inbox and its documents'", async
|
||||
// Two deposits, one at each level, both made by someone else.
|
||||
setCurrentUser("carol");
|
||||
const carolDoc = await createEntityDoc("carol", "protected");
|
||||
await shareCap(capFor(carolDoc)!, aliceInbox); // a Link, to alice herself
|
||||
await shareCap(capFor(carolDoc)!, "alice"); // a Link, to alice herself
|
||||
await post(docInbox, { payload: { onTheDocument: true }, ts: 2 });
|
||||
|
||||
// Alice connects: one call, both queues.
|
||||
|
||||
Reference in New Issue
Block a user