mindoodb-app-sdk 0.0.59 → 0.0.60

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.
@@ -1,7 +1,24 @@
1
- import { aK as MindooDBAppCreateViewNavigatorInput, cX as MindooDBAppViewNavigator, aa as MindooDBAppBridgeRpcRequest, bj as MindooDBAppHostTheme, as as MindooDBAppCapability, j as MindooDBAppDefinition, I as MindooDBAppAttachmentApi, e as MindooDBAppBridge, cx as MindooDBAppSession, bZ as MindooDBAppProposeAppInput, d3 as MindooDBAppViewport, cR as MindooDBAppUiPreferences, c3 as MindooDBAppQueryResult, d2 as MindooDBAppViewUpdateStats, a6 as MindooDBAppBridgePortMessage, aL as MindooDBAppDatabaseInfo, a1 as MindooDBAppBridgeErrorPayload, bE as MindooDBAppLaunchContext, aU as MindooDBAppDocumentApi, cZ as MindooDBAppViewNavigatorOpenOptions, bk as MindooDBAppIdentityApi, cN as MindooDBAppTimestampApi, aS as MindooDBAppDirectoryApi, l as MindooDBAppDocument, bg as MindooDBAppFulltextSetup, bf as MindooDBAppExtractionSetup, cF as MindooDBAppSummarySetup, b_ as MindooDBAppProposeAppResult, bu as MindooDBAppIncomingSource, c as MindooDBAppDragStartResult, b9 as MindooDBAppDragProfile, bt as MindooDBAppIncomingResult } from '../types-DkzIJKBw.js';
1
+ import { ax as MindooDBAppComponentInfo, bo as MindooDBAppEmbedRect, aT as MindooDBAppCreateViewNavigatorInput, dc as MindooDBAppViewNavigator, ac as MindooDBAppBridgeRpcRequest, bA as MindooDBAppHostTheme, au as MindooDBAppCapability, j as MindooDBAppDefinition, J as MindooDBAppAttachmentApi, e as MindooDBAppBridge, cO as MindooDBAppSession, ce as MindooDBAppProposeAppInput, dk as MindooDBAppViewport, d6 as MindooDBAppUiPreferences, ck as MindooDBAppQueryResult, dj as MindooDBAppViewUpdateStats, a8 as MindooDBAppBridgePortMessage, aU as MindooDBAppDatabaseInfo, bk as MindooDBAppEmbedCloseReason, a3 as MindooDBAppBridgeErrorPayload, bV as MindooDBAppLaunchContext, b1 as MindooDBAppDocumentApi, de as MindooDBAppViewNavigatorOpenOptions, bB as MindooDBAppIdentityApi, d2 as MindooDBAppTimestampApi, a$ as MindooDBAppDirectoryApi, l as MindooDBAppDocument, bx as MindooDBAppFulltextSetup, bw as MindooDBAppExtractionSetup, cW as MindooDBAppSummarySetup, cf as MindooDBAppProposeAppResult, bL as MindooDBAppIncomingSource, c as MindooDBAppDragStartResult, bi as MindooDBAppDragProfile, bK as MindooDBAppIncomingResult } from '../types-D0Bsbd1G.js';
2
2
  import * as mindoodb from 'mindoodb';
3
3
  import 'mindoodb-view-language';
4
4
 
