/** * 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 { UnionSubject } from "@ng-eventually/polyfill"; /** * One entry, as THIS APPLICATION decodes one out of the index document. * * It is declared here and not imported, because `@ng-helpers/indexing` publishes no * such type and no call that produces one: an index is an ordinary document, so its * contents are whatever `readUnion` hands back, read with the two published IRIs. * A subject carrying several values shows up as several rows — the document's own * truth, and the application's business to make something of. */ export interface IndexRow { readonly object: string; readonly value: string; } /** What the leak probe observed — see `run.ts`'s last journey. */ export interface BrokenInboxOutcome { /** The message `create` rejected with, or `null` if it did not reject. */ readonly rejected: string | null; /** What `create` 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[]; } /** * What one anchored SPARQL SELECT answered — or how it failed. * * The three fields are kept apart deliberately. "Nothing came back" and "the call failed" * are different answers, and a shape that folded them together would let a failure read as * an empty index — the defect class this repository keeps finding. `raw` carries the answer * BEFORE anything here decodes it, so a decoder that is wrong about the result's shape * cannot pass its own blindness off as a query that returned nothing. */ export interface SelectOutcome { /** The message the query rejected with, or `null` when it returned. */ readonly failed: string | null; /** Whatever came back, rendered as JSON — the answer before any decoding of it. */ readonly raw: string; /** The SELECT's bindings, decoded to plain `variable → value` rows. */ readonly rows: ReadonlyArray>>; } /** * 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; /** Publish a public document carrying one value for one predicate. */ publishObject(predicate: string, value: string): Promise; /** Hand the CONFIGURED index a reference to an object. Anyone may. */ addToConfigured(object: string): Promise; /** Hand a NAMED index a reference — used where no identity boundary is crossed. */ addTo(index: string, object: string): Promise; /** * Obtain a fresh `Indexing` handle, which is what a page load does. * * It reaches NOTHING — a handle is a session id and two acts, and building one talks * to nobody. That is precisely what one journey asserts: taking a handle again changes * nothing an index holds. It is NOT a settle point and cannot be used as one; what a * journey waits on after a deposit is the INDEX, read like any other document (`run.ts`, * `settled`). */ rebuildHandle(): Promise; /** * The index's entries, ordered by value — decoded BY THIS APPLICATION, out of an * ordinary `readUnion` of the index document, with nothing from the library but the * two IRIs it publishes. That the suite can do this at all is the claim under test. */ read(index: string): Promise; /** What a document literally holds, straight off `readUnion` — the write-form probe. */ readRaw(doc: string): Promise; /** * Run a SPARQL SELECT anchored on a document, through `docs.sparqlQuery`. * * An index is claimed to be an ORDINARY document, which means an ordinary query must * reach it. Nothing in `src/` ever issues one — this layer composes SPARQL only to * write — so this is the one act here that no code of this package performs, and it is * on the bridge because the claim had never been measured against a broker. */ select(anchor: string, query: string): Promise; /** This identity's public documents. How an owner discovers a document it did not keep. */ listPublicDocs(): Promise; /** * `create` 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; } declare global { interface Window { __indexing: IndexingBridge; } }