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.
- package/README.md +57 -0
- package/dist/{chunk-SKPP4T6S.js → chunk-HJUDYIPR.js} +852 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +23 -510
- package/dist/testing/index.d.ts +38 -2
- package/dist/testing/index.js +295 -6
- package/dist/{types-DkzIJKBw.d.ts → types-D0Bsbd1G.d.ts} +196 -2
- package/package.json +3 -3
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import {
|
|
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 };
|
package/dist/testing/index.js
CHANGED
|
@@ -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-
|
|
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
|
-
|
|
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
|
|
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 ===
|
|
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) => {
|