Files
ng-helpers/e2e/bridge.ts
T

92 lines
4.2 KiB
TypeScript

/**
* The contract between the application page and the suite that drives it.
*
* It is declared ONCE and imported by both sides — `indexing-app.ts` implements it,
* `run.ts` calls it — so a method that changes shape breaks the typecheck instead of
* failing at run time inside a browser, where the only symptom would be `undefined is
* not a function` three minutes into a broker crossing.
*
* Everything crossing `frame.evaluate` must be structured-cloneable, which is why every
* member below takes and returns plain strings, numbers and object literals. A `Nuri` is
* a template-literal string type upstream (`did:ng:${string}`), so it crosses as itself;
* it is declared `string` here because a value that has been through structured clone
* carries no proof of its shape, and pretending otherwise is how an unvalidated string
* ends up typed as a reference.
*/
import type { IndexEntry, UnionSubject } from "../src/index";
/** What the leak probe observed — see `run.ts`'s last journey. */
export interface BrokenInboxOutcome {
/** The message `createIndex` rejected with, or `null` if it did not reject. */
readonly rejected: string | null;
/** What `createIndex` returned, on the impossible branch where it did not reject. */
readonly returned: string | null;
/** The documents that appeared in this identity's public store despite the failure. */
readonly appeared: readonly string[];
}
/**
* The acts this application can perform — and ONLY acts an application can perform.
*
* There is no back door onto the library's internals here. The one method that is not
* something an application does (`createIndexWithBrokenInbox`) injects a failure and is
* named for it, because the alternative — leaving the question unanswered — is worse
* than a probe that says what it is.
*/
export interface IndexingBridge {
/** `connecting` → `ready`, or `failed`. */
status(): string;
/** Why the boot failed, or `null`. */
error(): string | null;
/** Who this page signed in as. */
whoami(): string;
/**
* The index this deployment was BUILT to contribute to, read off its own configuration.
*
* An index is an ordinary document; what makes it an index is that an application
* references its NURI in its own source (`src/indexing.ts`). This page is configured
* through its URL rather than through a compiled-in constant, which is the same thing
* one build step earlier — and it is how the reference reaches a SECOND identity
* without the suite handing it over through a variable no application would have.
*/
configuredIndex(): string | null;
/** Create an index in this identity's public store, indexing by `field`. */
createIndex(field: string): Promise<string>;
/** Publish a public document carrying one value for one predicate. */
publishObject(predicate: string, value: string): Promise<string>;
/** Hand the CONFIGURED index a reference to an object. Anyone may. */
referConfigured(object: string): Promise<void>;
/** Hand a NAMED index a reference — used where no identity boundary is crossed. */
referTo(index: string, object: string): Promise<void>;
/**
* Connect again — obtain a fresh `Indexing` handle, which is what a page load does.
*
* There is no curating act to drive: an index is curated at its creator's next
* connection and on each deposit while the creator is connected. This is the first
* of the two, driven deliberately so a journey has a point at which the catching
* up is over; the second needs nothing from anyone.
*/
reconnect(): Promise<void>;
/** The index's entries, ordered by value. */
read(index: string): Promise<IndexEntry[]>;
/** What a document literally holds, straight off `readUnion` — the write-form probe. */
readRaw(doc: string): Promise<UnionSubject[]>;
/** This identity's public documents. How an owner discovers a document it did not keep. */
listPublicDocs(): Promise<string[]>;
/**
* `createIndex` with its inbox step made to fail — everything else real, against the
* real broker. Answers whether a half-created index is left behind.
*/
createIndexWithBrokenInbox(field: string): Promise<BrokenInboxOutcome>;
}
declare global {
interface Window {
__indexing: IndexingBridge;
}
}