5
+ /** An embed the mock host currently shows, as tests and the test host page see it. */
6
+ interface MockEmbedState {
7
+ embedId: string;
8
+ component: MindooDBAppComponentInfo;
9
+ databaseId: string;
10
+ docId: string;
11
+ intent: "edit" | "view";
12
+ rect: MindooDBAppEmbedRect;
13
+ visible: boolean;
14
+ }
15
+ /** How an app running as an embedded component finished (`session.embedding`). */
16
+ interface MockEmbeddingFinish {
17
+ reason: "completed" | "cancelled";
18
+ result?: unknown;
19
+ message?: string;
20
+ }
21
+
5
22
  type EvaluatingViewDocument = {
6
23
  origin: string;
7
24
  docId: string;
@@ -321,6 +338,10 @@ interface CreateMockMindooDBAppSessionOptions {
321
338
  * `methods.directory` still wins.
322
339
  */
323
340
  directoryUsers?: readonly string[];
341
+ /** What `session.components.list` offers; see `closeEmbed` on the controller. */
342
+ components?: MindooDBAppComponentInfo[];
343
+ /** Called whenever the app opens, moves or closes an embed. */
344
+ onEmbedChange?: (embeds: readonly MockEmbedState[]) => void;
324
345
  }
325
346
  /**
326
347
  * Test usernames in Haven's canonical form: `CN=Test User 001/O=Test`, …
@@ -366,7 +387,16 @@ interface MockMindooDBAppSessionController {
366
387
  * and resolves with the handler's result.
367
388
  */
368
389
  emitIncomingContent(input: MockIncomingContentInput): Promise<MindooDBAppIncomingResult>;
390
+ /** Embeds the app has open (`session.embeds.open`). */
391
+ listEmbeds(): MockEmbedState[];
392
+ /** Closes an embed as Haven does when the component finishes or the user closes it. */
393
+ closeEmbed(embedId: string, reason?: MindooDBAppEmbedCloseReason, result?: unknown): void;
394
+ /** Replaces what `session.components.list` offers. */
395
+ setComponents(components: MindooDBAppComponentInfo[]): void;
396
+ /** For an app under test that runs as a component: its `session.embedding` call. */
397
+ getEmbeddingFinish(): MockEmbeddingFinish | null;
369
398
  }
399
+
370
400
  /** Content for `emitIncomingContent`. */
371
401
  interface MockIncomingContentInput {
372
402
  acceptId?: string;
@@ -456,7 +486,13 @@ interface FakeBridgeHostController {
456
486
  /** See {@link CreateMockMindooDBAppSessionOptions.directoryUsers}. */
457
487
  setDirectoryUsers(users: readonly string[]): void;
458
488
  getDirectoryUsers(): string[];
489
+ /** Embeds the app has open (`session.embeds.open`). */
490
+ listEmbeds(): MockEmbedState[];
491
+ /** Closes an embed and pushes the `embed-event` to the app. */
492
+ closeEmbed(embedId: string, reason?: MindooDBAppEmbedCloseReason, result?: unknown): void;
493
+ /** For an app under test that runs as a component: its `session.embedding` call. */
494
+ getEmbeddingFinish(): MockEmbeddingFinish | null;
459
495
  }
460
496
  declare function createFakeBridgeHost(options?: CreateFakeBridgeHostOptions): FakeBridgeHostController;
461
497
 
462
- export { ALL_CAPABILITIES, type BrowserTestHost, type BrowserTestHostLog, type BrowserTestHostScan, type BrowserTestHostScanMode, type CreateBrowserTestHostOptions, type CreateFakeBridgeHostOptions, type CreateMockMindooDBAppSessionOptions, type EvaluatingViewDocument, type FakeBridgeHostController, type FakeBridgePortMessageHandler, type FakeBridgeRequestHandler, type FakeBridgeRpcResponse, type MockDatabaseOverride, type MockDatabasesFromDefinitionOptions, MockForbiddenError, type MockIncomingContentInput, type MockMindooDBAppDatabaseDefinition, type MockMindooDBAppSessionController, type MockSealedChannelOptions, type MockSeedDocument, type MountHavenTestHostOptions, TEST_HOST_LOCALES, type TestHostUrlSettings, capabilitiesForDefinitionPermissions, createBrowserTestHost, createEvaluatingViewNavigator, createFakeBridgeHost, createMemoryAttachments, createMockMindooDBAppBridge, createMockMindooDBAppSession, generateDirectoryUsers, loadMindoodbForTesting, mockDatabasesFromDefinition, mountHavenTestHost, previewJson, readTestHostUrlSettings };
498
+ export { ALL_CAPABILITIES, type BrowserTestHost, type BrowserTestHostLog, type BrowserTestHostScan, type BrowserTestHostScanMode, type CreateBrowserTestHostOptions, type CreateFakeBridgeHostOptions, type CreateMockMindooDBAppSessionOptions, type EvaluatingViewDocument, type FakeBridgeHostController, type FakeBridgePortMessageHandler, type FakeBridgeRequestHandler, type FakeBridgeRpcResponse, type MockDatabaseOverride, type MockDatabasesFromDefinitionOptions, type MockEmbedState, type MockEmbeddingFinish, MockForbiddenError, type MockIncomingContentInput, type MockMindooDBAppDatabaseDefinition, type MockMindooDBAppSessionController, type MockSealedChannelOptions, type MockSeedDocument, type MountHavenTestHostOptions, TEST_HOST_LOCALES, type TestHostUrlSettings, capabilitiesForDefinitionPermissions, createBrowserTestHost, createEvaluatingViewNavigator, createFakeBridgeHost, createMemoryAttachments, createMockMindooDBAppBridge, createMockMindooDBAppSession, generateDirectoryUsers, loadMindoodbForTesting, mockDatabasesFromDefinition, mountHavenTestHost, previewJson, readTestHostUrlSettings };
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  MINDOODB_APP_VALUE_TAG,
3
3
  assertValidMindooDBCreateIds,
4
+ mindooDBAppComponentFieldsMatch,
4
5
  pageUsers,
5
6
  releaseMindooDBAppBridgeSessions
6
- } from "../chunk-SKPP4T6S.js";
7
+ } from "../chunk-HJUDYIPR.js";
7
8
 
