mindoodb-app-sdk 0.0.51 → 0.0.53
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 +34 -0
- package/TESTING.md +57 -0
- package/dist/{chunk-R76XXRJ6.js → chunk-6NTVTL6G.js} +1 -1
- package/dist/index.d.ts +74 -3
- package/dist/index.js +389 -17
- package/dist/testing/index.d.ts +97 -2
- package/dist/testing/index.js +412 -141
- package/dist/{types-BLyV6Ejy.d.ts → types-CsKw_niD.d.ts} +46 -1
- package/package.json +3 -3
package/dist/testing/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MINDOODB_APP_VALUE_TAG,
|
|
3
3
|
releaseMindooDBAppBridgeSessions
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-6NTVTL6G.js";
|
|
5
5
|
|
|
6
6
|
// src/testing/index.ts
|
|
7
7
|
import * as Automerge from "@automerge/automerge";
|
|
@@ -29,10 +29,10 @@ function toFormulaBoolean(value) {
|
|
|
29
29
|
}
|
|
30
30
|
return Boolean(value);
|
|
31
31
|
}
|
|
32
|
-
function matchesFilter(mindoodb, definition,
|
|
32
|
+
function matchesFilter(mindoodb, definition, document2) {
|
|
33
33
|
void mindoodb;
|
|
34
34
|
if (!definition.filter) return true;
|
|
35
|
-
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } =
|
|
35
|
+
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } = document2;
|
|
36
36
|
return toFormulaBoolean(
|
|
37
37
|
evaluateExpression(definition.filter.expression, {
|
|
38
38
|
doc,
|
|
@@ -47,8 +47,8 @@ function matchesFilter(mindoodb, definition, document) {
|
|
|
47
47
|
})
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
|
-
function computeColumnValues(definition,
|
|
51
|
-
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } =
|
|
50
|
+
function computeColumnValues(definition, document2) {
|
|
51
|
+
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } = document2;
|
|
52
52
|
const values = {};
|
|
53
53
|
for (const [key, value] of Object.entries(doc)) {
|
|
54
54
|
if (!key.startsWith("_")) values[key] = value;
|
|
@@ -172,13 +172,13 @@ async function buildVirtualView(mindoodb, definition, documents, categorizationS
|
|
|
172
172
|
}
|
|
173
173
|
const view = await builder.build();
|
|
174
174
|
const changes = /* @__PURE__ */ new Map();
|
|
175
|
-
for (const
|
|
176
|
-
if (!matchesFilter(mindoodb, definition,
|
|
175
|
+
for (const document2 of documents) {
|
|
176
|
+
if (!matchesFilter(mindoodb, definition, document2)) {
|
|
177
177
|
continue;
|
|
178
178
|
}
|
|
179
|
-
const change = changes.get(
|
|
180
|
-
change.addEntry(
|
|
181
|
-
changes.set(
|
|
179
|
+
const change = changes.get(document2.origin) ?? new mindoodb.VirtualViewDataChange(document2.origin);
|
|
180
|
+
change.addEntry(document2.docId, computeColumnValues(definition, document2));
|
|
181
|
+
changes.set(document2.origin, change);
|
|
182
182
|
}
|
|
183
183
|
for (const change of changes.values()) {
|
|
184
184
|
if (change.hasChanges()) view.applyChanges(change);
|
|
@@ -454,6 +454,249 @@ async function createEvaluatingViewNavigator(input, documents) {
|
|
|
454
454
|
return wrapNavigator(input.definition, navigator);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
+
// src/testing/browserTestHost.ts
|
|
458
|
+
function capabilitiesForDefinitionPermissions(permissions) {
|
|
459
|
+
const result = /* @__PURE__ */ new Set(["read"]);
|
|
460
|
+
for (const permission of permissions ?? []) {
|
|
461
|
+
if (permission === "write") {
|
|
462
|
+
result.add("create");
|
|
463
|
+
result.add("update");
|
|
464
|
+
} else if (permission === "delete" || permission === "history" || permission === "attachments" || permission === "views" || permission === "sign" || permission === "timestamps" || permission === "directory" || permission === "sealedchannel") {
|
|
465
|
+
result.add(permission);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return [...result];
|
|
469
|
+
}
|
|
470
|
+
function mockDatabasesFromDefinition(definition, seed = {}) {
|
|
471
|
+
return (definition.databases ?? []).map((database) => ({
|
|
472
|
+
info: {
|
|
473
|
+
id: database.logicalDatabaseId,
|
|
474
|
+
title: database.label ?? database.logicalDatabaseId,
|
|
475
|
+
capabilities: capabilitiesForDefinitionPermissions(database.permissions)
|
|
476
|
+
},
|
|
477
|
+
documents: seed[database.logicalDatabaseId]
|
|
478
|
+
}));
|
|
479
|
+
}
|
|
480
|
+
function withLaunchId(appUrl, launchId) {
|
|
481
|
+
const url = new URL(appUrl, window.location.href);
|
|
482
|
+
url.searchParams.set("mindoodbAppLaunchId", launchId);
|
|
483
|
+
return url.toString();
|
|
484
|
+
}
|
|
485
|
+
function createBrowserTestHost(options) {
|
|
486
|
+
const { frame, appUrl, onChange, ...hostOptions } = options;
|
|
487
|
+
let nextScan = null;
|
|
488
|
+
let scanCounter = 0;
|
|
489
|
+
const log = {
|
|
490
|
+
notifications: [],
|
|
491
|
+
previews: [],
|
|
492
|
+
scans: [],
|
|
493
|
+
focusRequests: 0,
|
|
494
|
+
requests: []
|
|
495
|
+
};
|
|
496
|
+
const host = createFakeBridgeHost({
|
|
497
|
+
...hostOptions,
|
|
498
|
+
onRequest(request) {
|
|
499
|
+
log.requests.push(request);
|
|
500
|
+
const params = request.params ?? {};
|
|
501
|
+
if (request.method === "notifications.show") {
|
|
502
|
+
log.notifications.push({
|
|
503
|
+
id: typeof params.id === "string" ? params.id : void 0,
|
|
504
|
+
severity: typeof params.severity === "string" ? params.severity : void 0,
|
|
505
|
+
text: typeof params.text === "string" ? params.text : void 0,
|
|
506
|
+
durationMs: typeof params.durationMs === "number" ? params.durationMs : void 0
|
|
507
|
+
});
|
|
508
|
+
} else if (request.method === "session.requestHostFocus") {
|
|
509
|
+
log.focusRequests += 1;
|
|
510
|
+
} else if (request.method === "attachments.openPreview" || request.method === "attachments.preparePreviewSession") {
|
|
511
|
+
log.previews.push({
|
|
512
|
+
databaseId: String(params.databaseId),
|
|
513
|
+
docId: String(params.docId),
|
|
514
|
+
attachmentName: String(params.attachmentName)
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
hostOptions.onRequest?.(request);
|
|
518
|
+
queueMicrotask(() => onChange?.());
|
|
519
|
+
},
|
|
520
|
+
requestHandlers: {
|
|
521
|
+
"attachments.scanAndWrite": (params) => {
|
|
522
|
+
const input = params ?? {};
|
|
523
|
+
const scan = nextScan;
|
|
524
|
+
nextScan = null;
|
|
525
|
+
log.scans.push({
|
|
526
|
+
databaseId: String(input.databaseId),
|
|
527
|
+
docId: String(input.docId),
|
|
528
|
+
result: scan ? "scanned" : "cancelled"
|
|
529
|
+
});
|
|
530
|
+
if (!scan) {
|
|
531
|
+
return { ok: false };
|
|
532
|
+
}
|
|
533
|
+
scanCounter += 1;
|
|
534
|
+
return {
|
|
535
|
+
ok: true,
|
|
536
|
+
attachment: {
|
|
537
|
+
attachmentId: `test-scan-${scanCounter}`,
|
|
538
|
+
fileName: scan.fileName,
|
|
539
|
+
mimeType: scan.mimeType,
|
|
540
|
+
size: scan.size
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
},
|
|
544
|
+
...hostOptions.requestHandlers
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
const onMessage = (event) => {
|
|
548
|
+
if (event.source !== frame.contentWindow) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
host.acceptConnection(event.data, event.ports);
|
|
552
|
+
};
|
|
553
|
+
window.addEventListener("message", onMessage);
|
|
554
|
+
frame.src = withLaunchId(appUrl, host.launchId);
|
|
555
|
+
return {
|
|
556
|
+
host,
|
|
557
|
+
log,
|
|
558
|
+
setNextScan(scan) {
|
|
559
|
+
nextScan = scan;
|
|
560
|
+
},
|
|
561
|
+
setTheme(theme) {
|
|
562
|
+
host.emitThemeChange(theme);
|
|
563
|
+
onChange?.();
|
|
564
|
+
},
|
|
565
|
+
setHostFocus(focused) {
|
|
566
|
+
host.emitHostFocusChange(focused);
|
|
567
|
+
onChange?.();
|
|
568
|
+
},
|
|
569
|
+
reloadApp() {
|
|
570
|
+
frame.src = withLaunchId(appUrl, host.launchId);
|
|
571
|
+
},
|
|
572
|
+
dispose() {
|
|
573
|
+
window.removeEventListener("message", onMessage);
|
|
574
|
+
host.dispose();
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
var STYLE = `
|
|
579
|
+
.htest{display:grid;grid-template-columns:minmax(0,1fr) 300px;height:100vh;margin:0;font:13px/1.45 system-ui,sans-serif;background:#eef1f7;color:#172033}
|
|
580
|
+
.htest *{box-sizing:border-box}
|
|
581
|
+
.htest__frame{width:100%;height:100%;border:0;background:#fff}
|
|
582
|
+
.htest__panel{border-left:1px solid #d7dce8;overflow:auto;padding:14px;background:#f8f9fc}
|
|
583
|
+
.htest__badge{display:inline-block;padding:2px 8px;border-radius:999px;background:#fde68a;color:#713f12;font-weight:600;font-size:11px;letter-spacing:.04em}
|
|
584
|
+
.htest h1{font-size:15px;margin:8px 0 12px}
|
|
585
|
+
.htest h2{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:#5b6478;margin:16px 0 6px}
|
|
586
|
+
.htest__row{display:flex;gap:6px;flex-wrap:wrap}
|
|
587
|
+
.htest button{font:inherit;padding:5px 9px;border-radius:7px;border:1px solid #c9d0e0;background:#fff;cursor:pointer}
|
|
588
|
+
.htest ul{list-style:none;margin:0;padding:0}
|
|
589
|
+
.htest li{padding:5px 0;border-bottom:1px solid #e4e8f1;word-break:break-word}
|
|
590
|
+
.htest__muted{color:#5b6478}
|
|
591
|
+
@media (max-width:720px){.htest{grid-template-columns:1fr;grid-template-rows:65vh auto}.htest__panel{border-left:0;border-top:1px solid #d7dce8}}
|
|
592
|
+
`;
|
|
593
|
+
function item(text) {
|
|
594
|
+
const li = document.createElement("li");
|
|
595
|
+
li.textContent = text;
|
|
596
|
+
return li;
|
|
597
|
+
}
|
|
598
|
+
function mountHavenTestHost(options) {
|
|
599
|
+
const { container = document.body, title = "Haven test host", ...hostOptions } = options;
|
|
600
|
+
const style = document.createElement("style");
|
|
601
|
+
style.textContent = STYLE;
|
|
602
|
+
document.head.append(style);
|
|
603
|
+
const root = document.createElement("div");
|
|
604
|
+
root.className = "htest";
|
|
605
|
+
const frame = document.createElement("iframe");
|
|
606
|
+
frame.className = "htest__frame";
|
|
607
|
+
frame.title = title;
|
|
608
|
+
frame.dataset.testid = "haven-test-app-frame";
|
|
609
|
+
const panel = document.createElement("aside");
|
|
610
|
+
panel.className = "htest__panel";
|
|
611
|
+
root.append(frame, panel);
|
|
612
|
+
container.replaceChildren(root);
|
|
613
|
+
if (container === document.body) {
|
|
614
|
+
document.body.style.margin = "0";
|
|
615
|
+
}
|
|
616
|
+
let focused = false;
|
|
617
|
+
let dark = false;
|
|
618
|
+
const lists = {
|
|
619
|
+
notifications: document.createElement("ul"),
|
|
620
|
+
previews: document.createElement("ul"),
|
|
621
|
+
scans: document.createElement("ul"),
|
|
622
|
+
requests: document.createElement("ul")
|
|
623
|
+
};
|
|
624
|
+
const focusState = document.createElement("span");
|
|
625
|
+
focusState.className = "htest__muted";
|
|
626
|
+
function button(label, onClick) {
|
|
627
|
+
const node = document.createElement("button");
|
|
628
|
+
node.type = "button";
|
|
629
|
+
node.textContent = label;
|
|
630
|
+
node.addEventListener("click", onClick);
|
|
631
|
+
return node;
|
|
632
|
+
}
|
|
633
|
+
function section(label, ...children) {
|
|
634
|
+
const heading2 = document.createElement("h2");
|
|
635
|
+
heading2.textContent = label;
|
|
636
|
+
panel.append(heading2, ...children);
|
|
637
|
+
}
|
|
638
|
+
function render() {
|
|
639
|
+
const { log } = testHost;
|
|
640
|
+
focusState.textContent = `focused: ${focused ? "yes" : "no"} \xB7 requests: ${log.focusRequests}`;
|
|
641
|
+
lists.notifications.replaceChildren(
|
|
642
|
+
...log.notifications.map((entry) => item(`[${entry.severity ?? "?"}] ${entry.text ?? ""}`))
|
|
643
|
+
);
|
|
644
|
+
lists.previews.replaceChildren(
|
|
645
|
+
...log.previews.map((entry) => item(`${entry.attachmentName} (${entry.databaseId}/${entry.docId})`))
|
|
646
|
+
);
|
|
647
|
+
lists.scans.replaceChildren(...log.scans.map((entry) => item(`${entry.result} \u2192 ${entry.docId}`)));
|
|
648
|
+
lists.requests.replaceChildren(...log.requests.slice(-30).reverse().map((entry) => item(entry.method)));
|
|
649
|
+
}
|
|
650
|
+
const testHost = createBrowserTestHost({ ...hostOptions, frame, onChange: render });
|
|
651
|
+
const badge = document.createElement("span");
|
|
652
|
+
badge.className = "htest__badge";
|
|
653
|
+
badge.textContent = "TEST HOST \xB7 MOCK DATA";
|
|
654
|
+
const heading = document.createElement("h1");
|
|
655
|
+
heading.textContent = title;
|
|
656
|
+
panel.append(badge, heading);
|
|
657
|
+
const hostRow = document.createElement("div");
|
|
658
|
+
hostRow.className = "htest__row";
|
|
659
|
+
hostRow.append(
|
|
660
|
+
button("Toggle theme", () => {
|
|
661
|
+
dark = !dark;
|
|
662
|
+
testHost.setTheme({ mode: dark ? "dark" : "light", preset: "mindoo" });
|
|
663
|
+
}),
|
|
664
|
+
button("Toggle focus", () => {
|
|
665
|
+
focused = !focused;
|
|
666
|
+
testHost.setHostFocus(focused);
|
|
667
|
+
}),
|
|
668
|
+
button("Reload app", () => testHost.reloadApp())
|
|
669
|
+
);
|
|
670
|
+
section("Host", hostRow, focusState);
|
|
671
|
+
const scanInput = document.createElement("input");
|
|
672
|
+
scanInput.type = "file";
|
|
673
|
+
scanInput.accept = "image/jpeg,image/png,application/pdf";
|
|
674
|
+
scanInput.addEventListener("change", () => {
|
|
675
|
+
const file = scanInput.files?.[0];
|
|
676
|
+
testHost.setNextScan(
|
|
677
|
+
file ? {
|
|
678
|
+
fileName: file.name,
|
|
679
|
+
mimeType: file.type === "image/png" || file.type === "application/pdf" ? file.type : "image/jpeg",
|
|
680
|
+
size: file.size
|
|
681
|
+
} : null
|
|
682
|
+
);
|
|
683
|
+
});
|
|
684
|
+
const scanHint = document.createElement("p");
|
|
685
|
+
scanHint.className = "htest__muted";
|
|
686
|
+
scanHint.textContent = "The app's next scan returns this file. Without one it is cancelled.";
|
|
687
|
+
section("Next scan", scanInput, scanHint);
|
|
688
|
+
section("Notifications", lists.notifications);
|
|
689
|
+
section("Previews", lists.previews);
|
|
690
|
+
section("Scans", lists.scans);
|
|
691
|
+
section("Requests (latest first)", lists.requests);
|
|
692
|
+
void testHost.host.session.getLaunchContext().then((context) => {
|
|
693
|
+
dark = context.theme.mode === "dark";
|
|
694
|
+
});
|
|
695
|
+
render();
|
|
696
|
+
window.__havenTestHost = testHost;
|
|
697
|
+
return testHost;
|
|
698
|
+
}
|
|
699
|
+
|
|
457
700
|
// src/testing/index.ts
|
|
458
701
|
var PROTOCOL = "mindoodb-app-bridge";
|
|
459
702
|
var MOCK_SIGNING_PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmockmockmockmockmockmockmockmockmockmockmoc=\n-----END PUBLIC KEY-----\n";
|
|
@@ -897,27 +1140,27 @@ function createDefaultWritableAttachmentStream() {
|
|
|
897
1140
|
}
|
|
898
1141
|
};
|
|
899
1142
|
}
|
|
900
|
-
function mockDecryptionKeyId(
|
|
901
|
-
if (!
|
|
1143
|
+
function mockDecryptionKeyId(document2) {
|
|
1144
|
+
if (!document2.decryptionKeyId || document2.data._encryptFor) {
|
|
902
1145
|
return {};
|
|
903
1146
|
}
|
|
904
|
-
return { decryptionKeyId:
|
|
1147
|
+
return { decryptionKeyId: document2.decryptionKeyId };
|
|
905
1148
|
}
|
|
906
|
-
function loadMockAutomergeDocument(
|
|
907
|
-
if (
|
|
908
|
-
return Automerge.load(
|
|
1149
|
+
function loadMockAutomergeDocument(document2) {
|
|
1150
|
+
if (document2.automergeBinary) {
|
|
1151
|
+
return Automerge.load(document2.automergeBinary);
|
|
909
1152
|
}
|
|
910
1153
|
const initialDoc = Automerge.from({
|
|
911
|
-
...structuredClone(
|
|
912
|
-
body: typeof
|
|
1154
|
+
...structuredClone(document2.data),
|
|
1155
|
+
body: typeof document2.data.body === "string" ? document2.data.body : ""
|
|
913
1156
|
});
|
|
914
|
-
|
|
1157
|
+
document2.automergeBinary = Automerge.save(initialDoc);
|
|
915
1158
|
return initialDoc;
|
|
916
1159
|
}
|
|
917
|
-
function persistMockAutomergeDocument(
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1160
|
+
function persistMockAutomergeDocument(document2, automergeDoc) {
|
|
1161
|
+
document2.automergeBinary = Automerge.save(automergeDoc);
|
|
1162
|
+
document2.data = structuredClone(automergeDoc);
|
|
1163
|
+
document2.heads = Automerge.getHeads(automergeDoc);
|
|
921
1164
|
}
|
|
922
1165
|
function getFieldValue2(source, field) {
|
|
923
1166
|
return field.split(".").reduce((current, part) => {
|
|
@@ -927,12 +1170,12 @@ function getFieldValue2(source, field) {
|
|
|
927
1170
|
return void 0;
|
|
928
1171
|
}, source);
|
|
929
1172
|
}
|
|
930
|
-
function matchesDocumentFilter(
|
|
1173
|
+
function matchesDocumentFilter(document2, filter) {
|
|
931
1174
|
if (!filter) {
|
|
932
1175
|
return true;
|
|
933
1176
|
}
|
|
934
1177
|
return Object.entries(filter).every(
|
|
935
|
-
([field, expected]) => getFieldValue2(
|
|
1178
|
+
([field, expected]) => getFieldValue2(document2.data, field) === expected
|
|
936
1179
|
);
|
|
937
1180
|
}
|
|
938
1181
|
function matchesMockIdPrefix(docId, idPrefix) {
|
|
@@ -979,8 +1222,8 @@ function collectMockText(value, depth = 0) {
|
|
|
979
1222
|
return "";
|
|
980
1223
|
}
|
|
981
1224
|
const parts = [];
|
|
982
|
-
for (const
|
|
983
|
-
const text = collectMockText(
|
|
1225
|
+
for (const item2 of Array.isArray(value) ? value : Object.values(value)) {
|
|
1226
|
+
const text = collectMockText(item2, depth + 1);
|
|
984
1227
|
if (text.length > 0) {
|
|
985
1228
|
parts.push(text);
|
|
986
1229
|
}
|
|
@@ -990,14 +1233,14 @@ function collectMockText(value, depth = 0) {
|
|
|
990
1233
|
function mockTokenize(text) {
|
|
991
1234
|
return text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((token) => token.length > 0);
|
|
992
1235
|
}
|
|
993
|
-
function computeMockTextScore(
|
|
1236
|
+
function computeMockTextScore(document2, clause) {
|
|
994
1237
|
const terms = mockTokenize(clause.query);
|
|
995
1238
|
if (terms.length === 0) {
|
|
996
1239
|
return void 0;
|
|
997
1240
|
}
|
|
998
|
-
const haystack = clause.fields ? clause.fields.map((field) => collectMockText(getFieldValue2(
|
|
1241
|
+
const haystack = clause.fields ? clause.fields.map((field) => collectMockText(getFieldValue2(document2.data, field))).join(" ") : collectMockText(
|
|
999
1242
|
Object.fromEntries(
|
|
1000
|
-
Object.entries(
|
|
1243
|
+
Object.entries(document2.data).filter(([key]) => !key.startsWith("_"))
|
|
1001
1244
|
)
|
|
1002
1245
|
);
|
|
1003
1246
|
const tokens = mockTokenize(haystack);
|
|
@@ -1021,22 +1264,22 @@ function runMockDocumentQuery(storedDocuments, databaseId, query, resolveDatabas
|
|
|
1021
1264
|
const filter = typeof query?.filter === "string" ? parseMindooDBFormulaBooleanExpression(query.filter) : query?.filter;
|
|
1022
1265
|
const sortBy = query?.sortBy && query.sortBy.length > 0 ? query.sortBy : query?.text ? [{ special: "textScore", direction: "descending" }] : [];
|
|
1023
1266
|
const matches = [];
|
|
1024
|
-
for (const
|
|
1025
|
-
if (
|
|
1267
|
+
for (const document2 of storedDocuments.values()) {
|
|
1268
|
+
if (document2.isDeleted || document2.inaccessible) {
|
|
1026
1269
|
continue;
|
|
1027
1270
|
}
|
|
1028
1271
|
let textScore;
|
|
1029
1272
|
if (query?.text) {
|
|
1030
|
-
textScore = computeMockTextScore(
|
|
1273
|
+
textScore = computeMockTextScore(document2, query.text);
|
|
1031
1274
|
if (textScore === void 0) {
|
|
1032
1275
|
continue;
|
|
1033
1276
|
}
|
|
1034
1277
|
}
|
|
1035
1278
|
const context = {
|
|
1036
|
-
doc:
|
|
1279
|
+
doc: document2.data,
|
|
1037
1280
|
values: {},
|
|
1038
1281
|
origin: databaseId,
|
|
1039
|
-
docId:
|
|
1282
|
+
docId: document2.id,
|
|
1040
1283
|
variables: {}
|
|
1041
1284
|
};
|
|
1042
1285
|
if (filter && !mockExpressionToBoolean(evaluateExpression2(filter, context))) {
|
|
@@ -1046,9 +1289,9 @@ function runMockDocumentQuery(storedDocuments, databaseId, query, resolveDatabas
|
|
|
1046
1289
|
if (key.special === "textScore") {
|
|
1047
1290
|
return textScore ?? 0;
|
|
1048
1291
|
}
|
|
1049
|
-
return key.expression ? evaluateExpression2(key.expression, context) : getFieldValue2(
|
|
1292
|
+
return key.expression ? evaluateExpression2(key.expression, context) : getFieldValue2(document2.data, key.field ?? "");
|
|
1050
1293
|
});
|
|
1051
|
-
matches.push({ document, sortValues, textScore });
|
|
1294
|
+
matches.push({ document: document2, sortValues, textScore });
|
|
1052
1295
|
}
|
|
1053
1296
|
if (sortBy.length > 0) {
|
|
1054
1297
|
matches.sort((left, right) => {
|
|
@@ -1069,19 +1312,19 @@ function runMockDocumentQuery(storedDocuments, databaseId, query, resolveDatabas
|
|
|
1069
1312
|
const offset = Math.max(0, query?.offset ?? 0);
|
|
1070
1313
|
const limit = Math.max(1, query?.limit ?? 200);
|
|
1071
1314
|
const page = matches.slice(offset, offset + limit);
|
|
1072
|
-
const rows = page.map(({ document, textScore }) => ({
|
|
1073
|
-
docId:
|
|
1074
|
-
fields: projectMockFields(
|
|
1075
|
-
lastModified: mockLastModified(
|
|
1315
|
+
const rows = page.map(({ document: document2, textScore }) => ({
|
|
1316
|
+
docId: document2.id,
|
|
1317
|
+
fields: projectMockFields(document2.data, query?.fields),
|
|
1318
|
+
lastModified: mockLastModified(document2),
|
|
1076
1319
|
...textScore === void 0 ? {} : { textScore }
|
|
1077
1320
|
}));
|
|
1078
1321
|
if (query?.include) {
|
|
1079
1322
|
hydrateMockIncludes({
|
|
1080
1323
|
includes: query.include,
|
|
1081
|
-
parents: page.map(({ document }, index) => ({
|
|
1324
|
+
parents: page.map(({ document: document2 }, index) => ({
|
|
1082
1325
|
row: rows[index],
|
|
1083
|
-
docId:
|
|
1084
|
-
data:
|
|
1326
|
+
docId: document2.id,
|
|
1327
|
+
data: document2.data
|
|
1085
1328
|
})),
|
|
1086
1329
|
parentDatabaseId: databaseId,
|
|
1087
1330
|
parentDocuments: storedDocuments,
|
|
@@ -1095,8 +1338,8 @@ function runMockDocumentQuery(storedDocuments, databaseId, query, resolveDatabas
|
|
|
1095
1338
|
function projectMockFields(data, fields) {
|
|
1096
1339
|
return fields ? Object.fromEntries(fields.map((field) => [field, getFieldValue2(data, field)])) : structuredClone(data);
|
|
1097
1340
|
}
|
|
1098
|
-
function mockLastModified(
|
|
1099
|
-
return
|
|
1341
|
+
function mockLastModified(document2) {
|
|
1342
|
+
return document2.updatedAt ? Date.parse(document2.updatedAt) || 0 : 0;
|
|
1100
1343
|
}
|
|
1101
1344
|
var MOCK_MAX_INCLUDE_DEPTH = 3;
|
|
1102
1345
|
var MOCK_DEFAULT_INCLUDE_LIMIT = 200;
|
|
@@ -1205,7 +1448,7 @@ function mockJoinValues(value) {
|
|
|
1205
1448
|
return [];
|
|
1206
1449
|
}
|
|
1207
1450
|
return (Array.isArray(value) ? value : [value]).filter(
|
|
1208
|
-
(
|
|
1451
|
+
(item2) => item2 !== void 0 && item2 !== null
|
|
1209
1452
|
);
|
|
1210
1453
|
}
|
|
1211
1454
|
function validateMockInclude(slot, label, include, depth) {
|
|
@@ -1289,35 +1532,35 @@ function hydrateMockIncludes(params) {
|
|
|
1289
1532
|
const sortBy = include.sortBy ?? [];
|
|
1290
1533
|
const childrenByKey = /* @__PURE__ */ new Map();
|
|
1291
1534
|
if (parentsByKey.size > 0) {
|
|
1292
|
-
for (const
|
|
1293
|
-
if (
|
|
1535
|
+
for (const document2 of childDocuments.values()) {
|
|
1536
|
+
if (document2.isDeleted || document2.inaccessible) {
|
|
1294
1537
|
continue;
|
|
1295
1538
|
}
|
|
1296
|
-
const childValue = plan.child.kind === "docId" ?
|
|
1539
|
+
const childValue = plan.child.kind === "docId" ? document2.id : getFieldValue2(document2.data, plan.child.path);
|
|
1297
1540
|
const matchedKeys = mockJoinValues(childValue).filter((key) => parentsByKey.has(key));
|
|
1298
1541
|
if (matchedKeys.length === 0) {
|
|
1299
1542
|
continue;
|
|
1300
1543
|
}
|
|
1301
1544
|
const context = {
|
|
1302
|
-
doc:
|
|
1545
|
+
doc: document2.data,
|
|
1303
1546
|
values: {},
|
|
1304
1547
|
origin: childDatabaseId,
|
|
1305
|
-
docId:
|
|
1548
|
+
docId: document2.id,
|
|
1306
1549
|
variables: {}
|
|
1307
1550
|
};
|
|
1308
1551
|
if (plan.residualFilter && !mockExpressionToBoolean(evaluateExpression2(plan.residualFilter, context))) {
|
|
1309
1552
|
continue;
|
|
1310
1553
|
}
|
|
1311
1554
|
const candidate = {
|
|
1312
|
-
docId:
|
|
1313
|
-
data:
|
|
1555
|
+
docId: document2.id,
|
|
1556
|
+
data: document2.data,
|
|
1314
1557
|
row: {
|
|
1315
|
-
docId:
|
|
1316
|
-
fields: projectMockFields(
|
|
1317
|
-
lastModified: mockLastModified(
|
|
1558
|
+
docId: document2.id,
|
|
1559
|
+
fields: projectMockFields(document2.data, include.fields),
|
|
1560
|
+
lastModified: mockLastModified(document2)
|
|
1318
1561
|
},
|
|
1319
1562
|
sortValues: sortBy.map(
|
|
1320
|
-
(key) => key.expression ? evaluateExpression2(key.expression, context) : getFieldValue2(
|
|
1563
|
+
(key) => key.expression ? evaluateExpression2(key.expression, context) : getFieldValue2(document2.data, key.field ?? "")
|
|
1321
1564
|
)
|
|
1322
1565
|
};
|
|
1323
1566
|
for (const key of matchedKeys) {
|
|
@@ -1746,30 +1989,30 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1746
1989
|
const offset = decodeMockListCursor(query?.cursor) + skip;
|
|
1747
1990
|
const metadataOnly = query?.metadataOnly ?? false;
|
|
1748
1991
|
const idPrefix = query?.idPrefix;
|
|
1749
|
-
const items = Array.from(storedDocuments.values()).filter((
|
|
1750
|
-
(
|
|
1751
|
-
).filter((
|
|
1752
|
-
(
|
|
1992
|
+
const items = Array.from(storedDocuments.values()).filter((document2) => !document2.inaccessible).filter(
|
|
1993
|
+
(document2) => status === "all" ? true : status === "deleted" ? document2.isDeleted : !document2.isDeleted
|
|
1994
|
+
).filter((document2) => matchesMockIdPrefix(document2.id, idPrefix)).filter(
|
|
1995
|
+
(document2) => metadataOnly ? true : matchesDocumentFilter(document2, query?.filter)
|
|
1753
1996
|
).sort((left, right) => left.id.localeCompare(right.id));
|
|
1754
|
-
const page = items.slice(offset, offset + limit).map((
|
|
1997
|
+
const page = items.slice(offset, offset + limit).map((document2) => {
|
|
1755
1998
|
if (metadataOnly) {
|
|
1756
1999
|
return {
|
|
1757
|
-
id:
|
|
1758
|
-
isDeleted:
|
|
2000
|
+
id: document2.id,
|
|
2001
|
+
isDeleted: document2.isDeleted
|
|
1759
2002
|
};
|
|
1760
2003
|
}
|
|
1761
2004
|
const projectedData = query?.fields ? Object.fromEntries(
|
|
1762
2005
|
query.fields.map((field) => [
|
|
1763
2006
|
field,
|
|
1764
|
-
getFieldValue2(
|
|
2007
|
+
getFieldValue2(document2.data, field)
|
|
1765
2008
|
])
|
|
1766
|
-
) :
|
|
2009
|
+
) : document2.data;
|
|
1767
2010
|
return {
|
|
1768
|
-
id:
|
|
2011
|
+
id: document2.id,
|
|
1769
2012
|
data: projectedData,
|
|
1770
|
-
attachmentCount:
|
|
1771
|
-
updatedAt:
|
|
1772
|
-
isDeleted: status !== "existing" ?
|
|
2013
|
+
attachmentCount: document2.attachments?.length ?? 0,
|
|
2014
|
+
updatedAt: document2.updatedAt,
|
|
2015
|
+
isDeleted: status !== "existing" ? document2.isDeleted : void 0
|
|
1773
2016
|
};
|
|
1774
2017
|
});
|
|
1775
2018
|
const nextCursor = offset + page.length < items.length ? String(offset + page.length) : null;
|
|
@@ -1785,50 +2028,50 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1785
2028
|
},
|
|
1786
2029
|
async listInaccessible(query) {
|
|
1787
2030
|
const idPrefix = query?.idPrefix;
|
|
1788
|
-
const items = Array.from(storedDocuments.values()).filter((
|
|
1789
|
-
id:
|
|
1790
|
-
createdAt:
|
|
1791
|
-
decryptionKeyId:
|
|
1792
|
-
authorLabel:
|
|
2031
|
+
const items = Array.from(storedDocuments.values()).filter((document2) => document2.inaccessible).filter((document2) => matchesMockIdPrefix(document2.id, idPrefix)).sort((left, right) => left.id.localeCompare(right.id)).map((document2) => ({
|
|
2032
|
+
id: document2.id,
|
|
2033
|
+
createdAt: document2.createdAt ?? document2.updatedAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
2034
|
+
decryptionKeyId: document2.decryptionKeyId ?? "sealed",
|
|
2035
|
+
authorLabel: document2.authorLabel
|
|
1793
2036
|
}));
|
|
1794
2037
|
return { items };
|
|
1795
2038
|
},
|
|
1796
2039
|
async get(_docId) {
|
|
1797
|
-
const
|
|
1798
|
-
if (!
|
|
2040
|
+
const document2 = storedDocuments.get(_docId);
|
|
2041
|
+
if (!document2 || document2.isDeleted || document2.inaccessible) {
|
|
1799
2042
|
return null;
|
|
1800
2043
|
}
|
|
1801
2044
|
return {
|
|
1802
|
-
id:
|
|
1803
|
-
data: structuredClone(
|
|
1804
|
-
heads:
|
|
1805
|
-
attachments:
|
|
1806
|
-
updatedAt:
|
|
1807
|
-
...mockDecryptionKeyId(
|
|
2045
|
+
id: document2.id,
|
|
2046
|
+
data: structuredClone(document2.data),
|
|
2047
|
+
heads: document2.heads ? [...document2.heads] : void 0,
|
|
2048
|
+
attachments: document2.attachments ? structuredClone(document2.attachments) : [],
|
|
2049
|
+
updatedAt: document2.updatedAt,
|
|
2050
|
+
...mockDecryptionKeyId(document2)
|
|
1808
2051
|
};
|
|
1809
2052
|
},
|
|
1810
2053
|
async getRichText(docId, path, _options) {
|
|
1811
|
-
const
|
|
1812
|
-
if (!
|
|
2054
|
+
const document2 = storedDocuments.get(docId);
|
|
2055
|
+
if (!document2 || document2.isDeleted) {
|
|
1813
2056
|
throw new Error(`Document ${docId} was not found.`);
|
|
1814
2057
|
}
|
|
1815
2058
|
return {
|
|
1816
2059
|
path: [...path],
|
|
1817
|
-
heads:
|
|
1818
|
-
spans: structuredClone(readRichTextSpansAtPath(
|
|
2060
|
+
heads: document2.heads ? [...document2.heads] : void 0,
|
|
2061
|
+
spans: structuredClone(readRichTextSpansAtPath(document2.data, path))
|
|
1819
2062
|
};
|
|
1820
2063
|
},
|
|
1821
2064
|
// Mock cursors store the index they were created at and do not follow
|
|
1822
2065
|
// later edits; Haven's Automerge-backed cursors do.
|
|
1823
2066
|
async getTextCursors(docId, path, positions, options) {
|
|
1824
|
-
const
|
|
1825
|
-
if (!
|
|
2067
|
+
const document2 = storedDocuments.get(docId);
|
|
2068
|
+
if (!document2 || document2.isDeleted) {
|
|
1826
2069
|
throw new Error(`Document ${docId} was not found.`);
|
|
1827
2070
|
}
|
|
1828
|
-
const text = readMockCursorText(
|
|
2071
|
+
const text = readMockCursorText(document2.data, path);
|
|
1829
2072
|
return {
|
|
1830
2073
|
path: [...path],
|
|
1831
|
-
heads: options?.heads ? [...options.heads] : [...
|
|
2074
|
+
heads: options?.heads ? [...options.heads] : [...document2.heads ?? []],
|
|
1832
2075
|
cursors: positions.map((position) => {
|
|
1833
2076
|
if (position === "start") return `${MOCK_CURSOR_PREFIX}0`;
|
|
1834
2077
|
if (position === "end") return `${MOCK_CURSOR_PREFIX}end`;
|
|
@@ -1840,14 +2083,14 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1840
2083
|
};
|
|
1841
2084
|
},
|
|
1842
2085
|
async resolveTextCursors(docId, path, cursors, options) {
|
|
1843
|
-
const
|
|
1844
|
-
if (!
|
|
2086
|
+
const document2 = storedDocuments.get(docId);
|
|
2087
|
+
if (!document2 || document2.isDeleted) {
|
|
1845
2088
|
throw new Error(`Document ${docId} was not found.`);
|
|
1846
2089
|
}
|
|
1847
|
-
const text = readMockCursorText(
|
|
2090
|
+
const text = readMockCursorText(document2.data, path);
|
|
1848
2091
|
return {
|
|
1849
2092
|
path: [...path],
|
|
1850
|
-
heads: options?.heads ? [...options.heads] : [...
|
|
2093
|
+
heads: options?.heads ? [...options.heads] : [...document2.heads ?? []],
|
|
1851
2094
|
positions: cursors.map((cursor) => {
|
|
1852
2095
|
if (typeof cursor !== "string" || !cursor.startsWith(MOCK_CURSOR_PREFIX)) {
|
|
1853
2096
|
throw new Error(`Unknown text cursor ${String(cursor)}`);
|
|
@@ -1858,29 +2101,29 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1858
2101
|
};
|
|
1859
2102
|
},
|
|
1860
2103
|
async getAutomergeSnapshot(docId, _options) {
|
|
1861
|
-
const
|
|
1862
|
-
if (!
|
|
2104
|
+
const document2 = storedDocuments.get(docId);
|
|
2105
|
+
if (!document2 || document2.isDeleted) {
|
|
1863
2106
|
throw new Error(`Document ${docId} was not found.`);
|
|
1864
2107
|
}
|
|
1865
|
-
const automergeDoc = loadMockAutomergeDocument(
|
|
2108
|
+
const automergeDoc = loadMockAutomergeDocument(document2);
|
|
1866
2109
|
return {
|
|
1867
2110
|
binary: Automerge.save(automergeDoc),
|
|
1868
2111
|
heads: Automerge.getHeads(automergeDoc)
|
|
1869
2112
|
};
|
|
1870
2113
|
},
|
|
1871
2114
|
async applyAutomergeChanges(docId, patch) {
|
|
1872
|
-
const
|
|
1873
|
-
if (!
|
|
2115
|
+
const document2 = storedDocuments.get(docId);
|
|
2116
|
+
if (!document2 || document2.isDeleted) {
|
|
1874
2117
|
throw new Error(`Document ${docId} was not found.`);
|
|
1875
2118
|
}
|
|
1876
|
-
const currentDoc = loadMockAutomergeDocument(
|
|
2119
|
+
const currentDoc = loadMockAutomergeDocument(document2);
|
|
1877
2120
|
const [mergedDoc] = Automerge.applyChanges(
|
|
1878
2121
|
currentDoc,
|
|
1879
2122
|
patch.changes.map((change) => new Uint8Array(change))
|
|
1880
2123
|
);
|
|
1881
|
-
persistMockAutomergeDocument(
|
|
1882
|
-
|
|
1883
|
-
const mergedHeads =
|
|
2124
|
+
persistMockAutomergeDocument(document2, mergedDoc);
|
|
2125
|
+
document2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2126
|
+
const mergedHeads = document2.heads ? [...document2.heads] : [];
|
|
1884
2127
|
let changesSince;
|
|
1885
2128
|
if (patch.replicaHeads?.length) {
|
|
1886
2129
|
const missingChanges = Automerge.getChangesSince(
|
|
@@ -1894,12 +2137,12 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1894
2137
|
}
|
|
1895
2138
|
return {
|
|
1896
2139
|
document: {
|
|
1897
|
-
id:
|
|
1898
|
-
data: structuredClone(
|
|
2140
|
+
id: document2.id,
|
|
2141
|
+
data: structuredClone(document2.data),
|
|
1899
2142
|
heads: mergedHeads,
|
|
1900
|
-
attachments:
|
|
1901
|
-
updatedAt:
|
|
1902
|
-
...mockDecryptionKeyId(
|
|
2143
|
+
attachments: document2.attachments ? structuredClone(document2.attachments) : [],
|
|
2144
|
+
updatedAt: document2.updatedAt,
|
|
2145
|
+
...mockDecryptionKeyId(document2)
|
|
1903
2146
|
},
|
|
1904
2147
|
heads: mergedHeads,
|
|
1905
2148
|
changesSince
|
|
@@ -1907,8 +2150,8 @@ function createDatabaseHandle(definition, peers) {
|
|
|
1907
2150
|
},
|
|
1908
2151
|
async applyAutomergeChangesBatch(items) {
|
|
1909
2152
|
const results = [];
|
|
1910
|
-
for (const
|
|
1911
|
-
results.push(await this.applyAutomergeChanges(
|
|
2153
|
+
for (const item2 of items) {
|
|
2154
|
+
results.push(await this.applyAutomergeChanges(item2.docId, item2.patch));
|
|
1912
2155
|
}
|
|
1913
2156
|
return results;
|
|
1914
2157
|
},
|
|
@@ -2295,11 +2538,11 @@ function createDatabaseHandle(definition, peers) {
|
|
|
2295
2538
|
};
|
|
2296
2539
|
return {
|
|
2297
2540
|
handle: databaseHandle,
|
|
2298
|
-
listViewDocuments: () => Array.from(storedDocuments.values()).filter((
|
|
2541
|
+
listViewDocuments: () => Array.from(storedDocuments.values()).filter((document2) => !document2.isDeleted && !document2.inaccessible).map((document2) => ({
|
|
2299
2542
|
origin: definition.info.id,
|
|
2300
|
-
docId:
|
|
2301
|
-
data: structuredClone(
|
|
2302
|
-
createdAt:
|
|
2543
|
+
docId: document2.id,
|
|
2544
|
+
data: structuredClone(document2.data),
|
|
2545
|
+
createdAt: document2.updatedAt ?? null
|
|
2303
2546
|
})),
|
|
2304
2547
|
documents: storedDocuments,
|
|
2305
2548
|
notifyLiveQueries: refreshLiveQueries
|
|
@@ -2741,31 +2984,35 @@ function createFakeBridgeHost(options = {}) {
|
|
|
2741
2984
|
);
|
|
2742
2985
|
let previousWindowValue = typeof window === "undefined" ? void 0 : window;
|
|
2743
2986
|
let installed = false;
|
|
2987
|
+
function acceptConnection(message, transfer) {
|
|
2988
|
+
const payload = message;
|
|
2989
|
+
if (!payload || payload.protocol !== PROTOCOL || payload.type !== "mindoodb-app:connect") {
|
|
2990
|
+
return false;
|
|
2991
|
+
}
|
|
2992
|
+
if (payload.launchId !== state.getLaunchContext().launchId) {
|
|
2993
|
+
return false;
|
|
2994
|
+
}
|
|
2995
|
+
const port = transfer?.[0];
|
|
2996
|
+
if (!port) {
|
|
2997
|
+
throw new Error(
|
|
2998
|
+
"Expected the bridge connection to transfer a MessagePort."
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
connectedPorts.add(port);
|
|
3002
|
+
port.addEventListener("message", (event) => {
|
|
3003
|
+
void handlePortMessage(port, event.data);
|
|
3004
|
+
});
|
|
3005
|
+
port.start();
|
|
3006
|
+
const connected = {
|
|
3007
|
+
protocol: PROTOCOL,
|
|
3008
|
+
type: "mindoodb-app:connected"
|
|
3009
|
+
};
|
|
3010
|
+
port.postMessage(connected);
|
|
3011
|
+
return true;
|
|
3012
|
+
}
|
|
2744
3013
|
const hostWindow = {
|
|
2745
3014
|
postMessage(message, _targetOrigin, transfer) {
|
|
2746
|
-
|
|
2747
|
-
if (!payload || payload.protocol !== PROTOCOL || payload.type !== "mindoodb-app:connect") {
|
|
2748
|
-
return;
|
|
2749
|
-
}
|
|
2750
|
-
if (payload.launchId !== state.getLaunchContext().launchId) {
|
|
2751
|
-
return;
|
|
2752
|
-
}
|
|
2753
|
-
const port = transfer?.[0];
|
|
2754
|
-
if (!port) {
|
|
2755
|
-
throw new Error(
|
|
2756
|
-
"Expected the bridge connection to transfer a MessagePort."
|
|
2757
|
-
);
|
|
2758
|
-
}
|
|
2759
|
-
connectedPorts.add(port);
|
|
2760
|
-
port.addEventListener("message", (event) => {
|
|
2761
|
-
void handlePortMessage(port, event.data);
|
|
2762
|
-
});
|
|
2763
|
-
port.start();
|
|
2764
|
-
const connected = {
|
|
2765
|
-
protocol: PROTOCOL,
|
|
2766
|
-
type: "mindoodb-app:connected"
|
|
2767
|
-
};
|
|
2768
|
-
port.postMessage(connected);
|
|
3015
|
+
acceptConnection(message, transfer);
|
|
2769
3016
|
}
|
|
2770
3017
|
};
|
|
2771
3018
|
function getWindowSearch() {
|
|
@@ -2885,6 +3132,8 @@ function createFakeBridgeHost(options = {}) {
|
|
|
2885
3132
|
return state.getLicensedProducts();
|
|
2886
3133
|
case "session.listDatabases":
|
|
2887
3134
|
return state.listDatabaseInfos();
|
|
3135
|
+
case "session.listDocumentsSinceViewCursor":
|
|
3136
|
+
return { items: [], nextCursor: null };
|
|
2888
3137
|
case "session.openDatabase":
|
|
2889
3138
|
state.getDatabase(String(params.databaseId));
|
|
2890
3139
|
return { ok: true };
|
|
@@ -3049,6 +3298,18 @@ function createFakeBridgeHost(options = {}) {
|
|
|
3049
3298
|
String(params.docId),
|
|
3050
3299
|
params.patch
|
|
3051
3300
|
);
|
|
3301
|
+
case "documents.automerge.applyChangesBatch":
|
|
3302
|
+
return await state.getDatabase(String(params.databaseId)).documents.applyAutomergeChangesBatch(
|
|
3303
|
+
Array.isArray(params.items) ? params.items : []
|
|
3304
|
+
);
|
|
3305
|
+
case "documents.createMany":
|
|
3306
|
+
return await state.getDatabase(String(params.databaseId)).documents.createMany(
|
|
3307
|
+
Array.isArray(params.inputs) ? params.inputs : []
|
|
3308
|
+
);
|
|
3309
|
+
case "documents.deleteMany":
|
|
3310
|
+
return await state.getDatabase(String(params.databaseId)).documents.deleteMany(Array.isArray(params.docIds) ? params.docIds.map(String) : []);
|
|
3311
|
+
case "databases.info":
|
|
3312
|
+
return await state.getDatabase(String(params.databaseId)).info();
|
|
3052
3313
|
case "documents.create":
|
|
3053
3314
|
return await state.getDatabase(String(params.databaseId)).documents.create(
|
|
3054
3315
|
params.input
|
|
@@ -3412,6 +3673,7 @@ function createFakeBridgeHost(options = {}) {
|
|
|
3412
3673
|
}
|
|
3413
3674
|
if (message.kind === "request") {
|
|
3414
3675
|
requests.push(message);
|
|
3676
|
+
options.onRequest?.(message);
|
|
3415
3677
|
try {
|
|
3416
3678
|
const customHandler = customRequestHandlers.get(message.method);
|
|
3417
3679
|
if (customHandler) {
|
|
@@ -3426,7 +3688,7 @@ function createFakeBridgeHost(options = {}) {
|
|
|
3426
3688
|
const builtinResult = await handleBuiltinRequest(message);
|
|
3427
3689
|
if (builtinResult === void 0 && message.method !== "viewNavigators.dispose") {
|
|
3428
3690
|
postRpcError(port, message.id, {
|
|
3429
|
-
code: "
|
|
3691
|
+
code: "method-not-found",
|
|
3430
3692
|
message: `No fake bridge handler is configured for ${message.method}.`
|
|
3431
3693
|
});
|
|
3432
3694
|
return;
|
|
@@ -3474,8 +3736,13 @@ function createFakeBridgeHost(options = {}) {
|
|
|
3474
3736
|
return state.proposedApps;
|
|
3475
3737
|
},
|
|
3476
3738
|
install,
|
|
3739
|
+
acceptConnection,
|
|
3477
3740
|
dispose() {
|
|
3478
3741
|
restoreWindow();
|
|
3742
|
+
connectedPorts.forEach((port) => {
|
|
3743
|
+
port.close();
|
|
3744
|
+
});
|
|
3745
|
+
connectedPorts.clear();
|
|
3479
3746
|
viewSessions.clear();
|
|
3480
3747
|
readStreams.clear();
|
|
3481
3748
|
writeStreams.clear();
|
|
@@ -3586,9 +3853,13 @@ function createFakeBridgeHost(options = {}) {
|
|
|
3586
3853
|
return controller;
|
|
3587
3854
|
}
|
|
3588
3855
|
export {
|
|
3856
|
+
capabilitiesForDefinitionPermissions,
|
|
3857
|
+
createBrowserTestHost,
|
|
3589
3858
|
createEvaluatingViewNavigator,
|
|
3590
3859
|
createFakeBridgeHost,
|
|
3591
3860
|
createMockMindooDBAppBridge,
|
|
3592
3861
|
createMockMindooDBAppSession,
|
|
3593
|
-
loadMindoodbForTesting
|
|
3862
|
+
loadMindoodbForTesting,
|
|
3863
|
+
mockDatabasesFromDefinition,
|
|
3864
|
+
mountHavenTestHost
|
|
3594
3865
|
};
|