@mdbase-dev/connect 0.1.0-beta.26 → 0.1.0-beta.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,8 +22,7 @@ const mdbase = new MdbaseConnect({
22
22
  manifest: new URL(".well-known/mdbase-app.json", location.href).href,
23
23
  redirectUri: "https://workouts.example/auth/mdbase/callback"
24
24
  });
25
- const session = mdbase.createSession({
26
- operations: ["describe", "changes", "read", "query", "update"],
25
+ const session = mdbase.createApplicationSession({
27
26
  selection: new MdbaseBrowserSelection()
28
27
  });
29
28
 
@@ -33,14 +32,7 @@ if (!started.ok) {
33
32
  return;
34
33
  }
35
34
  if (session.getSnapshot().status === "unselected") {
36
- const authorized = await session.authorize("choose", {
37
- onFirstContact: ({ authenticationString }) => {
38
- showPersistentSecurityPrompt({
39
- title: "Compare with mdbase connect",
40
- code: authenticationString
41
- });
42
- }
43
- });
35
+ const authorized = await session.authorize("choose");
44
36
  if (!authorized.ok) {
45
37
  renderProblem(authorized.problem);
46
38
  return;
@@ -49,7 +41,8 @@ if (session.getSnapshot().status === "unselected") {
49
41
 
50
42
  const snapshot = session.getSnapshot();
51
43
  if (snapshot.status !== "ready") throw new Error("Choose an authorized collection.");
52
- const connection = snapshot.connection;
44
+ const connection = session.connection();
45
+ if (!connection) throw new Error("The ready session has no active connection.");
53
46
  const queried = await connection.query({ types: ["workout"] });
54
47
  if (!queried.ok) {
55
48
  renderProblem(queried.problem);
@@ -78,12 +71,32 @@ reserved for programming errors and broken SDK invariants. See
78
71
  problem model, setup failures, mutation uncertainty, and UI guidance.
79
72
 
80
73
  `MdbaseConnect` is the application-level authorization registry.
81
- `MdbaseSession` is the normal application boundary: it owns active collection
82
- selection, authorization completion, access capabilities, and one
83
- reactive snapshot. Use `getSnapshot()` and `subscribe()` directly or through
84
- your framework's external-store integration. A snapshot is `unselected`,
85
- `ready`, or `unavailable`; an unavailable bookmark includes the explicit
86
- collection ID and reason instead of collapsing every recovery state to `null`.
74
+ `MdbaseApplicationSession` is the normal application boundary: it owns active
75
+ collection selection, authorization completion, semantic capabilities,
76
+ definition compatibility, and one reactive snapshot. Applications declare
77
+ versioned capabilities in their manifest; they never maintain a parallel array
78
+ of protocol operations. Use `getSnapshot()` and `subscribe()` directly or
79
+ through your framework's external-store integration.
80
+
81
+ The session distinguishes `authorization_required`, `checking_definitions`,
82
+ `definition_review_required`, `ready`, `unavailable`, and `blocked`. Definition
83
+ inspection is read-only. If an update is needed, render the supplied plan and
84
+ apply the exact assessment the user reviewed:
85
+
86
+ ```ts
87
+ const snapshot = session.getSnapshot();
88
+ if (snapshot.status === "definition_review_required") {
89
+ renderDefinitionChanges(snapshot.updates);
90
+ const applied = await session.applyDefinitionUpdates();
91
+ if (!applied.ok) renderProblem(applied.problem);
92
+ }
93
+ ```
94
+
95
+ A `ready` snapshot may be `cached` for immediate startup and is then reverified
96
+ in the background. Route details remain diagnostics; feature UI should read
97
+ `snapshot.capabilities`, whose values explain whether a capability is available,
98
+ needs authorization/setup, is temporarily unavailable, or is unsupported by the
99
+ selected authority.
87
100
 
88
101
  `MdbaseBrowserSelection` keeps the stable collection ID in
89
102
  `?collection=<id>`, preserves unrelated path/query/hash and router state, and
@@ -111,15 +124,14 @@ Collection IDs are opaque non-secret locators that may appear in browser
111
124
  history and logs. Grants remain the authorization boundary, and names are
112
125
  display text that may change.
113
126
 
114
- When the chosen collection is owned by a computer that has not seen this
115
- application installation before, `onFirstContact` is required. The SDK derives
116
- the eight-character value locally from the application's non-extractable
117
- installation key and the connector key; it never accepts a value supplied by
118
- the control plane. Keep the value visible while the user compares and accepts
119
- the exact same value in mdbase connect. Headless operators use
120
- `mdbase connect trust list`, `trust show <id>`, and
121
- `trust accept <id> --code XXXX-XXXX`. Hosted-only authorization does not invoke
122
- this callback.
127
+ The SDK keeps one non-extractable P-256 installation signing identity per
128
+ server/application and signs every authorization ceiling with it. Grant
129
+ agreement and signing keys remain disposable and are replaced on
130
+ reauthorization. For local collections, the SDK also pins the connector public
131
+ key after the first successful authorization and rejects silent replacement as
132
+ `connector_identity_changed`, even after the grant is forgotten. Only call
133
+ `forgetConnectorIdentity(connectorId)` after independently verifying an
134
+ intentional connector replacement.
123
135
 
124
136
  Bundled v1 application manifests can declare runtime notification criteria.
125
137
  Register a service worker from a user gesture to receive standards-based Web
@@ -254,17 +266,31 @@ Request `read_type`, `create_type`, and `update_type` during authorization.
254
266
  Contract-scoped applications cannot manage collection-wide type definitions.
255
267
 
256
268
  To install a complete catalog pack without exposing its individual collection
257
- paths, request `install_type_pack`, fetch and verify the published provision,
258
- then pass it to the atomic collection operation:
269
+ paths, request `assess_type_pack` and `apply_type_pack`, fetch and verify the
270
+ published provision, then review and apply the authority's exact plan:
259
271
 
260
272
  ```ts
261
273
  const response = await fetch(pack.provisionUrl);
262
274
  const provision = await response.json();
263
- await connection.installTypePack(provision);
275
+ const installedBy = "dev.example.catalog";
276
+ const assessment = await connection.assessTypePack({
277
+ provision,
278
+ installed_by: installedBy
279
+ });
280
+ if (!assessment.ok) return renderProblem(assessment.problem);
281
+
282
+ renderDefinitionChanges(assessment.value);
283
+ const applied = await connection.applyTypePack({
284
+ provision,
285
+ installed_by: installedBy,
286
+ expected_assessment_digest: assessment.value.assessment_digest
287
+ });
288
+ if (!applied.ok) return renderProblem(applied.problem);
264
289
  ```
265
290
 
266
291
  The caller remains responsible for verifying the catalog digest before sending
267
- the provision. Existing targets with different content are rejected.
292
+ the provision. Apply rechecks the reviewed assessment inside the transaction;
293
+ stale plans and locally modified targets fail without partial writes.
268
294
 
269
295
  For a local collection, ask for same-computer access from a user gesture:
270
296
 
@@ -333,6 +359,25 @@ implements:
333
359
  ---
334
360
  `;
335
361
 
362
+ const workItemPack = defineTypePack({
363
+ id: "example.work-items",
364
+ version: "1.0.0",
365
+ resources: [
366
+ {
367
+ kind: "contract",
368
+ mode: "managed",
369
+ source: "_contracts/example.work-item.md",
370
+ document: contract
371
+ },
372
+ {
373
+ kind: "type",
374
+ mode: "seed",
375
+ source: "_types/work-item.md",
376
+ document: type
377
+ }
378
+ ]
379
+ });
380
+
336
381
  export const manifest = {
337
382
  manifest_version: 1,
338
383
  id: "dev.mdbase.worklog",
@@ -340,18 +385,10 @@ export const manifest = {
340
385
  homepage: "https://worklog.example",
341
386
  redirect_uris: ["https://worklog.example/auth/mdbase/callback"],
342
387
  requirements: {
343
- contracts: [{ id: "example.work-item", version: "1.0.0" }]
388
+ contracts: workItemPack.provides
344
389
  },
345
390
  provisions: {
346
- type_packs: [defineTypePack({
347
- id: "example.work-items",
348
- version: "1.0.0",
349
- provides: [{ id: "example.work-item", version: "1.0.0" }],
350
- resources: [
351
- { kind: "contract", source: "_contracts/example.work-item.md", document: contract },
352
- { kind: "type", source: "_types/work-item.md", document: type }
353
- ]
354
- })]
391
+ type_packs: [workItemPack]
355
392
  }
356
393
  };
357
394
  ```
@@ -398,10 +435,11 @@ allows a host to choose another persistence boundary.
398
435
  Native shells can pass `navigate` to open the approval URL in the system
399
436
  browser and list a reverse-domain callback such as
400
437
  `dev.mdbase.worklog://auth/mdbase/callback` in the bundled declaration. Its
401
- scheme must match the declaration ID. The application remains alive, polls the
402
- PKCE-bound status endpoint, displays first contact when required, and receives
403
- the completed connection directly from `authorize()`; the browser does not
404
- carry credentials back through a deep link.
438
+ scheme must match the declaration ID. `authorize()` returns `redirecting`; the
439
+ browser redirects to the declared callback with a short-lived code and state,
440
+ and the shell passes that URL to `completeAuthorization()`. PKCE prevents the
441
+ callback code from being exchanged without the pending application state and
442
+ verifier.
405
443
 
406
444
  New authorizations require encrypted relay protocol 1 by default. The SDK keeps
407
445
  independent non-extractable P-256 ECDH agreement and ECDSA signing keys plus an
@@ -1,5 +1,34 @@
1
1
  import { authorizationSigningMessage, type ApplicationAuthorizationBinding, type ApplicationAuthorizationProof } from "@mdbase-dev/connect-protocol";
2
- import type { GrantKeyRecord } from "./crypto.js";
2
+ import type { Application } from "./internal-types.js";
3
+ export interface ApplicationIdentity {
4
+ handle: string;
5
+ signingPrivateKey: CryptoKey;
6
+ signingPublicKey: string;
7
+ }
8
+ export interface ApplicationIdentityStore {
9
+ create(handle: string): Promise<ApplicationIdentity>;
10
+ get(handle: string): Promise<ApplicationIdentity | null>;
11
+ delete(handle: string): Promise<void>;
12
+ }
13
+ /** Origin-scoped persistence for one non-extractable signing key per app/server installation. */
14
+ export declare class IndexedDbApplicationIdentityStore implements ApplicationIdentityStore {
15
+ private database;
16
+ create(handle: string): Promise<ApplicationIdentity>;
17
+ get(handle: string): Promise<ApplicationIdentity | null>;
18
+ delete(handle: string): Promise<void>;
19
+ private open;
20
+ }
21
+ /** Process-local identity storage for portable applications, tests, and custom hosts. */
22
+ export declare class MemoryApplicationIdentityStore implements ApplicationIdentityStore {
23
+ private readonly records;
24
+ create(handle: string): Promise<ApplicationIdentity>;
25
+ get(handle: string): Promise<ApplicationIdentity | null>;
26
+ delete(handle: string): Promise<void>;
27
+ }
28
+ export declare class ApplicationIdentityStoreError extends Error {
29
+ constructor(message: string);
30
+ }
3
31
  export { authorizationSigningMessage };
4
- export declare function applicationInstallationId(identity: Pick<GrantKeyRecord, "agreementPublicKey" | "signingPublicKey">): Promise<string>;
5
- export declare function signApplicationAuthorization(binding: ApplicationAuthorizationBinding, identity: Pick<GrantKeyRecord, "signingPrivateKey" | "agreementPublicKey" | "signingPublicKey">): Promise<ApplicationAuthorizationProof>;
32
+ export declare function applicationInstallationId(identity: Pick<ApplicationIdentity, "signingPublicKey">): Promise<string>;
33
+ export declare function signApplicationAuthorization(binding: ApplicationAuthorizationBinding, identity: Pick<ApplicationIdentity, "signingPrivateKey" | "signingPublicKey">): Promise<ApplicationAuthorizationProof>;
34
+ export declare function applicationIdentity(store: ApplicationIdentityStore, serverUrl: string, application: Application): Promise<ApplicationIdentity>;
@@ -1,21 +1,115 @@
1
- import { applicationInstallationIdFromPublicKeys, authorizationSigningMessage } from "@mdbase-dev/connect-protocol";
1
+ import { applicationInstallationIdFromPublicKey, authorizationSigningMessage } from "@mdbase-dev/connect-protocol";
2
+ const DATABASE_NAME = "mdbase-connect-identities";
3
+ const STORE_NAME = "application-identities";
2
4
  const P256_ORDER = BigInt("0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
3
5
  const P256_HALF_ORDER = P256_ORDER / 2n;
6
+ /** Origin-scoped persistence for one non-extractable signing key per app/server installation. */
7
+ export class IndexedDbApplicationIdentityStore {
8
+ database = null;
9
+ async create(handle) {
10
+ const record = await generateApplicationIdentity(handle);
11
+ const database = await this.open();
12
+ await idbWrite(database, (store) => store.add(record));
13
+ return record;
14
+ }
15
+ async get(handle) {
16
+ const database = await this.open();
17
+ return await idbRequest(database.transaction(STORE_NAME).objectStore(STORE_NAME).get(handle)) ?? null;
18
+ }
19
+ async delete(handle) {
20
+ const database = await this.open();
21
+ await idbWrite(database, (store) => store.delete(handle));
22
+ }
23
+ open() {
24
+ if (typeof indexedDB === "undefined") {
25
+ throw new ApplicationIdentityStoreError("Persistent application identity requires browser IndexedDB or an injected identity store.");
26
+ }
27
+ if (!this.database) {
28
+ this.database = new Promise((resolve, reject) => {
29
+ const request = indexedDB.open(DATABASE_NAME, 1);
30
+ request.onupgradeneeded = () => {
31
+ if (!request.result.objectStoreNames.contains(STORE_NAME)) {
32
+ request.result.createObjectStore(STORE_NAME, { keyPath: "handle" });
33
+ }
34
+ };
35
+ request.onerror = () => reject(request.error);
36
+ request.onsuccess = () => resolve(request.result);
37
+ });
38
+ }
39
+ return this.database;
40
+ }
41
+ }
42
+ /** Process-local identity storage for portable applications, tests, and custom hosts. */
43
+ export class MemoryApplicationIdentityStore {
44
+ records = new Map();
45
+ async create(handle) {
46
+ if (this.records.has(handle))
47
+ throw new Error(`Application identity already exists: ${handle}`);
48
+ const record = await generateApplicationIdentity(handle);
49
+ this.records.set(handle, record);
50
+ return record;
51
+ }
52
+ async get(handle) {
53
+ return this.records.get(handle) ?? null;
54
+ }
55
+ async delete(handle) {
56
+ this.records.delete(handle);
57
+ }
58
+ }
59
+ export class ApplicationIdentityStoreError extends Error {
60
+ constructor(message) {
61
+ super(message);
62
+ this.name = "ApplicationIdentityStoreError";
63
+ }
64
+ }
4
65
  export { authorizationSigningMessage };
5
66
  export async function applicationInstallationId(identity) {
6
- return applicationInstallationIdFromPublicKeys(identity.agreementPublicKey, identity.signingPublicKey);
67
+ return applicationInstallationIdFromPublicKey(identity.signingPublicKey);
7
68
  }
8
69
  export async function signApplicationAuthorization(binding, identity) {
9
- if (binding.installation_agreement_public_key !== identity.agreementPublicKey
10
- || binding.installation_signing_public_key !== identity.signingPublicKey
70
+ if (binding.installation_signing_public_key !== identity.signingPublicKey
11
71
  || binding.application_installation_id !== await applicationInstallationId(identity)) {
12
72
  throw new Error("Application authorization identity does not match its binding.");
13
73
  }
14
74
  const signature = canonicalSignature(new Uint8Array(await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, identity.signingPrivateKey, authorizationSigningMessage(binding))));
15
- return {
16
- binding,
17
- signature: base64Url(signature)
18
- };
75
+ return { binding, signature: base64Url(signature) };
76
+ }
77
+ export async function applicationIdentity(store, serverUrl, application) {
78
+ const handle = `application-installation:v2:${serverUrl}:${application.id}`;
79
+ const existing = await store.get(handle);
80
+ if (existing)
81
+ return existing;
82
+ try {
83
+ return await store.create(handle);
84
+ }
85
+ catch (error) {
86
+ const raced = await store.get(handle);
87
+ if (raced)
88
+ return raced;
89
+ throw error;
90
+ }
91
+ }
92
+ async function generateApplicationIdentity(handle) {
93
+ const signing = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"]);
94
+ const signingPublicKey = base64Url(new Uint8Array(await crypto.subtle.exportKey("raw", signing.publicKey)));
95
+ const signingPkcs8 = await crypto.subtle.exportKey("pkcs8", signing.privateKey);
96
+ const signingPrivateKey = await crypto.subtle.importKey("pkcs8", signingPkcs8, { name: "ECDSA", namedCurve: "P-256" }, false, ["sign"]);
97
+ return { handle, signingPrivateKey, signingPublicKey };
98
+ }
99
+ function idbRequest(request) {
100
+ return new Promise((resolve, reject) => {
101
+ request.onerror = () => reject(request.error);
102
+ request.onsuccess = () => resolve(request.result);
103
+ });
104
+ }
105
+ function idbWrite(database, write) {
106
+ return new Promise((resolve, reject) => {
107
+ const transaction = database.transaction(STORE_NAME, "readwrite");
108
+ write(transaction.objectStore(STORE_NAME)).onerror = () => reject(transaction.error);
109
+ transaction.onerror = () => reject(transaction.error);
110
+ transaction.onabort = () => reject(transaction.error ?? new Error("Identity transaction aborted."));
111
+ transaction.oncomplete = () => resolve();
112
+ });
19
113
  }
20
114
  function concat(values) {
21
115
  const output = new Uint8Array(values.reduce((length, value) => length + value.byteLength, 0));
@@ -33,13 +127,11 @@ function base64Url(value) {
33
127
  .replace(/=+$/u, "");
34
128
  }
35
129
  function canonicalSignature(signature) {
36
- if (signature.byteLength !== 64) {
130
+ if (signature.byteLength !== 64)
37
131
  throw new Error("Application authorization signature is invalid.");
38
- }
39
132
  const s = bytesBigInt(signature.slice(32));
40
- if (s === 0n || s >= P256_ORDER) {
133
+ if (s === 0n || s >= P256_ORDER)
41
134
  throw new Error("Application authorization signature is invalid.");
42
- }
43
135
  if (s <= P256_HALF_ORDER)
44
136
  return signature;
45
137
  return concat([signature.slice(0, 32), bigIntBytes(P256_ORDER - s, 32)]);
@@ -0,0 +1,120 @@
1
+ import { type ApplicationCapabilityId, type JsonObject, type MdbaseAppManifest, type TypePackAssessment } from "@mdbase-dev/connect-protocol";
2
+ import { type MdbaseEffectiveCapabilities } from "./capabilities.js";
3
+ import type { MdbaseAuthorizationOutcome, MdbaseAuthorizeOptions, MdbaseConnection } from "./connection.js";
4
+ import type { MdbaseConnectionInfo } from "./connection-types.js";
5
+ import { type ConnectOutcome, type CollectionTypeProblemCode, type AuthorizationProblemCode, type RegistrationProblemCode, type SessionProblemCode } from "./outcomes.js";
6
+ import type { MdbaseApplicationSelection, MdbaseSelectionHistory } from "./selection.js";
7
+ import { type MdbaseSessionConnect, type MdbaseUnavailableReason } from "./session.js";
8
+ export interface MdbaseApplicationSessionConnect<Frontmatter extends JsonObject = JsonObject> extends MdbaseSessionConnect<Frontmatter> {
9
+ manifest(): Promise<ConnectOutcome<MdbaseAppManifest, RegistrationProblemCode>>;
10
+ }
11
+ export interface MdbaseApplicationSessionOptions {
12
+ selection: MdbaseApplicationSelection;
13
+ autoSelect?: "only" | "never";
14
+ verificationStore?: MdbaseApplicationVerificationStore;
15
+ }
16
+ export interface MdbaseApplicationVerificationStore {
17
+ read(key: string): string | null;
18
+ write(key: string, value: string): void;
19
+ remove(key: string): void;
20
+ }
21
+ export declare class MdbaseMemoryVerificationStore implements MdbaseApplicationVerificationStore {
22
+ private readonly values;
23
+ read(key: string): string | null;
24
+ write(key: string, value: string): void;
25
+ remove(key: string): void;
26
+ }
27
+ export interface MdbaseDefinitionUpdate {
28
+ id: string;
29
+ name: string;
30
+ status: TypePackAssessment["status"];
31
+ applicable: boolean;
32
+ assessmentDigest: string;
33
+ currentVersion?: string;
34
+ desiredVersion: string;
35
+ resources: TypePackAssessment["resources"];
36
+ contractSetups: TypePackAssessment["contract_setups"];
37
+ canApply: boolean;
38
+ reason: string;
39
+ }
40
+ interface ApplicationSessionContext {
41
+ collectionId: string;
42
+ info: MdbaseConnectionInfo;
43
+ capabilities: MdbaseEffectiveCapabilities;
44
+ connections: MdbaseConnectionInfo[];
45
+ }
46
+ export type MdbaseApplicationSessionSnapshot = {
47
+ status: "opening";
48
+ connections: MdbaseConnectionInfo[];
49
+ } | {
50
+ status: "unselected";
51
+ connections: MdbaseConnectionInfo[];
52
+ } | ({
53
+ status: "authorization_required";
54
+ } & ApplicationSessionContext) | ({
55
+ status: "checking_definitions";
56
+ } & ApplicationSessionContext) | ({
57
+ status: "definition_review_required";
58
+ updates: MdbaseDefinitionUpdate[];
59
+ } & ApplicationSessionContext) | ({
60
+ status: "ready";
61
+ verification: "cached" | "verified";
62
+ } & ApplicationSessionContext) | {
63
+ status: "unavailable";
64
+ collectionId: string;
65
+ reason: MdbaseUnavailableReason;
66
+ connections: MdbaseConnectionInfo[];
67
+ } | ({
68
+ status: "blocked";
69
+ problem: {
70
+ code: string;
71
+ message: string;
72
+ recovery?: string;
73
+ };
74
+ } & ApplicationSessionContext);
75
+ /**
76
+ * The application-level lifecycle boundary. It derives authorization from the
77
+ * bundled manifest, exposes semantic capabilities, and never mutates collection
78
+ * definitions without an explicit `applyDefinitionUpdates` call.
79
+ */
80
+ export declare class MdbaseApplicationSession<Frontmatter extends JsonObject = JsonObject> {
81
+ private readonly connect;
82
+ private readonly options;
83
+ private readonly listeners;
84
+ private readonly verificationStore;
85
+ private snapshot;
86
+ private manifest;
87
+ private base;
88
+ private stopBase?;
89
+ private reviewEntries;
90
+ private verificationGeneration;
91
+ constructor(connect: MdbaseApplicationSessionConnect<Frontmatter>, options: MdbaseApplicationSessionOptions);
92
+ start(): Promise<ConnectOutcome<MdbaseApplicationSessionSnapshot, SessionProblemCode>>;
93
+ destroy(): void;
94
+ getSnapshot(): MdbaseApplicationSessionSnapshot;
95
+ subscribe(listener: () => void): () => void;
96
+ connection(): MdbaseConnection<Frontmatter> | null;
97
+ select(collectionId: string, options?: {
98
+ history?: MdbaseSelectionHistory;
99
+ }): ConnectOutcome<MdbaseConnection<Frontmatter>, "unknown_collection">;
100
+ clearSelection(options?: {
101
+ history?: MdbaseSelectionHistory;
102
+ }): void;
103
+ forget(collectionId: string): void;
104
+ authorize(target: "choose" | "selected" | {
105
+ collectionId: string;
106
+ }, options?: Omit<MdbaseAuthorizeOptions, "operations" | "returnTo" | "target">): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, SessionProblemCode>>;
107
+ handleAuthorizationCallback(callbackUrl: string): Promise<ConnectOutcome<MdbaseConnection<Frontmatter>, AuthorizationProblemCode>>;
108
+ ensureCapabilities(capabilities: ApplicationCapabilityId[]): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter> | {
109
+ kind: "unchanged";
110
+ connection: MdbaseConnection<Frontmatter>;
111
+ }, SessionProblemCode>>;
112
+ applyDefinitionUpdates(): Promise<ConnectOutcome<MdbaseApplicationSessionSnapshot, CollectionTypeProblemCode | "collection_not_ready">>;
113
+ private refresh;
114
+ private verifyDefinitions;
115
+ private context;
116
+ private publish;
117
+ private requireBase;
118
+ private requireManifest;
119
+ }
120
+ export {};