8
9
  // src/testing/index.ts
9
10
  import * as Automerge from "@automerge/automerge";
@@ -456,6 +457,172 @@ async function createEvaluatingViewNavigator(input, documents) {
456
457
  return wrapNavigator(input.definition, navigator);
457
458
  }
458
459
 
460
+ // src/testing/mockEmbeds.ts
461
+ function createMockEmbedHost(options, getDatabase) {
462
+ let components = [...options.components ?? []];
463
+ const embeds = /* @__PURE__ */ new Map();
464
+ const handles = /* @__PURE__ */ new Map();
465
+ const closedListeners = /* @__PURE__ */ new Set();
466
+ let embedCounter = 0;
467
+ let embeddingFinish = null;
468
+ function notifyChange() {
469
+ options.onEmbedChange?.([...embeds.values()].map((entry) => ({ ...entry, rect: { ...entry.rect } })));
470
+ }
471
+ async function openEmbed(input) {
472
+ const component = components.find((entry) => entry.key === input.componentKey);
473
+ if (!component) {
474
+ throw new Error(`Unknown component "${input.componentKey}".`);
475
+ }
476
+ const intent = input.intent ?? "edit";
477
+ if (!component.intents.includes(intent) && !(intent === "edit" && component.intents.includes("create"))) {
478
+ throw new Error(`Component "${component.label}" does not support "${intent}".`);
479
+ }
480
+ const document2 = await getDatabase(input.databaseId).documents.get(input.docId);
481
+ if (!document2) {
482
+ throw new Error(`Document ${input.docId} does not exist.`);
483
+ }
484
+ if (!mindooDBAppComponentFieldsMatch(component.match, document2.data)) {
485
+ throw new Error(`Document ${input.docId} is not a "${component.label}" document.`);
486
+ }
487
+ embedCounter += 1;
488
+ const embedId = `mock-embed-${embedCounter}`;
489
+ embeds.set(embedId, {
490
+ embedId,
491
+ component,
492
+ databaseId: input.databaseId,
493
+ docId: input.docId,
494
+ intent,
495
+ rect: { ...input.rect },
496
+ visible: input.visible !== false
497
+ });
498
+ notifyChange();
499
+ return embedId;
500
+ }
501
+ function closeEmbed(embedId, reason = "closed", result) {
502
+ if (!embeds.delete(embedId)) {
503
+ return;
504
+ }
505
+ const event = {
506
+ embedId,
507
+ reason,
508
+ ...result === void 0 ? {} : { result: JSON.parse(JSON.stringify(result)) }
509
+ };
510
+ handles.get(embedId)?.settle(event);
511
+ handles.delete(embedId);
512
+ closedListeners.forEach((listener) => listener(event));
513
+ notifyChange();
514
+ }
515
+ class MockEmbed {
516
+ constructor(embedId, componentKey, databaseId, docId) {
517
+ this.embedId = embedId;
518
+ this.componentKey = componentKey;
519
+ this.databaseId = databaseId;
520
+ this.docId = docId;
521
+ this.closed = new Promise((resolve) => {
522
+ this.resolve = resolve;
523
+ });
524
+ }
525
+ embedId;
526
+ componentKey;
527
+ databaseId;
528
+ docId;
529
+ closed;
530
+ resolve;
531
+ listeners = /* @__PURE__ */ new Set();
532
+ settled = null;
533
+ async setRect(rect) {
534
+ setRect(this.embedId, rect);
535
+ }
536
+ async setVisible(visible) {
537
+ setVisible(this.embedId, visible);
538
+ }
539
+ async close() {
540
+ closeEmbed(this.embedId, "closed");
541
+ return await this.closed;
542
+ }
543
+ onClosed(listener) {
544
+ if (this.settled) {
545
+ const event = this.settled;
546
+ queueMicrotask(() => listener(event));
547
+ return () => {
548
+ };
549
+ }
550
+ this.listeners.add(listener);
551
+ return () => {
552
+ this.listeners.delete(listener);
553
+ };
554
+ }
555
+ settle(event) {
556
+ this.settled = event;
557
+ this.resolve(event);
558
+ this.listeners.forEach((listener) => listener(event));
559
+ this.listeners.clear();
560
+ }
561
+ }
562
+ function setRect(embedId, rect) {
563
+ const entry = embeds.get(embedId);
564
+ if (entry) {
565
+ entry.rect = { ...rect };
566
+ notifyChange();
567
+ }
568
+ }
569
+ function setVisible(embedId, visible) {
570
+ const entry = embeds.get(embedId);
571
+ if (entry) {
572
+ entry.visible = visible;
573
+ notifyChange();
574
+ }
575
+ }
576
+ return {
577
+ components: {
578
+ async list(query) {
579
+ return components.filter((entry) => !query?.intent || entry.intents.includes(query.intent)).filter((entry) => !query?.document || mindooDBAppComponentFieldsMatch(entry.match, query.document)).map((entry) => structuredClone(entry));
580
+ }
581
+ },
582
+ embeds: {
583
+ async open(input) {
584
+ const embedId = await openEmbed(input);
585
+ const handle = new MockEmbed(embedId, input.componentKey, input.databaseId, input.docId);
586
+ handles.set(embedId, handle);
587
+ return handle;
588
+ }
589
+ },
590
+ embedding: {
591
+ async complete(result) {
592
+ embeddingFinish = {
593
+ reason: "completed",
594
+ ...result === void 0 ? {} : { result: JSON.parse(JSON.stringify(result)) }
595
+ };
596
+ },
597
+ async cancel(message) {
598
+ embeddingFinish = { reason: "cancelled", ...message ? { message } : {} };
599
+ }
600
+ },
601
+ openEmbed,
602
+ setRect,
603
+ setVisible,
604
+ closeEmbed,
605
+ listEmbeds() {
606
+ return [...embeds.values()].map((entry) => ({ ...entry, rect: { ...entry.rect } }));
607
+ },
608
+ setComponents(next) {
609
+ components = [...next];
610
+ },
611
+ getEmbeddingFinish() {
612
+ return embeddingFinish;
613
+ },
614
+ finishEmbedding(finish) {
615
+ embeddingFinish = finish;
616
+ },
617
+ onClosed(listener) {
618
+ closedListeners.add(listener);
619
+ return () => {
620
+ closedListeners.delete(listener);
621
+ };
622
+ }
623
+ };
624
+ }
625
+
459
626
  // src/testing/capabilityGuard.ts
