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:
@@ -19,9 +19,7 @@ import {
|
||||
configure,
|
||||
configureStoreRegistry,
|
||||
setCurrentUser,
|
||||
getCurrentUser,
|
||||
capFor,
|
||||
getCaps,
|
||||
resetCaps,
|
||||
shareCap,
|
||||
connectedUser,
|
||||
@@ -40,6 +38,8 @@ import {
|
||||
// application must not — but through the internal path, never the published entry.
|
||||
// `storeRegistry` above is the app-facing slice; these are the shim internals.
|
||||
import * as registryInternals from "../src/shared-wallet/account-registry";
|
||||
import { getCaps, getCurrentUser } from "../src/shared-wallet/bootstrap";
|
||||
import { documentInboxAddress } from "../src/emulated-verifier/branch-registers";
|
||||
import * as virtualUsers from "../src/shared-wallet/virtual-users";
|
||||
import { isNuri, ensureIdentity } from "@ng-eventually/client";
|
||||
import type { Nuri, ShapeObservable, ShapeQuery } from "@ng-eventually/client";
|
||||
@@ -433,7 +433,7 @@ const identity = new IdentityStore(
|
||||
// deposit into anyone's, you may only read your own. Establishing the identity
|
||||
// FIRST is what makes `userInbox` resolve (and file) that user's inbox.
|
||||
setCurrentUser(id);
|
||||
const target = await storeRegistry.userInbox(id, "protected");
|
||||
const target = await registryInternals.userInbox(id, "protected");
|
||||
await inbox.post(target, { payload: payloadA, from: null, ts: 1000 });
|
||||
await inbox.post(target, { payload: payloadB, from: null, ts: 2000 });
|
||||
const deposits = await inbox.read(target);
|
||||
@@ -447,7 +447,7 @@ const identity = new IdentityStore(
|
||||
// Watching an inbox is READING it continuously, so the watcher stays connected
|
||||
// for the whole probe — including across `inboxWatchDeposit`.
|
||||
setCurrentUser(id);
|
||||
const target = await storeRegistry.userInbox(id, "protected");
|
||||
const target = await registryInternals.userInbox(id, "protected");
|
||||
const rec = { fires: 0, lastLen: -1, unsub: () => {}, target };
|
||||
(window as any).__sdk._inboxWatch = rec;
|
||||
rec.unsub = inbox.watch(target, (deposits) => {
|
||||
@@ -874,7 +874,7 @@ const identity = new IdentityStore(
|
||||
|
||||
setCurrentUser(depositorId);
|
||||
getCaps().learn(link);
|
||||
const resolved = await storeRegistry.documentInboxAddress(doc);
|
||||
const resolved = await documentInboxAddress(doc);
|
||||
// The one-call form an app actually uses: it names the DOCUMENT, never an inbox.
|
||||
await inbox.postToDocument(doc, { payload: { viaPostToDocument: true }, ts: 900 });
|
||||
// Opening one on someone else's document must be refused, not silently forked.
|
||||
@@ -908,7 +908,7 @@ const identity = new IdentityStore(
|
||||
// the recipient's durable Links would grow run after run on a persistent wallet,
|
||||
// making every later `connectedUser()` re-apply a longer and longer history.
|
||||
setCurrentUser(friendId);
|
||||
const friendInbox = await storeRegistry.userInbox(friendId, "protected");
|
||||
const friendInbox = await registryInternals.userInbox(friendId, "protected");
|
||||
|
||||
setCurrentUser("owner-O");
|
||||
const doc = await docs.docCreate(s.session_id, "Graph", "data:graph", "store", undefined);
|
||||
@@ -920,7 +920,7 @@ const identity = new IdentityStore(
|
||||
const before = [...(libUseShape(null, null) as Iterable<any>)].length;
|
||||
|
||||
setCurrentUser("owner-O");
|
||||
await shareCap(cap, friendInbox);
|
||||
await shareCap(cap, friendId);
|
||||
|
||||
setCurrentUser(friendId);
|
||||
const absorbed = await inbox.read(friendInbox); // processing it applies the cap
|
||||
|
||||
Reference in New Issue
Block a user