/** * Stands in for Home around the system private inbox: it holds the inbox and * the owner's profiles, and gives a sender and a stranger handlers of their own * that reach the inbox through a profile. Four more stand-ins, `adoptingHome`, * `refusingHome`, `curedHome` and `creatingHome`, are Homes whose profiles * already point at inboxes when the host first ensures their own, and a fifth, * `readoptingHome`, is one whose default profile is pointed elsewhere after it * holds an inbox, and a sixth, `replacingHome`, is one whose owner replaces the * inbox it was refused. A seventh, `ownSpaceHome`, records a refusal of the * private inbox, the one in Home's own `private-inbox` space, and its owner * replaces it, and an eighth, `unreadableRefusedHome`, is refused an inbox * whose space stops letting the owner read it, which its owner replaces. * `olderHome` stands in for a Home of the vintage whose ensure takes no * refusal, and `unreadableHome` for one whose profile keeps its pointer per * user. `requestingHome`, `profilelessHome` and `leavingHome` are Homes whose * inboxes a client requests, as a loom daemon does: a profile of the first's * may be of a vintage without `setInbox`, the second has no profiles, and the * third loses its first profile once its inbox is requested. `racingHome` is * a Home whose one profile two runtimes of the owner's point at inboxes of * their own, each only while it points at none. Fixture for * `private-inbox-multi-runtime.test.ts`. */ import { type Cell, currentPrincipal, Default, type DID, handler, NAME, pattern, revokeSpaceAccess, type Stream, UI, type VNode, Writable, } from "commonfabric"; import EarlierProfile from "./earlier-profile.tsx"; import UserScopedProfile from "./user-scoped-profile.tsx"; import ProfileCreate from "../../../system/profile-create.tsx"; import ProfileHome, { type ProfileHomeOutput, } from "../../../system/profile-home.tsx"; import PrivateInbox, { ensurePrivateInbox, type EnsurePrivateInboxEvent, type Offer, type OfferEvent, pointProfilesAtPrivateInbox, type PointTarget, PrivateInboxAnswering, type PrivateInboxHolder, type PrivateInboxOutput, type PrivateInboxPiece, type PrivateInboxReceipt, type PrivateInboxRefusalHolder, type PrivateInboxReplacementHolder, type PrivateInboxRequest, replaceRefusedPrivateInbox, repointProfilesFromReplacedInbox, requestPrivateInbox, type RetainedPrivateInboxes, } from "../../../system/private-inbox.tsx"; /** The host origin every offer here names. */ const OFFER_HOST = "https://example.com"; /** An offer a sender's handler sends on to the owner's inbox. */ export interface OfferRequest { /** The sender's key for the offer. */ id: string; /** The DID of the space offered. */ space: string; /** What the sender calls it. */ title: string; } /** * The envelope a sender sends for `request`, from the principal sending the * event. */ function envelopeOf(request: OfferRequest): OfferEvent { return { kind: "fabrichat-room", id: request.id, space: request.space, host: OFFER_HOST, ownerOrigin: OFFER_HOST, title: request.title, from: currentPrincipal(), sharedAt: Date.now(), }; } /** The fields of an offer a copy keeps. */ export interface CopiedOffer { title: string; from: string; } /** An inbox a link reaches, as the cell its result is. */ function inboxOf(link: unknown): Cell; function inboxOf(link: unknown): unknown { return link; } /** An inbox's result, as the link a holder keeps. */ function inboxLinkOf(inbox: unknown): Cell; function inboxLinkOf(inbox: unknown): unknown { return inbox; } /** A stand-in profile's result, as an entry in the owner's profile list. */ function asProfile(profile: unknown): ProfileHomeOutput; function asProfile(profile: unknown): unknown { return profile; } /** * Creates one of the owner's profiles, in a space of its own that grants * anyone `WRITE`, as `profile-create.tsx` does. */ const createProfile = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.push( ProfileHome.inSpace(undefined, { grants: { "*": "WRITE" } })({ initialName: "Owner", }) as ProfileHomeOutput, ); }); /** * Creates a profile of an earlier vintage, in a space of its own that grants * anyone `WRITE`. */ const createEarlierProfile = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.push( asProfile( EarlierProfile.inSpace(undefined, { grants: { "*": "WRITE" } })({}), ), ); }); /** The result of {@link PointerOnlyProfile}. */ interface PointerOnlyProfileOutput { [NAME]: string; /** The stand-in's name, which every profile vintage holds. */ name: string; /** Where the stand-in points, which nothing here sets. */ inbox: { piece?: Cell }; } /** * Stands in for a profile of a vintage without `setInbox`, the stream through * which alone Home points a profile: a name and a pointer. */ const PointerOnlyProfile = pattern< Record, PointerOnlyProfileOutput >(() => ({ [NAME]: "Pointer-only profile", name: "Pointer-only profile", inbox: new Writable<{ piece?: Cell }>({}).for("inbox"), })); /** * Creates a profile of a vintage without `setInbox`, in a space of its own that * grants anyone `WRITE`. */ const createPointerOnlyProfile = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.push( asProfile( PointerOnlyProfile.inSpace(undefined, { grants: { "*": "WRITE" } })({}), ), ); }); /** * Creates a profile keeping its pointer per user, in a space of its own that * grants anyone `WRITE`. */ const createUserScopedProfile = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.push( asProfile( UserScopedProfile.inSpace(undefined, { grants: { "*": "WRITE" } })({}), ), ); }); /** Creates an inbox other than the private inbox, in a space of its own. */ const createOtherInbox = handler< void, { otherInbox: Writable } >((_event, { otherInbox }) => { otherInbox.set({ piece: inboxLinkOf(PrivateInbox.inSpace()({ offers: [] })), }); }); /** * Creates an inbox in a space of its own that grants every principal `WRITE`, * as a loom daemon creates its share inbox, and keeps it in `inbox`. The * principal sending the event owns the space. */ const createSharedInbox = handler< void, { inbox: Writable } >((_event, { inbox }) => { inbox.set({ piece: inboxLinkOf( PrivateInbox.inSpace(undefined, { grants: { "*": "WRITE" } })({ offers: [], }), ), }); }); /** Which of the owner's profiles to point at an inbox. */ export interface PointElsewhereRequest { /** The profile's position in its list. */ index: number; } /** Points one of the profiles in `profiles` at the inbox `inbox` holds. */ const pointProfileAt = handler< PointElsewhereRequest, { profiles: Writable; inbox: Writable; } >((event, { profiles, inbox }) => { profiles.key(event.index).resolveAsCell().key("setInbox").send({ inbox: inbox.get().piece?.resolveAsCell(), }); }); /** * Points one of the profiles in `profiles` at the inbox `inbox` holds, only * while the profile points at no inbox, as Home and a loom daemon point one. */ const pointProfileAtIfUnset = handler< PointElsewhereRequest, { profiles: Writable; inbox: Writable; } >((event, { profiles, inbox }) => { profiles.key(event.index).resolveAsCell().key("setInbox").send({ inbox: inbox.get().piece?.resolveAsCell(), replacing: undefined, }); }); /** The principal an inbox's space is to let read it. */ export interface ReaderRequest { /** The principal's DID. */ reader: DID; } /** * Creates an inbox in a space of its own that grants `reader` `READ` and no * one else anything, and keeps it in `inbox`. The principal sending the event * owns the space. */ const createReadableByInbox = handler< ReaderRequest, { inbox: Writable } >((event, { inbox }) => { inbox.set({ piece: inboxLinkOf( PrivateInbox.inSpace(undefined, { grants: { [event.reader]: "READ" } })({ offers: [], }), ), }); }); /** Revokes `reader`'s access to the space of the inbox `inbox` holds. */ const revokeReader = handler< ReaderRequest, { inbox: Writable } >((event, { inbox }) => { const piece = inbox.get().piece?.resolveAsCell(); if (piece === undefined) return; revokeSpaceAccess(piece, event.reader); }); /** * Records in `refusal` the host's refusal of the inbox `inbox` holds, as Home's * ensure records one, for a Home holding none. */ const recordRefusalOf = handler< void, { inbox: Writable; refusal: Writable; } >((_event, { inbox, refusal }) => { const refused = inbox.get().piece?.resolveAsCell(); if (refused === undefined) return; refusal.set({ refusal: { reason: "inbox-offers-invalid", inbox: refused, refusedAt: Date.now(), }, }); }); /** * Takes the first profile out of `profiles`, by removing its link, which * leaves every other entry as it is stored. */ const dropFirstProfile = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.removeByValue(profiles.key(0).resolveAsCell()); }); /** Empties `profiles`. */ const dropProfiles = handler< void, { profiles: Writable } >((_event, { profiles }) => { profiles.set([]); }); /** A Home's default profile, held under `profile` as Home's slot holds it. */ export interface DefaultProfileSlot { /** The default profile, absent while none is chosen. */ profile?: Cell; } /** Makes one of `profiles` the default, as Home's picker does. */ const setDefaultProfile = handler< PointElsewhereRequest, { profiles: Writable; defaultProfile: Writable; } >((event, { profiles, defaultProfile }) => { defaultProfile.set({ profile: profiles.key(event.index).resolveAsCell() }); }); /** What the host reads of a Home, and sends it, and what a test drives. */ export interface HomeStandInOutput { [NAME]: string; privateInbox: PrivateInboxHolder; retainedPrivateInboxes: RetainedPrivateInboxes; privateInboxRefusal: PrivateInboxRefusalHolder; privateInboxReplacement: PrivateInboxReplacementHolder; profiles: ProfileHomeOutput[]; defaultProfile: DefaultProfileSlot; /** Makes one of the Home's profiles its default. */ setDefaultProfile: Stream; /** Gives the Home a private inbox, as Home's own stream does. */ ensurePrivateInbox: Stream; /** * Has the Home ensure its inbox and answers with it, as Home's own stream * does. */ requestPrivateInbox: Stream; /** Replaces the inbox the Home was refused, as Home's own stream does. */ replaceRefusedPrivateInbox: Stream; /** Creates one of the Home's profiles. */ createProfile: Stream; /** Creates a profile of an earlier vintage in the Home. */ createEarlierProfile: Stream; } /** * Stands in for a Home whose profiles may point at inboxes before the host * first ensures its own. `label` keeps each stand-in's state its own. */ const HomeStandIn = pattern<{ label: string }, HomeStandInOutput>( ({ label }) => { const privateInbox = new Writable({}).for( "privateInbox", ); const retainedPrivateInboxes = new Writable([]) .for("retainedPrivateInboxes"); const privateInboxRefusal = new Writable({}) .for("privateInboxRefusal"); const privateInboxReplacement = new Writable< PrivateInboxReplacementHolder >({}).for("privateInboxReplacement"); const profiles = new Writable([]).for("profiles"); const defaultProfile = new Writable({}).for( "defaultProfileSlot", ); const requested = new Writable>({}).for( "privateInboxRequests", ); const ensure = ensurePrivateInbox({ privateInbox, retainedPrivateInboxes, privateInboxRefusal, // deno-lint-ignore no-explicit-any profiles: profiles as any, pointProfiles: pointProfilesAtPrivateInbox({ privateInbox, // deno-lint-ignore no-explicit-any profiles: profiles as any, }), }); return { [NAME]: label, privateInbox, retainedPrivateInboxes, privateInboxRefusal, privateInboxReplacement, profiles, defaultProfile, setDefaultProfile: setDefaultProfile({ profiles, defaultProfile }), ensurePrivateInbox: ensure, requestPrivateInbox: requestPrivateInbox({ // deno-lint-ignore no-explicit-any profiles: profiles as any, requested, answers: PrivateInboxAnswering({ privateInbox, // deno-lint-ignore no-explicit-any profiles: profiles as any, requested, }).answers, ensure, }), replaceRefusedPrivateInbox: replaceRefusedPrivateInbox({ privateInbox, privateInboxRefusal, privateInboxReplacement, repointProfiles: repointProfilesFromReplacedInbox({ privateInbox, privateInboxReplacement, // deno-lint-ignore no-explicit-any profiles: profiles as any, }), }), createProfile: createProfile({ profiles }), createEarlierProfile: createEarlierProfile({ profiles }), }; }, ); /** * The event a Home of the vintage before the refusal record takes: an inbox to * adopt and the deciding profile, and nothing about a refusal. */ export type OlderEnsureEvent = { /** The inbox to adopt. */ adopt?: Cell; /** The deciding profile. */ from?: Cell; }; /** * Records each event an older Home's ensure is delivered, and the fields * delivered with it. */ const ensureAsOlderHome = handler< OlderEnsureEvent, { handled: Writable; delivered: Writable } >((event, { handled, delivered }) => { handled.set(handled.get() + 1); delivered.set(Object.keys(event ?? {}).sort()); }); /** What the host reads of an older Home, and what a test reads back. */ export interface OlderHomeStandInOutput { [NAME]: string; privateInbox: PrivateInboxHolder; profiles: ProfileHomeOutput[]; /** How many events its ensure has handled. */ handled: number; /** The fields of the event its ensure last handled, sorted. */ delivered: string[]; /** Takes the event as a Home of that vintage typed it. */ ensurePrivateInbox: Stream; /** Creates one of the Home's profiles. */ createProfile: Stream; } /** * Stands in for a Home of the vintage whose ensure takes no refusal: its event * type names `adopt` and `from` alone, so the event's schema is what such a * Home's is. */ const OlderHomeStandIn = pattern, OlderHomeStandInOutput>( () => { const privateInbox = new Writable({}).for( "privateInbox", ); const profiles = new Writable([]).for("profiles"); const handled = new Writable(0).for("handled"); const delivered = new Writable([]).for("delivered"); return { [NAME]: "Older Home", privateInbox, profiles, handled, delivered, ensurePrivateInbox: ensureAsOlderHome({ handled, delivered }), createProfile: createProfile({ profiles }), }; }, ); /** * Sends an offer to the inbox the owner's first profile points at, from the * event's actor's own handler. */ const offer = handler< OfferRequest, { profiles: Writable } >((event, { profiles }) => { const inbox = inboxOf( profiles.key(0).resolveAsCell().key("inbox").key("piece").resolveAsCell(), ); inbox.key("receive").send(envelopeOf(event)); }); /** * Queues `send` with the request, so the offer leaves from a handler that * another handler's run emitted, as an offer leaves a room's creation. */ const queueOffer = handler }>( (event, { send }) => { send.send({ id: event.id, space: event.space, title: event.title }); }, ); /** * Sends an offer to the inbox the owner's first profile points at, reading * the pointer through the profile's own types, as a typed link. */ const sendToPointedInbox = handler< OfferRequest, { profiles: Writable } >((event, { profiles }) => { const pointer = profiles.key(0).resolveAsCell().key("inbox").get()?.piece; if (pointer === undefined) return; inboxOf(pointer.resolveAsCell()).key("receive").send(envelopeOf(event)); }); /** Copies the offers in the owner's private inbox into this piece. */ const copyOffers = handler< void, { privateInbox: Writable; copiedOffers: Writable; } >((_event, { privateInbox, copiedOffers }) => { const offers = inboxOf(privateInbox.key("piece").resolveAsCell()).key( "offers", ).get() as Offer[] | undefined; copiedOffers.set( (offers ?? []).map((item) => ({ title: `${item.title}`, from: `${item.from}`, })), ); }); export interface MainInput { privateInbox: Writable>>; profiles: Writable>; otherInbox: Writable>>; copiedOffers: Writable>; } export interface MainOutput { [NAME]: string; [UI]: VNode; privateInbox: PrivateInboxHolder; profiles: ProfileHomeOutput[]; otherInbox: PrivateInboxHolder; loomInbox: PrivateInboxHolder; strangerInbox: PrivateInboxHolder; readoptLoomInbox: PrivateInboxHolder; cureInbox: PrivateInboxHolder; unreadableInbox: PrivateInboxHolder; adoptingHome: HomeStandInOutput; refusingHome: HomeStandInOutput; curedHome: HomeStandInOutput; creatingHome: HomeStandInOutput; readoptingHome: HomeStandInOutput; replacingHome: HomeStandInOutput; racingHome: HomeStandInOutput; ownSpaceHome: HomeStandInOutput; unreadableRefusedHome: HomeStandInOutput; olderHome: OlderHomeStandInOutput; copiedOffers: CopiedOffer[]; retainedPrivateInboxes: RetainedPrivateInboxes; privateInboxRefusal: PrivateInboxRefusalHolder; /** * Gives the stand-in Home the private inbox its profiles advertise, or one of * its own, and points profiles at it. */ ensurePrivateInbox: Stream; /** Creates one of the owner's profiles. */ createProfile: Stream; /** Creates a profile of an earlier vintage. */ createEarlierProfile: Stream; /** Creates an inbox other than the private inbox. */ createOtherInbox: Stream; /** Points one of the owner's profiles at the other inbox. */ pointProfileElsewhere: Stream; /** * Creates an inbox shaped as a loom daemon's, in a space of its own that * grants every principal `WRITE`, kept in `loomInbox`. */ createLoomInbox: Stream; /** * Creates an inbox as `createLoomInbox` does, kept in `strangerInbox`; sent * by another principal, the space is theirs. */ createStrangerInbox: Stream; /** Creates one of `adoptingHome`'s profiles. */ createAdoptingProfile: Stream; /** Creates a profile of an earlier vintage in `adoptingHome`. */ createAdoptingEarlierProfile: Stream; /** Points one of `adoptingHome`'s profiles at the loom-shaped inbox. */ pointAdoptingProfileAtLoom: Stream; /** Points one of `adoptingHome`'s profiles at the other inbox. */ pointAdoptingProfileAtOther: Stream; /** Creates one of `refusingHome`'s profiles. */ createRefusingProfile: Stream; /** Points one of `refusingHome`'s profiles at the stranger's inbox. */ pointRefusingProfileAtStranger: Stream; /** Creates one of `replacingHome`'s profiles. */ createReplacingProfile: Stream; /** Points one of `replacingHome`'s profiles at the stranger's inbox. */ pointReplacingProfileAtStranger: Stream; /** Replaces the inbox `replacingHome` was refused. */ replaceReplacingInbox: Stream; /** Creates one of `racingHome`'s profiles. */ createRacingProfile: Stream; /** * Points one of `racingHome`'s profiles at the loom-shaped inbox, only while * it points at none. */ pointRacingProfileAtLoomIfUnset: Stream; /** * Points one of `racingHome`'s profiles at the other inbox, only while it * points at none. */ pointRacingProfileAtOtherIfUnset: Stream; /** Creates one of `ownSpaceHome`'s profiles. */ createOwnSpaceProfile: Stream; /** Points one of `ownSpaceHome`'s profiles at the private inbox. */ pointOwnSpaceProfileAtPrivateInbox: Stream; /** Records in `ownSpaceHome` a refusal of the private inbox. */ refuseOwnSpaceInbox: Stream; /** Replaces the inbox `ownSpaceHome` was refused. */ replaceOwnSpaceInbox: Stream; /** * Creates an inbox in a space of its own that grants the event's `reader` * `READ`, kept in `unreadableInbox`; the sender owns the space. */ createUnreadableInbox: Stream; /** Revokes the event's `reader`'s access to `unreadableInbox`'s space. */ revokeUnreadableInbox: Stream; /** Creates one of `unreadableRefusedHome`'s profiles. */ createUnreadableRefusedProfile: Stream; /** Points one of `unreadableRefusedHome`'s profiles at `unreadableInbox`. */ pointUnreadableRefusedProfile: Stream; /** Replaces the inbox `unreadableRefusedHome` was refused. */ replaceUnreadableRefusedInbox: Stream; /** Creates an inbox as `createLoomInbox` does, kept in `cureInbox`. */ createCureInbox: Stream; /** Creates one of `curedHome`'s profiles. */ createCuredProfile: Stream; /** Points one of `curedHome`'s profiles at the stranger's inbox. */ pointCuredProfileAtStranger: Stream; /** Points one of `curedHome`'s profiles at the inbox in `cureInbox`. */ pointCuredProfileAtCure: Stream; /** Creates one of `creatingHome`'s profiles. */ createCreatingProfile: Stream; /** Points one of `creatingHome`'s profiles at the stranger's inbox. */ pointCreatingProfileAtStranger: Stream; /** Empties `creatingHome`'s profile list. */ dropCreatingProfiles: Stream; /** Creates one of `olderHome`'s profiles. */ createOlderProfile: Stream; /** Points one of `olderHome`'s profiles at the stranger's inbox. */ pointOlderProfileAtStranger: Stream; /** * Creates an inbox as `createLoomInbox` does, kept in `readoptLoomInbox`. */ createReadoptLoomInbox: Stream; /** Creates one of `readoptingHome`'s profiles. */ createReadoptingProfile: Stream; /** * Points one of `readoptingHome`'s profiles at the inbox in * `readoptLoomInbox`, through the profile's own `setInbox`, whatever it * pointed at before, as a loom daemon points it. */ pointReadoptingProfileAtLoom: Stream; /** Sends an offer through `readoptingHome`'s first profile. */ offerToReadopting: Stream; /** Makes one of `readoptingHome`'s profiles its default. */ setReadoptingDefault: Stream; /** Sends an offer through the owner's first profile. */ offer: Stream; /** * Sends an offer to the inbox the owner's first profile points at, from a * handler this stream's handler queues. */ queuedOffer: Stream; /** Copies the private inbox's offers into this piece. */ copyOffers: Stream; /** * Creates one of the owner's profiles the way the profile-create surface * does, handing it the private inbox. */ createProfileThroughSurface: Stream<{ name?: string }>; /** A Home whose profile keeps its pointer per user. */ unreadableHome: HomeStandInOutput; /** Creates a profile keeping its pointer per user in `unreadableHome`. */ createUnreadableProfile: Stream; /** Points a profile of `unreadableHome` at the loom-shaped inbox. */ pointUnreadableProfileAtLoom: Stream; /** Ensures `unreadableHome`'s inbox, with the event the host sends. */ ensureUnreadable: Stream; /** A Home whose inbox a client requests, as a loom daemon does. */ requestingHome: HomeStandInOutput; /** Creates one of `requestingHome`'s profiles. */ createRequestingProfile: Stream; /** Creates a profile of `requestingHome`'s without `setInbox`. */ createRequestingPointerOnlyProfile: Stream; /** Points one of `requestingHome`'s profiles at the loom-shaped inbox. */ pointRequestingProfileAtLoom: Stream; /** A Home with no profiles, whose inbox a client requests. */ profilelessHome: HomeStandInOutput; /** A Home whose first profile leaves its list once its inbox is requested. */ leavingHome: HomeStandInOutput; /** Creates one of `leavingHome`'s profiles. */ createLeavingProfile: Stream; /** Points one of `leavingHome`'s profiles at the loom-shaped inbox. */ pointLeavingProfileAtLoom: Stream; /** Takes `leavingHome`'s first profile out of its list. */ dropLeavingFirstProfile: Stream; } export default pattern(( { privateInbox, profiles, otherInbox, copiedOffers }, ) => { const loomInbox = new Writable({}).for("loomInbox"); const strangerInbox = new Writable({}).for( "strangerInbox", ); const readoptLoomInbox = new Writable({}).for( "readoptLoomInbox", ); const cureInbox = new Writable({}).for("cureInbox"); const unreadableInbox = new Writable({}).for( "unreadableInbox", ); const retainedPrivateInboxes = new Writable([]).for( "retainedPrivateInboxes", ); const privateInboxRefusal = new Writable({}).for( "privateInboxRefusal", ); const adoptingHome = HomeStandIn({ label: "Adopting Home" }); const refusingHome = HomeStandIn({ label: "Refusing Home" }); const curedHome = HomeStandIn({ label: "Cured Home" }); const creatingHome = HomeStandIn({ label: "Creating Home" }); const olderHome = OlderHomeStandIn({}); const readoptingHome = HomeStandIn({ label: "Home adopting again" }); const replacingHome = HomeStandIn({ label: "Replacing Home" }); const racingHome = HomeStandIn({ label: "Home pointed twice at once" }); const ownSpaceHome = HomeStandIn({ label: "Home refused its own inbox" }); const unreadableRefusedHome = HomeStandIn({ label: "Home refused an inbox it cannot read", }); const unreadableHome = HomeStandIn({ label: "Home of an unreadable profile", }); const requestingHome = HomeStandIn({ label: "Requested Home" }); const profilelessHome = HomeStandIn({ label: "Home with no profiles" }); const leavingHome = HomeStandIn({ label: "Home losing a profile" }); return { [NAME]: "Private inbox fixture", [UI]:
private inbox fixture
, privateInbox, profiles, otherInbox, loomInbox, strangerInbox, readoptLoomInbox, cureInbox, unreadableInbox, adoptingHome, refusingHome, curedHome, creatingHome, readoptingHome, replacingHome, racingHome, ownSpaceHome, unreadableRefusedHome, olderHome, requestingHome, profilelessHome, leavingHome, copiedOffers, retainedPrivateInboxes, privateInboxRefusal, ensurePrivateInbox: ensurePrivateInbox({ privateInbox, retainedPrivateInboxes, privateInboxRefusal, // deno-lint-ignore no-explicit-any profiles: profiles as any, pointProfiles: pointProfilesAtPrivateInbox({ privateInbox, // deno-lint-ignore no-explicit-any profiles: profiles as any, }), }), createProfile: createProfile({ profiles }), createEarlierProfile: createEarlierProfile({ profiles }), createOtherInbox: createOtherInbox({ otherInbox }), pointProfileElsewhere: pointProfileAt({ profiles, inbox: otherInbox }), createLoomInbox: createSharedInbox({ inbox: loomInbox }), createStrangerInbox: createSharedInbox({ inbox: strangerInbox }), createAdoptingProfile: adoptingHome.createProfile, createAdoptingEarlierProfile: adoptingHome.createEarlierProfile, pointAdoptingProfileAtLoom: pointProfileAt({ profiles: adoptingHome.profiles, inbox: loomInbox, }), pointAdoptingProfileAtOther: pointProfileAt({ profiles: adoptingHome.profiles, inbox: otherInbox, }), createRefusingProfile: refusingHome.createProfile, pointRefusingProfileAtStranger: pointProfileAt({ profiles: refusingHome.profiles, inbox: strangerInbox, }), createReplacingProfile: replacingHome.createProfile, pointReplacingProfileAtStranger: pointProfileAt({ profiles: replacingHome.profiles, inbox: strangerInbox, }), replaceReplacingInbox: replacingHome.replaceRefusedPrivateInbox, createRacingProfile: racingHome.createProfile, pointRacingProfileAtLoomIfUnset: pointProfileAtIfUnset({ profiles: racingHome.profiles, inbox: loomInbox, }), pointRacingProfileAtOtherIfUnset: pointProfileAtIfUnset({ profiles: racingHome.profiles, inbox: otherInbox, }), createOwnSpaceProfile: ownSpaceHome.createProfile, pointOwnSpaceProfileAtPrivateInbox: pointProfileAt({ profiles: ownSpaceHome.profiles, inbox: privateInbox, }), refuseOwnSpaceInbox: recordRefusalOf({ inbox: privateInbox, refusal: ownSpaceHome.privateInboxRefusal, }), replaceOwnSpaceInbox: ownSpaceHome.replaceRefusedPrivateInbox, createUnreadableInbox: createReadableByInbox({ inbox: unreadableInbox }), revokeUnreadableInbox: revokeReader({ inbox: unreadableInbox }), createUnreadableRefusedProfile: unreadableRefusedHome.createProfile, pointUnreadableRefusedProfile: pointProfileAt({ profiles: unreadableRefusedHome.profiles, inbox: unreadableInbox, }), replaceUnreadableRefusedInbox: unreadableRefusedHome.replaceRefusedPrivateInbox, createCureInbox: createSharedInbox({ inbox: cureInbox }), createCuredProfile: curedHome.createProfile, pointCuredProfileAtStranger: pointProfileAt({ profiles: curedHome.profiles, inbox: strangerInbox, }), pointCuredProfileAtCure: pointProfileAt({ profiles: curedHome.profiles, inbox: cureInbox, }), createCreatingProfile: creatingHome.createProfile, pointCreatingProfileAtStranger: pointProfileAt({ profiles: creatingHome.profiles, inbox: strangerInbox, }), dropCreatingProfiles: dropProfiles({ profiles: creatingHome.profiles }), createOlderProfile: olderHome.createProfile, pointOlderProfileAtStranger: pointProfileAt({ profiles: olderHome.profiles, inbox: strangerInbox, }), createReadoptLoomInbox: createSharedInbox({ inbox: readoptLoomInbox }), createReadoptingProfile: readoptingHome.createProfile, pointReadoptingProfileAtLoom: pointProfileAt({ profiles: readoptingHome.profiles, inbox: readoptLoomInbox, }), offerToReadopting: offer({ profiles: readoptingHome.profiles }), setReadoptingDefault: readoptingHome.setDefaultProfile, offer: offer({ profiles }), queuedOffer: queueOffer({ send: sendToPointedInbox({ profiles }) }), copyOffers: copyOffers({ privateInbox, copiedOffers }), unreadableHome, createUnreadableProfile: createUserScopedProfile({ profiles: unreadableHome.profiles, }), pointUnreadableProfileAtLoom: pointProfileAt({ profiles: unreadableHome.profiles, inbox: loomInbox, }), ensureUnreadable: unreadableHome.ensurePrivateInbox, createRequestingProfile: requestingHome.createProfile, createLeavingProfile: leavingHome.createProfile, pointLeavingProfileAtLoom: pointProfileAt({ profiles: leavingHome.profiles, inbox: loomInbox, }), dropLeavingFirstProfile: dropFirstProfile({ profiles: leavingHome.profiles, }), createRequestingPointerOnlyProfile: createPointerOnlyProfile({ profiles: requestingHome.profiles, }), pointRequestingProfileAtLoom: pointProfileAt({ profiles: requestingHome.profiles, inbox: loomInbox, }), createProfileThroughSurface: ProfileCreate({ // deno-lint-ignore no-explicit-any profiles: profiles as any, // deno-lint-ignore no-explicit-any privateInbox: privateInbox as any, }).createProfile, }; });