460
627
  var NONE = [];
461
628
  var READ = ["read"];
@@ -921,6 +1088,10 @@ var STYLE = `
921
1088
  .htest{display:grid;grid-template-columns:minmax(0,1fr) 320px;height:100vh;margin:0;font:13px/1.45 system-ui,sans-serif;background:#eef1f7;color:#172033}
922
1089
  .htest *{box-sizing:border-box}
923
1090
  .htest__frame{width:100%;height:100%;border:0;background:#fff}
1091
+ .htest__stage{position:relative;min-width:0;height:100%;overflow:hidden}
1092
+ .htest__embed{position:absolute;display:flex;flex-direction:column;gap:8px;align-items:center;justify-content:center;border:2px dashed #6366f1;background:rgba(238,242,255,.94);color:#312e81;text-align:center;padding:12px;overflow:hidden}
1093
+ .htest__embed[hidden]{display:none}
1094
+ .htest__embed strong{font-size:14px}
924
1095
  .htest__panel{border-left:1px solid #d7dce8;overflow:auto;padding:14px;background:#f8f9fc}
925
1096
  .htest__badge{display:inline-block;padding:2px 8px;border-radius:999px;background:#fde68a;color:#713f12;font-weight:600;font-size:11px;letter-spacing:.04em}
926
1097
  .htest h1{font-size:15px;margin:8px 0 12px}
@@ -1006,8 +1177,36 @@ function mountHavenTestHost(options) {
1006
1177
  frame.dataset.testid = "haven-test-app-frame";
1007
1178
  const panel = document.createElement("aside");
1008
1179
  panel.className = "htest__panel";
1009
- root.append(frame, panel);
1180
+ const stage = document.createElement("div");
1181
+ stage.className = "htest__stage";
1182
+ const embedLayer = document.createElement("div");
1183
+ stage.append(frame, embedLayer);
1184
+ root.append(stage, panel);
1010
1185
  container.replaceChildren(root);
1186
+ function renderEmbeds(embeds) {
1187
+ embedLayer.replaceChildren(
1188
+ ...embeds.map((embed) => {
1189
+ const box = document.createElement("div");
1190
+ box.className = "htest__embed";
1191
+ box.dataset.testid = `haven-test-embed-${embed.embedId}`;
1192
+ box.hidden = !embed.visible;
1193
+ box.style.left = `${embed.rect.left}px`;
1194
+ box.style.top = `${embed.rect.top}px`;
1195
+ box.style.width = `${embed.rect.width}px`;
1196
+ box.style.height = `${embed.rect.height}px`;
1197
+ const name = document.createElement("strong");
1198
+ name.textContent = `${embed.component.appLabel}: ${embed.component.label}`;
1199
+ const row = document.createElement("div");
1200
+ row.className = "htest__row";
1201
+ row.append(
1202
+ button("Done", () => testHost.host.closeEmbed(embed.embedId, "completed", { saved: true })),
1203
+ button("Cancel", () => testHost.host.closeEmbed(embed.embedId, "cancelled"))
1204
+ );
1205
+ box.append(name, hint(`${embed.intent} \xB7 ${embed.databaseId}/${embed.docId}`), row);
1206
+ return box;
1207
+ })
1208
+ );
1209
+ }
1011
1210
  if (container === document.body) {
1012
1211
  document.body.style.margin = "0";
1013
1212
  }
@@ -1149,7 +1348,11 @@ function mountHavenTestHost(options) {
1149
1348
  enforceCapabilities: url.enforceCapabilities ?? hostOptions.enforceCapabilities,
1150
1349
  directoryUsers: url.directoryUserCount !== void 0 ? generateDirectoryUsers(url.directoryUserCount) : hostOptions.directoryUsers,
1151
1350
  frame,
1152
- onChange: render
1351
+ onChange: render,
1352
+ onEmbedChange(embeds) {
1353
+ hostOptions.onEmbedChange?.(embeds);
1354
+ renderEmbeds(embeds);
1355
+ }
1153
1356
  });
1154
1357
  let currentLocale = url.locale;
1155
1358
  const badge = document.createElement("span");
@@ -2008,6 +2211,23 @@ function extractMockSummaryFields(data, setup) {
2008
2211
  });
2009
2212
  }
2010
2213
  }
2214
+ if ((setup?.includeRecipients ?? true) && !isExcluded("_encryptFor")) {
2215
+ const encryptFor = data._encryptFor;
2216
+ if (encryptFor && typeof encryptFor === "object" && !Array.isArray(encryptFor)) {
2217
+ const projected = {};
2218
+ for (const [id, entry] of Object.entries(encryptFor)) {
2219
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
2220
+ const raw = entry;
2221
+ const info = { kind: raw.kind === "device" ? "device" : "user" };
2222
+ if (typeof raw.label === "string") info.label = raw.label;
2223
+ for (const key of ["addedAt", "removedAt"]) {
2224
+ if (typeof raw[key] === "number" && Number.isFinite(raw[key])) info[key] = raw[key];
2225
+ }
2226
+ projected[id] = info;
2227
+ }
2228
+ if (Object.keys(projected).length > 0) fields._encryptFor = projected;
2229
+ }
2230
+ }
2011
2231
  return fields;
2012
2232
  }
2013
2233
  function mockSummaryDocument(data, setup) {
@@ -3289,6 +3509,13 @@ function createDatabaseHandle(definition, peers, directoryUsers = () => []) {
3289
3509
  }
3290
3510
  function createMockSessionState(options = {}) {
3291
3511
  let launchContext = createDefaultLaunchContext(options.launchContext);
3512
+ const embedHost = createMockEmbedHost(options, (databaseId) => {
3513
+ const database = databaseHandles.get(databaseId);
3514
+ if (!database) {
3515
+ throw new Error(`Unknown test database: ${databaseId}`);
3516
+ }
3517
+ return database;
3518
+ });
3292
3519
  const themeListeners = /* @__PURE__ */ new Set();
3293
3520
  let incomingHandler = null;
3294
3521
  const pendingIncoming = [];
@@ -3561,6 +3788,9 @@ function createMockSessionState(options = {}) {
3561
3788
  },
3562
3789
  menus,
3563
3790
  drag,
3791
+ components: embedHost.components,
3792
+ embeds: embedHost.embeds,
3793
+ embedding: embedHost.embedding,
3564
3794
  storage: {
3565
3795
  async snapshot(snapshotOptions) {
3566
3796
  const prefixes = snapshotOptions?.prefixes;
@@ -3683,6 +3913,7 @@ function createMockSessionState(options = {}) {
3683
3913
  directoryUsers = [...users];
3684
3914
  },
3685
3915
  getDirectoryUsers: () => [...directoryUsers],
3916
+ embedHost,
3686
3917
  getDatabase(databaseId) {
3687
3918
  const database = databaseHandles.get(databaseId);
3688
3919
  if (!database) {
@@ -3816,12 +4047,17 @@ function createMockMindooDBAppSession(options = {}) {
3816
4047
  },
3817
4048
  resolveDrag: state.resolveDrag,
3818
4049
  getDragProfile: state.getDragProfile,
3819
- emitIncomingContent: state.emitIncomingContent
4050
+ emitIncomingContent: state.emitIncomingContent,
4051
+ listEmbeds: () => state.embedHost.listEmbeds(),
4052
+ closeEmbed: (embedId, reason, result) => state.embedHost.closeEmbed(embedId, reason, result),
4053
+ setComponents: (components) => state.embedHost.setComponents(components),
4054
+ getEmbeddingFinish: () => state.embedHost.getEmbeddingFinish()
3820
4055
  };
3821
4056
  }
3822
4057
  function createMockMindooDBAppBridge(options = {}) {
3823
4058
  return createMockMindooDBAppSession(options);
3824
4059
  }
4060
+ var NOT_HANDLED = /* @__PURE__ */ Symbol("not-handled");
3825
4061
  function createFakeBridgeHost(options = {}) {
3826
4062
  const state = createMockSessionState(options);
3827
4063
  const customRequestHandlers = new Map(
@@ -3829,6 +4065,11 @@ function createFakeBridgeHost(options = {}) {
3829
4065
  );
3830
4066
  const requests = [];
3831
4067
  const connectedPorts = /* @__PURE__ */ new Set();
4068
+ state.embedHost.onClosed((event) => {
4069
+ connectedPorts.forEach(
4070
+ (port) => port.postMessage({ protocol: PROTOCOL, kind: "embed-event", event: { type: "closed", ...event } })
4071
+ );
4072
+ });
3832
4073
  const beforeCloseWaiters = /* @__PURE__ */ new Map();
3833
4074
  let beforeCloseCounter = 0;
3834
4075
  const viewSessions = /* @__PURE__ */ new Map();
@@ -4034,6 +4275,51 @@ function createFakeBridgeHost(options = {}) {
4034
4275
  case "menus.hide":
4035
4276
  await state.session.menus.hide();
4036
4277
  return { ok: true };
4278
+ case "appStorage.snapshot":
4279
+ return await state.session.storage.snapshot({
4280
+ prefixes: Array.isArray(params.prefixes) ? params.prefixes.map(String) : void 0
4281
+ });
4282
+ case "appStorage.get":
4283
+ return await state.session.storage.get(String(params.key));
4284
+ case "appStorage.set":
4285
+ await state.session.storage.set(String(params.key), String(params.value));
4286
+ return null;
4287
+ case "appStorage.remove":
4288
+ await state.session.storage.remove(String(params.key));
4289
+ return null;
4290
+ case "appStorage.keys":
4291
+ return await state.session.storage.keys({
4292
+ prefix: typeof params.prefix === "string" ? params.prefix : void 0
4293
+ });
4294
+ case "appStorage.clear":
4295
+ await state.session.storage.clear({
4296
+ prefix: typeof params.prefix === "string" ? params.prefix : void 0
4297
+ });
4298
+ return null;
4299
+ case "components.list":
4300
+ return {
4301
+ components: await state.session.components.list(
4302
+ params.query ?? void 0
4303
+ )
4304
+ };
4305
+ case "embeds.open":
4306
+ return { embedId: await state.embedHost.openEmbed(params.input) };
4307
+ case "embeds.setRect":
4308
+ state.embedHost.setRect(String(params.embedId), params.rect);
4309
+ return { ok: true };
4310
+ case "embeds.setVisible":
4311
+ state.embedHost.setVisible(String(params.embedId), params.visible === true);
4312
+ return { ok: true };
4313
+ case "embeds.close":
4314
+ state.embedHost.closeEmbed(String(params.embedId), "closed");
4315
+ return { ok: true };
4316
+ case "embedding.finish":
4317
+ state.embedHost.finishEmbedding({
4318
+ reason: params.reason === "cancelled" ? "cancelled" : "completed",
4319
+ ...params.result === void 0 ? {} : { result: params.result },
4320
+ ...typeof params.message === "string" ? { message: params.message } : {}
4321
+ });
4322
+ return { ok: true };
4037
4323
  case "session.requestHostFocus":
4038
4324
  await state.session.requestHostFocus();
4039
4325
  return null;
@@ -4459,7 +4745,7 @@ function createFakeBridgeHost(options = {}) {
4459
4745
  return void 0;
4460
4746
  }
4461
4747
  default:
4462
- return void 0;
4748
+ return NOT_HANDLED;
4463
4749
  }
4464
4750
  }
4465
4751
  async function handleStreamMessage(port, message) {
@@ -4581,7 +4867,7 @@ function createFakeBridgeHost(options = {}) {
4581
4867
  return;
4582
4868
  }
4583
4869
  const builtinResult = await handleBuiltinRequest(message);
4584
- if (builtinResult === void 0 && message.method !== "viewNavigators.dispose") {
4870
+ if (builtinResult === NOT_HANDLED) {
4585
4871
  fail({
4586
4872
  code: "method-not-found",
4587
4873
  message: `No fake bridge handler is configured for ${message.method}.`
@@ -4638,6 +4924,9 @@ function createFakeBridgeHost(options = {}) {
4638
4924
  getEnforceCapabilities: state.getEnforceCapabilities,
4639
4925
  setDirectoryUsers: state.setDirectoryUsers,
4640
4926
  getDirectoryUsers: state.getDirectoryUsers,
4927
+ listEmbeds: () => state.embedHost.listEmbeds(),
4928
+ closeEmbed: (embedId, reason, result) => state.embedHost.closeEmbed(embedId, reason, result),
4929
+ getEmbeddingFinish: () => state.embedHost.getEmbeddingFinish(),
4641
4930
  dispose() {
4642
4931
  restoreWindow();
4643
4932
  connectedPorts.forEach((port) => {