mindoodb-app-sdk 0.0.4 → 0.0.5
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 +15 -7
- package/TESTING.md +3 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.js +48 -28
- package/dist/testing/index.d.ts +7 -3
- package/dist/testing/index.js +94 -31
- package/dist/{types-BGdIfp-D.d.ts → types-Cvlkh3vJ.d.ts} +18 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -98,6 +98,8 @@ console.log(launchContext.theme.mode); // "light" | "dark"
|
|
|
98
98
|
console.log(launchContext.viewport); // { width, height } | null
|
|
99
99
|
console.log(launchContext.user.username);
|
|
100
100
|
console.log(launchContext.launchParameters);
|
|
101
|
+
console.log(launchContext.databases);
|
|
102
|
+
console.log(launchContext.views);
|
|
101
103
|
```
|
|
102
104
|
|
|
103
105
|
`launchContext.viewport` is especially useful for responsive layouts inside embedded iframes. It is the initial viewport snapshot; later changes arrive through `onViewportChange()`.
|
|
@@ -126,19 +128,19 @@ The intended pattern is:
|
|
|
126
128
|
### 6. Discover the databases Haven exposed
|
|
127
129
|
|
|
128
130
|
```ts
|
|
129
|
-
const databases =
|
|
131
|
+
const databases = launchContext.databases;
|
|
130
132
|
|
|
131
133
|
for (const database of databases) {
|
|
132
134
|
console.log(database.id, database.title, database.capabilities);
|
|
133
135
|
}
|
|
134
136
|
```
|
|
135
137
|
|
|
136
|
-
|
|
138
|
+
Prefer `launchContext.databases` for the initial snapshot so your app discovers databases and views from the same source. `session.listDatabases()` is still available when you want to refresh database metadata later.
|
|
137
139
|
|
|
138
140
|
### 7. Open a database and work with documents
|
|
139
141
|
|
|
140
142
|
```ts
|
|
141
|
-
const databases =
|
|
143
|
+
const databases = launchContext.databases;
|
|
142
144
|
const db = await session.openDatabase(databases[0]!.id);
|
|
143
145
|
|
|
144
146
|
const list = await db.documents.list({ limit: 25 });
|
|
@@ -195,14 +197,16 @@ session.onViewportChange((viewport) => {
|
|
|
195
197
|
console.log("Resize:", viewport.width, viewport.height);
|
|
196
198
|
});
|
|
197
199
|
|
|
198
|
-
const databases =
|
|
200
|
+
const databases = launchContext.databases;
|
|
199
201
|
const db = await session.openDatabase(databases[0]!.id);
|
|
200
202
|
|
|
201
203
|
const list = await db.documents.list({ limit: 25 });
|
|
202
204
|
const firstDoc = list.items[0] ? await db.documents.get(list.items[0].id) : null;
|
|
203
205
|
|
|
204
206
|
const v = createViewLanguage<{ employee: string; hours: number; rate?: number }>();
|
|
205
|
-
const view = await
|
|
207
|
+
const view = await session.createView({
|
|
208
|
+
databaseId: databases[0]!.id,
|
|
209
|
+
definition: {
|
|
206
210
|
title: "Hours by employee",
|
|
207
211
|
defaultExpand: "collapsed",
|
|
208
212
|
filter: {
|
|
@@ -230,6 +234,7 @@ const view = await db.views.create({
|
|
|
230
234
|
),
|
|
231
235
|
},
|
|
232
236
|
],
|
|
237
|
+
},
|
|
233
238
|
});
|
|
234
239
|
|
|
235
240
|
const page = await view.page({ pageSize: 100 });
|
|
@@ -239,7 +244,7 @@ await view.dispose();
|
|
|
239
244
|
|
|
240
245
|
## Views and expression language
|
|
241
246
|
|
|
242
|
-
Views are app-defined and session-scoped. Create a definition
|
|
247
|
+
Views are app-defined and session-scoped. Create a definition with `session.createView()`, open Haven-configured mappings with `session.openView()`, page through rows, inspect categories, manage expansion state, then dispose the handle when done.
|
|
243
248
|
|
|
244
249
|
```ts
|
|
245
250
|
import { createViewLanguage } from "mindoodb-app-sdk";
|
|
@@ -252,7 +257,9 @@ const v = createViewLanguage<{
|
|
|
252
257
|
note?: string;
|
|
253
258
|
}>();
|
|
254
259
|
|
|
255
|
-
const view = await
|
|
260
|
+
const view = await session.createView({
|
|
261
|
+
databaseId: "main",
|
|
262
|
+
definition: {
|
|
256
263
|
title: "By employee",
|
|
257
264
|
defaultExpand: "collapsed",
|
|
258
265
|
filter: {
|
|
@@ -281,6 +288,7 @@ const view = await db.views.create({
|
|
|
281
288
|
sorting: "descending",
|
|
282
289
|
},
|
|
283
290
|
],
|
|
291
|
+
},
|
|
284
292
|
});
|
|
285
293
|
|
|
286
294
|
const page = await view.page({ pageSize: 100 });
|
package/TESTING.md
CHANGED
|
@@ -85,11 +85,13 @@ Both accept the same options:
|
|
|
85
85
|
- `databases`
|
|
86
86
|
- `onDisconnect`
|
|
87
87
|
|
|
88
|
+
When you pass `databases`, the mock session also exposes them through `session.getLaunchContext().databases`.
|
|
89
|
+
|
|
88
90
|
Each database entry can provide:
|
|
89
91
|
|
|
90
92
|
- `info`
|
|
91
93
|
- `methods.documents`
|
|
92
|
-
- `methods.views`
|
|
94
|
+
- `methods.views` for session-level `createView()` and `openView()` calls
|
|
93
95
|
- `methods.attachments`
|
|
94
96
|
|
|
95
97
|
## Level 2 example
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import { M as MindooDBAppBridge } from './types-
|
|
2
|
-
export {
|
|
1
|
+
import { M as MindooDBAppAttachmentPreviewMode, a as MindooDBAppBridge } from './types-Cvlkh3vJ.js';
|
|
2
|
+
export { b as MindooDBAppAttachmentApi, c as MindooDBAppAttachmentChunk, d as MindooDBAppAttachmentInfo, e as MindooDBAppAttachmentPreviewOptions, f as MindooDBAppBridgeConnectMessage, g as MindooDBAppBridgeConnectOptions, h as MindooDBAppBridgeConnectedMessage, i as MindooDBAppBridgeErrorPayload, j as MindooDBAppBridgePortMessage, k as MindooDBAppBridgeRpcError, l as MindooDBAppBridgeRpcMessage, m as MindooDBAppBridgeRpcRequest, n as MindooDBAppBridgeRpcSuccess, o as MindooDBAppBridgeStreamAbortRequest, p as MindooDBAppBridgeStreamAck, q as MindooDBAppBridgeStreamCloseRequest, r as MindooDBAppBridgeStreamError, s as MindooDBAppBridgeStreamMessage, t as MindooDBAppBridgeStreamOpenResult, u as MindooDBAppBridgeStreamReadRequest, v as MindooDBAppBridgeStreamWriteRequest, w as MindooDBAppBridgeThemeChangedMessage, x as MindooDBAppBridgeViewportChangedMessage, y as MindooDBAppCapability, z as MindooDBAppConfiguredViewCategorizationStyle, A as MindooDBAppConfiguredViewColumn, B as MindooDBAppConfiguredViewColumnRole, C as MindooDBAppConfiguredViewExpressionMode, D as MindooDBAppConfiguredViewFieldExpression, E as MindooDBAppConfiguredViewFilterDefinition, F as MindooDBAppConfiguredViewFilterMode, G as MindooDBAppConfiguredViewFilterRule, H as MindooDBAppConfiguredViewFormulaExpression, I as MindooDBAppConfiguredViewFormulaFilterDefinition, J as MindooDBAppConfiguredViewPreviewMode, K as MindooDBAppConfiguredViewRuleFilterDefinition, L as MindooDBAppConfiguredViewRuleMatchMode, N as MindooDBAppConfiguredViewRuleOperator, O as MindooDBAppConfiguredViewValueExpression, P as MindooDBAppCreateDocumentInput, Q as MindooDBAppCreateViewInput, R as MindooDBAppDatabase, S as MindooDBAppDatabaseInfo, T as MindooDBAppDocument, U as MindooDBAppDocumentApi, V as MindooDBAppDocumentHistoryEntry, W as MindooDBAppDocumentListQuery, X as MindooDBAppDocumentListResult, Y as MindooDBAppDocumentSummary, Z as MindooDBAppHistoricalDocument, _ as MindooDBAppHistoryQuery, $ as MindooDBAppHostTheme, a0 as MindooDBAppLaunchContext, a1 as MindooDBAppReadableAttachmentStream, a2 as MindooDBAppResolvedViewDefinition, a3 as MindooDBAppResolvedViewSource, a4 as MindooDBAppRuntime, a5 as MindooDBAppSession, a6 as MindooDBAppThemeMode, a7 as MindooDBAppUpdateDocumentInput, a8 as MindooDBAppViewHandle, a9 as MindooDBAppViewport, aa as MindooDBAppWritableAttachmentStream } from './types-Cvlkh3vJ.js';
|
|
3
3
|
export { MindooDBAppBooleanExpression, MindooDBAppExpression, MindooDBAppFilterDefinition, MindooDBAppViewCategoryChildrenPageRequest, MindooDBAppViewColumn, MindooDBAppViewColumnRole, MindooDBAppViewDefinition, MindooDBAppViewExpansionState, MindooDBAppViewExpressionBase, MindooDBAppViewExpressionDatePart, MindooDBAppViewExpressionOperation, MindooDBAppViewFieldExpression, MindooDBAppViewIfExpression, MindooDBAppViewLetExpression, MindooDBAppViewLiteralExpression, MindooDBAppViewLookupByPath, MindooDBAppViewOperationExpression, MindooDBAppViewOriginExpression, MindooDBAppViewPageRequest, MindooDBAppViewPageResult, MindooDBAppViewRow, MindooDBAppViewSortDirection, MindooDBAppViewTotalMode, MindooDBAppViewValueExpressionRef, MindooDBAppViewVariableExpression, createViewLanguage } from 'mindoodb-view-language';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Resolves whether Haven can render a built-in preview for an attachment.
|
|
7
|
+
*
|
|
8
|
+
* Apps can use this as a fast local check before calling
|
|
9
|
+
* `attachments.openPreview()`.
|
|
10
|
+
*/
|
|
11
|
+
declare function canPreviewAttachment(fileName: string, mimeType: string): MindooDBAppAttachmentPreviewMode | null;
|
|
12
|
+
|
|
5
13
|
/**
|
|
6
14
|
* Creates the browser-side bridge entry point used by MindooDB apps.
|
|
7
15
|
*
|
|
@@ -11,4 +19,4 @@ export { MindooDBAppBooleanExpression, MindooDBAppExpression, MindooDBAppFilterD
|
|
|
11
19
|
*/
|
|
12
20
|
declare function createMindooDBAppBridge(): MindooDBAppBridge;
|
|
13
21
|
|
|
14
|
-
export { MindooDBAppBridge, createMindooDBAppBridge };
|
|
22
|
+
export { MindooDBAppAttachmentPreviewMode, MindooDBAppBridge, canPreviewAttachment, createMindooDBAppBridge };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
// src/attachmentPreview.ts
|
|
2
|
+
function canPreviewAttachment(fileName, mimeType) {
|
|
3
|
+
const normalizedMimeType = mimeType.toLowerCase();
|
|
4
|
+
const normalizedFileName = fileName.toLowerCase();
|
|
5
|
+
if (normalizedMimeType.startsWith("image/")) {
|
|
6
|
+
return "image";
|
|
7
|
+
}
|
|
8
|
+
if (normalizedMimeType.startsWith("video/")) {
|
|
9
|
+
return "video";
|
|
10
|
+
}
|
|
11
|
+
if (normalizedMimeType.startsWith("audio/")) {
|
|
12
|
+
return "audio";
|
|
13
|
+
}
|
|
14
|
+
if (normalizedMimeType === "application/pdf" || normalizedFileName.endsWith(".pdf")) {
|
|
15
|
+
return "pdf";
|
|
16
|
+
}
|
|
17
|
+
if (normalizedMimeType === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || normalizedMimeType === "application/vnd.ms-excel" || normalizedMimeType === "application/vnd.ms-excel.sheet.macroenabled.12" || normalizedMimeType === "application/vnd.ms-excel.sheet.binary.macroenabled.12" || normalizedFileName.endsWith(".xlsx") || normalizedFileName.endsWith(".xls") || normalizedFileName.endsWith(".xlsm") || normalizedFileName.endsWith(".xlsb")) {
|
|
18
|
+
return "spreadsheet";
|
|
19
|
+
}
|
|
20
|
+
if (normalizedMimeType === "application/vnd.openxmlformats-officedocument.wordprocessingml.document" || normalizedFileName.endsWith(".docx")) {
|
|
21
|
+
return "docx";
|
|
22
|
+
}
|
|
23
|
+
if (normalizedMimeType === "application/vnd.openxmlformats-officedocument.presentationml.presentation" || normalizedFileName.endsWith(".pptx")) {
|
|
24
|
+
return "pptx";
|
|
25
|
+
}
|
|
26
|
+
if (normalizedMimeType.startsWith("text/") || normalizedMimeType === "application/json" || normalizedMimeType === "application/xml" || normalizedMimeType === "image/svg+xml" || normalizedFileName.endsWith(".json") || normalizedFileName.endsWith(".txt") || normalizedFileName.endsWith(".md") || normalizedFileName.endsWith(".csv") || normalizedFileName.endsWith(".log") || normalizedFileName.endsWith(".xml") || normalizedFileName.endsWith(".yaml") || normalizedFileName.endsWith(".yml") || normalizedFileName.endsWith(".svg")) {
|
|
27
|
+
return "text";
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
1
32
|
// src/client/portRpcClient.ts
|
|
2
33
|
var PROTOCOL = "mindoodb-app-bridge";
|
|
3
34
|
function normalizeRpcValue(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
@@ -235,86 +266,73 @@ function waitForConnectedPort(options, launchId) {
|
|
|
235
266
|
});
|
|
236
267
|
}
|
|
237
268
|
var MindooDBAppViewHandleImpl = class {
|
|
238
|
-
constructor(rpc,
|
|
269
|
+
constructor(rpc, viewId) {
|
|
239
270
|
this.rpc = rpc;
|
|
240
|
-
this.databaseId = databaseId;
|
|
241
271
|
this.viewId = viewId;
|
|
242
272
|
}
|
|
243
273
|
async getDefinition() {
|
|
244
274
|
return await this.rpc.call("views.getDefinition", {
|
|
245
|
-
databaseId: this.databaseId,
|
|
246
275
|
viewId: this.viewId
|
|
247
276
|
});
|
|
248
277
|
}
|
|
249
278
|
async refresh() {
|
|
250
279
|
await this.rpc.call("views.refresh", {
|
|
251
|
-
databaseId: this.databaseId,
|
|
252
280
|
viewId: this.viewId
|
|
253
281
|
});
|
|
254
282
|
}
|
|
255
283
|
async page(input) {
|
|
256
284
|
return await this.rpc.call("views.page", {
|
|
257
|
-
databaseId: this.databaseId,
|
|
258
285
|
viewId: this.viewId,
|
|
259
286
|
request: input ?? {}
|
|
260
287
|
});
|
|
261
288
|
}
|
|
262
289
|
async getExpansionState() {
|
|
263
290
|
return await this.rpc.call("views.expansion.get", {
|
|
264
|
-
databaseId: this.databaseId,
|
|
265
291
|
viewId: this.viewId
|
|
266
292
|
});
|
|
267
293
|
}
|
|
268
294
|
async setExpansionState(state) {
|
|
269
295
|
return await this.rpc.call("views.expansion.set", {
|
|
270
|
-
databaseId: this.databaseId,
|
|
271
296
|
viewId: this.viewId,
|
|
272
297
|
expansion: state
|
|
273
298
|
});
|
|
274
299
|
}
|
|
275
300
|
async expand(rowKey) {
|
|
276
301
|
return await this.rpc.call("views.expansion.expand", {
|
|
277
|
-
databaseId: this.databaseId,
|
|
278
302
|
viewId: this.viewId,
|
|
279
303
|
rowKey
|
|
280
304
|
});
|
|
281
305
|
}
|
|
282
306
|
async collapse(rowKey) {
|
|
283
307
|
return await this.rpc.call("views.expansion.collapse", {
|
|
284
|
-
databaseId: this.databaseId,
|
|
285
308
|
viewId: this.viewId,
|
|
286
309
|
rowKey
|
|
287
310
|
});
|
|
288
311
|
}
|
|
289
312
|
async expandAll() {
|
|
290
313
|
return await this.rpc.call("views.expansion.expandAll", {
|
|
291
|
-
databaseId: this.databaseId,
|
|
292
314
|
viewId: this.viewId
|
|
293
315
|
});
|
|
294
316
|
}
|
|
295
317
|
async collapseAll() {
|
|
296
318
|
return await this.rpc.call("views.expansion.collapseAll", {
|
|
297
|
-
databaseId: this.databaseId,
|
|
298
319
|
viewId: this.viewId
|
|
299
320
|
});
|
|
300
321
|
}
|
|
301
322
|
async getRow(rowKey) {
|
|
302
323
|
return await this.rpc.call("views.row.get", {
|
|
303
|
-
databaseId: this.databaseId,
|
|
304
324
|
viewId: this.viewId,
|
|
305
325
|
rowKey
|
|
306
326
|
});
|
|
307
327
|
}
|
|
308
328
|
async getCategory(input) {
|
|
309
329
|
return await this.rpc.call("views.category.get", {
|
|
310
|
-
databaseId: this.databaseId,
|
|
311
330
|
viewId: this.viewId,
|
|
312
331
|
lookup: input
|
|
313
332
|
});
|
|
314
333
|
}
|
|
315
334
|
async pageCategory(categoryKey, input) {
|
|
316
335
|
return await this.rpc.call("views.category.page", {
|
|
317
|
-
databaseId: this.databaseId,
|
|
318
336
|
viewId: this.viewId,
|
|
319
337
|
categoryKey,
|
|
320
338
|
request: input ?? {}
|
|
@@ -322,14 +340,12 @@ var MindooDBAppViewHandleImpl = class {
|
|
|
322
340
|
}
|
|
323
341
|
async listCategoryDocumentIds(categoryKey) {
|
|
324
342
|
return await this.rpc.call("views.category.documentIds", {
|
|
325
|
-
databaseId: this.databaseId,
|
|
326
343
|
viewId: this.viewId,
|
|
327
344
|
categoryKey
|
|
328
345
|
});
|
|
329
346
|
}
|
|
330
347
|
async dispose() {
|
|
331
348
|
await this.rpc.call("views.dispose", {
|
|
332
|
-
databaseId: this.databaseId,
|
|
333
349
|
viewId: this.viewId
|
|
334
350
|
});
|
|
335
351
|
}
|
|
@@ -522,16 +538,6 @@ var MindooDBAppDatabaseImpl = class {
|
|
|
522
538
|
timestamp
|
|
523
539
|
})
|
|
524
540
|
};
|
|
525
|
-
this.views = {
|
|
526
|
-
create: async (definition) => {
|
|
527
|
-
const result = await this.rpc.call("views.create", {
|
|
528
|
-
databaseId: this.databaseId,
|
|
529
|
-
definition
|
|
530
|
-
});
|
|
531
|
-
return new MindooDBAppViewHandleImpl(this.rpc, this.databaseId, result.viewId);
|
|
532
|
-
},
|
|
533
|
-
open: async (viewId) => new MindooDBAppViewHandleImpl(this.rpc, this.databaseId, viewId)
|
|
534
|
-
};
|
|
535
541
|
this.attachments = {
|
|
536
542
|
list: async (docId) => await this.rpc.call("attachments.list", {
|
|
537
543
|
databaseId: this.databaseId,
|
|
@@ -558,11 +564,16 @@ var MindooDBAppDatabaseImpl = class {
|
|
|
558
564
|
contentType
|
|
559
565
|
});
|
|
560
566
|
return new MindooDBAppWritableAttachmentStreamImpl(this.rpc, result.streamId);
|
|
561
|
-
}
|
|
567
|
+
},
|
|
568
|
+
openPreview: async (docId, attachmentName, options) => await this.rpc.call("attachments.openPreview", {
|
|
569
|
+
databaseId: this.databaseId,
|
|
570
|
+
docId,
|
|
571
|
+
attachmentName,
|
|
572
|
+
timestamp: options?.timestamp
|
|
573
|
+
})
|
|
562
574
|
};
|
|
563
575
|
}
|
|
564
576
|
documents;
|
|
565
|
-
views;
|
|
566
577
|
attachments;
|
|
567
578
|
/** Returns database metadata for the currently opened binding. */
|
|
568
579
|
async info() {
|
|
@@ -587,6 +598,14 @@ var MindooDBAppSessionImpl = class {
|
|
|
587
598
|
await this.rpc.call("session.openDatabase", { databaseId });
|
|
588
599
|
return new MindooDBAppDatabaseImpl(this.rpc, databaseId);
|
|
589
600
|
}
|
|
601
|
+
async createView(input) {
|
|
602
|
+
const result = await this.rpc.call("session.createView", input);
|
|
603
|
+
return new MindooDBAppViewHandleImpl(this.rpc, result.viewId);
|
|
604
|
+
}
|
|
605
|
+
async openView(viewId) {
|
|
606
|
+
await this.rpc.call("session.openView", { viewId });
|
|
607
|
+
return new MindooDBAppViewHandleImpl(this.rpc, viewId);
|
|
608
|
+
}
|
|
590
609
|
onThemeChange(listener) {
|
|
591
610
|
return this.rpc.addMessageListener((message) => {
|
|
592
611
|
if (isThemeChangedMessage(message)) {
|
|
@@ -629,6 +648,7 @@ import {
|
|
|
629
648
|
mindooDBViewLanguageHelpersByName
|
|
630
649
|
} from "mindoodb-view-language";
|
|
631
650
|
export {
|
|
651
|
+
canPreviewAttachment,
|
|
632
652
|
createMindooDBAppBridge,
|
|
633
653
|
createViewLanguage
|
|
634
654
|
};
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import 'mindoodb-view-language';
|
|
1
|
+
import { a0 as MindooDBAppLaunchContext, S as MindooDBAppDatabaseInfo, U as MindooDBAppDocumentApi, a8 as MindooDBAppViewHandle, b as MindooDBAppAttachmentApi, a as MindooDBAppBridge, a5 as MindooDBAppSession, m as MindooDBAppBridgeRpcRequest, $ as MindooDBAppHostTheme, a9 as MindooDBAppViewport, j as MindooDBAppBridgePortMessage } from '../types-Cvlkh3vJ.js';
|
|
2
|
+
import { MindooDBAppViewDefinition } from 'mindoodb-view-language';
|
|
3
3
|
|
|
4
4
|
type MaybePromise<T> = T | Promise<T>;
|
|
5
|
+
type MockViewApi = {
|
|
6
|
+
create(definition: MindooDBAppViewDefinition): MaybePromise<MindooDBAppViewHandle>;
|
|
7
|
+
open(viewId: string): MaybePromise<MindooDBAppViewHandle>;
|
|
8
|
+
};
|
|
5
9
|
type MockDatabaseMethods = {
|
|
6
10
|
documents?: Partial<MindooDBAppDocumentApi>;
|
|
7
|
-
views?: Partial<
|
|
11
|
+
views?: Partial<MockViewApi>;
|
|
8
12
|
attachments?: Partial<MindooDBAppAttachmentApi>;
|
|
9
13
|
};
|
|
10
14
|
interface MockMindooDBAppDatabaseDefinition {
|
package/dist/testing/index.js
CHANGED
|
@@ -20,6 +20,10 @@ function mergeLaunchContext(current, patch) {
|
|
|
20
20
|
viewport: current.viewport ? { ...current.viewport } : null,
|
|
21
21
|
user: { ...current.user },
|
|
22
22
|
launchParameters: { ...current.launchParameters },
|
|
23
|
+
databases: current.databases.map((database) => ({
|
|
24
|
+
...database,
|
|
25
|
+
capabilities: [...database.capabilities]
|
|
26
|
+
})),
|
|
23
27
|
views: current.views.map((view) => ({
|
|
24
28
|
...view,
|
|
25
29
|
sources: view.sources.map((source) => ({ ...source })),
|
|
@@ -45,6 +49,13 @@ function mergeLaunchContext(current, patch) {
|
|
|
45
49
|
viewport: patch.viewport === void 0 ? current.viewport ? { ...current.viewport } : null : patch.viewport ? { ...patch.viewport } : null,
|
|
46
50
|
user: patch.user ? { ...current.user, ...patch.user } : { ...current.user },
|
|
47
51
|
launchParameters: patch.launchParameters ? { ...current.launchParameters, ...patch.launchParameters } : { ...current.launchParameters },
|
|
52
|
+
databases: patch.databases ? patch.databases.map((database) => ({
|
|
53
|
+
...database,
|
|
54
|
+
capabilities: [...database.capabilities]
|
|
55
|
+
})) : current.databases.map((database) => ({
|
|
56
|
+
...database,
|
|
57
|
+
capabilities: [...database.capabilities]
|
|
58
|
+
})),
|
|
48
59
|
views: patch.views ? patch.views.map((view) => ({
|
|
49
60
|
...view,
|
|
50
61
|
sources: view.sources.map((source) => ({ ...source })),
|
|
@@ -98,6 +109,7 @@ function createDefaultLaunchContext(patch) {
|
|
|
98
109
|
username: "Test User"
|
|
99
110
|
},
|
|
100
111
|
launchParameters: {},
|
|
112
|
+
databases: [],
|
|
101
113
|
views: []
|
|
102
114
|
};
|
|
103
115
|
return mergeLaunchContext(base, patch);
|
|
@@ -265,6 +277,9 @@ function createDatabaseHandle(definition) {
|
|
|
265
277
|
},
|
|
266
278
|
async openWriteStream(_docId, _attachmentName, _contentType) {
|
|
267
279
|
return createDefaultWritableAttachmentStream();
|
|
280
|
+
},
|
|
281
|
+
async openPreview(_docId, _attachmentName, _options) {
|
|
282
|
+
return { ok: true };
|
|
268
283
|
}
|
|
269
284
|
};
|
|
270
285
|
const methods = definition.methods ?? {};
|
|
@@ -276,10 +291,6 @@ function createDatabaseHandle(definition) {
|
|
|
276
291
|
...defaultDocuments,
|
|
277
292
|
...methods.documents
|
|
278
293
|
},
|
|
279
|
-
views: {
|
|
280
|
-
...defaultViews,
|
|
281
|
-
...methods.views
|
|
282
|
-
},
|
|
283
294
|
attachments: {
|
|
284
295
|
...defaultAttachments,
|
|
285
296
|
...methods.attachments
|
|
@@ -291,16 +302,29 @@ function createMockSessionState(options = {}) {
|
|
|
291
302
|
const themeListeners = /* @__PURE__ */ new Set();
|
|
292
303
|
const viewportListeners = /* @__PURE__ */ new Set();
|
|
293
304
|
const databaseHandles = /* @__PURE__ */ new Map();
|
|
305
|
+
const databaseViewApis = /* @__PURE__ */ new Map();
|
|
306
|
+
const sessionViews = /* @__PURE__ */ new Map();
|
|
294
307
|
let databaseInfos = [];
|
|
295
308
|
const setDatabases = (definitions) => {
|
|
296
309
|
databaseHandles.clear();
|
|
310
|
+
databaseViewApis.clear();
|
|
297
311
|
databaseInfos = definitions.map((definition) => ({
|
|
298
312
|
...definition.info,
|
|
299
313
|
capabilities: [...definition.info.capabilities]
|
|
300
314
|
}));
|
|
301
315
|
for (const definition of definitions) {
|
|
302
316
|
databaseHandles.set(definition.info.id, createDatabaseHandle(definition));
|
|
317
|
+
databaseViewApis.set(definition.info.id, {
|
|
318
|
+
async create(_definition) {
|
|
319
|
+
return await createDefaultViewHandle();
|
|
320
|
+
},
|
|
321
|
+
async open(_viewId) {
|
|
322
|
+
return await createDefaultViewHandle();
|
|
323
|
+
},
|
|
324
|
+
...definition.methods?.views ?? {}
|
|
325
|
+
});
|
|
303
326
|
}
|
|
327
|
+
launchContext = mergeLaunchContext(launchContext, { databases: databaseInfos });
|
|
304
328
|
};
|
|
305
329
|
setDatabases(options.databases ?? []);
|
|
306
330
|
const session = {
|
|
@@ -320,6 +344,33 @@ function createMockSessionState(options = {}) {
|
|
|
320
344
|
}
|
|
321
345
|
return database;
|
|
322
346
|
},
|
|
347
|
+
async createView(input) {
|
|
348
|
+
const api = databaseViewApis.get(input.databaseId);
|
|
349
|
+
if (!api) {
|
|
350
|
+
throw new Error(`Unknown test database for view creation: ${input.databaseId}`);
|
|
351
|
+
}
|
|
352
|
+
const view = await api.create(input.definition);
|
|
353
|
+
const viewId = input.definition.id || crypto.randomUUID();
|
|
354
|
+
sessionViews.set(viewId, view);
|
|
355
|
+
return view;
|
|
356
|
+
},
|
|
357
|
+
async openView(viewId) {
|
|
358
|
+
const existing = sessionViews.get(viewId);
|
|
359
|
+
if (existing) {
|
|
360
|
+
return existing;
|
|
361
|
+
}
|
|
362
|
+
const sourceDatabaseId = launchContext.views.find((view2) => view2.id === viewId)?.sources[0]?.databaseId;
|
|
363
|
+
if (!sourceDatabaseId) {
|
|
364
|
+
throw new Error(`Unknown test view: ${viewId}`);
|
|
365
|
+
}
|
|
366
|
+
const api = databaseViewApis.get(sourceDatabaseId);
|
|
367
|
+
if (!api) {
|
|
368
|
+
throw new Error(`Unknown test database for view ${viewId}: ${sourceDatabaseId}`);
|
|
369
|
+
}
|
|
370
|
+
const view = await api.open(viewId);
|
|
371
|
+
sessionViews.set(viewId, view);
|
|
372
|
+
return view;
|
|
373
|
+
},
|
|
323
374
|
onThemeChange(listener) {
|
|
324
375
|
themeListeners.add(listener);
|
|
325
376
|
return () => {
|
|
@@ -363,6 +414,8 @@ function createMockSessionState(options = {}) {
|
|
|
363
414
|
}
|
|
364
415
|
return database;
|
|
365
416
|
},
|
|
417
|
+
createView: session.createView,
|
|
418
|
+
openView: session.openView,
|
|
366
419
|
bridge,
|
|
367
420
|
session,
|
|
368
421
|
emitThemeChange(theme) {
|
|
@@ -492,15 +545,13 @@ function createFakeBridgeHost(options = {}) {
|
|
|
492
545
|
});
|
|
493
546
|
installed = true;
|
|
494
547
|
}
|
|
495
|
-
async function resolveViewHandle(
|
|
496
|
-
const
|
|
497
|
-
const existing = viewSessions.get(key);
|
|
548
|
+
async function resolveViewHandle(viewId) {
|
|
549
|
+
const existing = viewSessions.get(viewId);
|
|
498
550
|
if (existing) {
|
|
499
551
|
return existing;
|
|
500
552
|
}
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
viewSessions.set(key, handle);
|
|
553
|
+
const handle = await state.openView(viewId);
|
|
554
|
+
viewSessions.set(viewId, handle);
|
|
504
555
|
return handle;
|
|
505
556
|
}
|
|
506
557
|
function postRpcSuccess(port, requestId, result) {
|
|
@@ -544,6 +595,18 @@ function createFakeBridgeHost(options = {}) {
|
|
|
544
595
|
case "session.openDatabase":
|
|
545
596
|
state.getDatabase(String(params.databaseId));
|
|
546
597
|
return { ok: true };
|
|
598
|
+
case "session.createView": {
|
|
599
|
+
const viewId = `view-${viewCounter += 1}`;
|
|
600
|
+
const handle = await state.createView({
|
|
601
|
+
databaseId: String(params.databaseId),
|
|
602
|
+
definition: params.definition
|
|
603
|
+
});
|
|
604
|
+
viewSessions.set(viewId, handle);
|
|
605
|
+
return { viewId };
|
|
606
|
+
}
|
|
607
|
+
case "session.openView":
|
|
608
|
+
await state.openView(String(params.viewId));
|
|
609
|
+
return { ok: true };
|
|
547
610
|
case "session.disconnect":
|
|
548
611
|
await state.session.disconnect();
|
|
549
612
|
return { ok: true };
|
|
@@ -593,52 +656,52 @@ function createFakeBridgeHost(options = {}) {
|
|
|
593
656
|
writeStreams.set(streamId, stream);
|
|
594
657
|
return { streamId };
|
|
595
658
|
}
|
|
596
|
-
case "
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
659
|
+
case "attachments.openPreview":
|
|
660
|
+
return await state.getDatabase(String(params.databaseId)).attachments.openPreview(
|
|
661
|
+
String(params.docId),
|
|
662
|
+
String(params.attachmentName),
|
|
663
|
+
typeof params.timestamp === "number" ? { timestamp: params.timestamp } : void 0
|
|
664
|
+
);
|
|
602
665
|
case "views.getDefinition":
|
|
603
|
-
return await (await resolveViewHandle(String(params.
|
|
666
|
+
return await (await resolveViewHandle(String(params.viewId))).getDefinition();
|
|
604
667
|
case "views.refresh":
|
|
605
|
-
return await (await resolveViewHandle(String(params.
|
|
668
|
+
return await (await resolveViewHandle(String(params.viewId))).refresh();
|
|
606
669
|
case "views.page":
|
|
607
|
-
return await (await resolveViewHandle(String(params.
|
|
670
|
+
return await (await resolveViewHandle(String(params.viewId))).page(
|
|
608
671
|
params.request
|
|
609
672
|
);
|
|
610
673
|
case "views.expansion.get":
|
|
611
|
-
return await (await resolveViewHandle(String(params.
|
|
674
|
+
return await (await resolveViewHandle(String(params.viewId))).getExpansionState();
|
|
612
675
|
case "views.expansion.set":
|
|
613
|
-
return await (await resolveViewHandle(String(params.
|
|
676
|
+
return await (await resolveViewHandle(String(params.viewId))).setExpansionState(
|
|
614
677
|
params.expansion
|
|
615
678
|
);
|
|
616
679
|
case "views.expansion.expand":
|
|
617
|
-
return await (await resolveViewHandle(String(params.
|
|
680
|
+
return await (await resolveViewHandle(String(params.viewId))).expand(String(params.rowKey));
|
|
618
681
|
case "views.expansion.collapse":
|
|
619
|
-
return await (await resolveViewHandle(String(params.
|
|
682
|
+
return await (await resolveViewHandle(String(params.viewId))).collapse(String(params.rowKey));
|
|
620
683
|
case "views.expansion.expandAll":
|
|
621
|
-
return await (await resolveViewHandle(String(params.
|
|
684
|
+
return await (await resolveViewHandle(String(params.viewId))).expandAll();
|
|
622
685
|
case "views.expansion.collapseAll":
|
|
623
|
-
return await (await resolveViewHandle(String(params.
|
|
686
|
+
return await (await resolveViewHandle(String(params.viewId))).collapseAll();
|
|
624
687
|
case "views.row.get":
|
|
625
|
-
return await (await resolveViewHandle(String(params.
|
|
688
|
+
return await (await resolveViewHandle(String(params.viewId))).getRow(String(params.rowKey));
|
|
626
689
|
case "views.category.get":
|
|
627
|
-
return await (await resolveViewHandle(String(params.
|
|
690
|
+
return await (await resolveViewHandle(String(params.viewId))).getCategory(
|
|
628
691
|
params.lookup
|
|
629
692
|
);
|
|
630
693
|
case "views.category.page":
|
|
631
|
-
return await (await resolveViewHandle(String(params.
|
|
694
|
+
return await (await resolveViewHandle(String(params.viewId))).pageCategory(
|
|
632
695
|
String(params.categoryKey),
|
|
633
696
|
params.request
|
|
634
697
|
);
|
|
635
698
|
case "views.category.documentIds":
|
|
636
|
-
return await (await resolveViewHandle(String(params.
|
|
699
|
+
return await (await resolveViewHandle(String(params.viewId))).listCategoryDocumentIds(
|
|
637
700
|
String(params.categoryKey)
|
|
638
701
|
);
|
|
639
702
|
case "views.dispose": {
|
|
640
|
-
const key =
|
|
641
|
-
const handle = await resolveViewHandle(String(params.
|
|
703
|
+
const key = String(params.viewId);
|
|
704
|
+
const handle = await resolveViewHandle(String(params.viewId));
|
|
642
705
|
await handle.dispose();
|
|
643
706
|
viewSessions.delete(key);
|
|
644
707
|
return void 0;
|
|
@@ -109,6 +109,7 @@ interface MindooDBAppLaunchContext {
|
|
|
109
109
|
username: string;
|
|
110
110
|
};
|
|
111
111
|
launchParameters: Record<string, string>;
|
|
112
|
+
databases: MindooDBAppDatabaseInfo[];
|
|
112
113
|
views: MindooDBAppResolvedViewDefinition[];
|
|
113
114
|
}
|
|
114
115
|
/** Attachment metadata returned by the attachment APIs. */
|
|
@@ -118,6 +119,13 @@ interface MindooDBAppAttachmentInfo {
|
|
|
118
119
|
mimeType: string;
|
|
119
120
|
size: number;
|
|
120
121
|
}
|
|
122
|
+
/** Preview modes supported by the Haven-hosted attachment preview dialog. */
|
|
123
|
+
type MindooDBAppAttachmentPreviewMode = "image" | "pdf" | "text" | "docx" | "pptx" | "spreadsheet" | "video" | "audio";
|
|
124
|
+
/** Optional parameters for opening an attachment preview in Haven. */
|
|
125
|
+
interface MindooDBAppAttachmentPreviewOptions {
|
|
126
|
+
/** Historical snapshot timestamp previously obtained from `documents.history.getAtTimestamp()`. */
|
|
127
|
+
timestamp?: number;
|
|
128
|
+
}
|
|
121
129
|
/** Database entry visible to the app during launch and database listing. */
|
|
122
130
|
interface MindooDBAppDatabaseInfo {
|
|
123
131
|
id: string;
|
|
@@ -334,10 +342,10 @@ interface MindooDBAppViewHandle {
|
|
|
334
342
|
listCategoryDocumentIds(categoryKey: string): Promise<string[]>;
|
|
335
343
|
dispose(): Promise<void>;
|
|
336
344
|
}
|
|
337
|
-
/**
|
|
338
|
-
interface
|
|
339
|
-
|
|
340
|
-
|
|
345
|
+
/** Payload used when creating one dynamic view inside the current app session. */
|
|
346
|
+
interface MindooDBAppCreateViewInput {
|
|
347
|
+
databaseId: string;
|
|
348
|
+
definition: MindooDBAppViewDefinition;
|
|
341
349
|
}
|
|
342
350
|
/** Attachment operations exposed by an opened database handle. */
|
|
343
351
|
interface MindooDBAppAttachmentApi {
|
|
@@ -347,12 +355,14 @@ interface MindooDBAppAttachmentApi {
|
|
|
347
355
|
}>;
|
|
348
356
|
openReadStream(docId: string, attachmentName: string): Promise<MindooDBAppReadableAttachmentStream>;
|
|
349
357
|
openWriteStream(docId: string, attachmentName: string, contentType?: string): Promise<MindooDBAppWritableAttachmentStream>;
|
|
358
|
+
openPreview(docId: string, attachmentName: string, options?: MindooDBAppAttachmentPreviewOptions): Promise<{
|
|
359
|
+
ok: true;
|
|
360
|
+
}>;
|
|
350
361
|
}
|
|
351
362
|
/** Database handle returned from `session.openDatabase()`. */
|
|
352
363
|
interface MindooDBAppDatabase {
|
|
353
364
|
info(): Promise<MindooDBAppDatabaseInfo>;
|
|
354
365
|
documents: MindooDBAppDocumentApi;
|
|
355
|
-
views: MindooDBAppViewApi;
|
|
356
366
|
attachments: MindooDBAppAttachmentApi;
|
|
357
367
|
}
|
|
358
368
|
/** Connected session between the running app and the Administrator host. */
|
|
@@ -360,6 +370,8 @@ interface MindooDBAppSession {
|
|
|
360
370
|
getLaunchContext(): Promise<MindooDBAppLaunchContext>;
|
|
361
371
|
listDatabases(): Promise<MindooDBAppDatabaseInfo[]>;
|
|
362
372
|
openDatabase(databaseId: string): Promise<MindooDBAppDatabase>;
|
|
373
|
+
createView(input: MindooDBAppCreateViewInput): Promise<MindooDBAppViewHandle>;
|
|
374
|
+
openView(viewId: string): Promise<MindooDBAppViewHandle>;
|
|
363
375
|
onThemeChange(listener: (theme: MindooDBAppHostTheme) => void): () => void;
|
|
364
376
|
onViewportChange(listener: (viewport: MindooDBAppViewport) => void): () => void;
|
|
365
377
|
disconnect(): Promise<void>;
|
|
@@ -369,4 +381,4 @@ interface MindooDBAppBridge {
|
|
|
369
381
|
connect(options?: MindooDBAppBridgeConnectOptions): Promise<MindooDBAppSession>;
|
|
370
382
|
}
|
|
371
383
|
|
|
372
|
-
export type {
|
|
384
|
+
export type { MindooDBAppHostTheme as $, MindooDBAppConfiguredViewColumn as A, MindooDBAppConfiguredViewColumnRole as B, MindooDBAppConfiguredViewExpressionMode as C, MindooDBAppConfiguredViewFieldExpression as D, MindooDBAppConfiguredViewFilterDefinition as E, MindooDBAppConfiguredViewFilterMode as F, MindooDBAppConfiguredViewFilterRule as G, MindooDBAppConfiguredViewFormulaExpression as H, MindooDBAppConfiguredViewFormulaFilterDefinition as I, MindooDBAppConfiguredViewPreviewMode as J, MindooDBAppConfiguredViewRuleFilterDefinition as K, MindooDBAppConfiguredViewRuleMatchMode as L, MindooDBAppAttachmentPreviewMode as M, MindooDBAppConfiguredViewRuleOperator as N, MindooDBAppConfiguredViewValueExpression as O, MindooDBAppCreateDocumentInput as P, MindooDBAppCreateViewInput as Q, MindooDBAppDatabase as R, MindooDBAppDatabaseInfo as S, MindooDBAppDocument as T, MindooDBAppDocumentApi as U, MindooDBAppDocumentHistoryEntry as V, MindooDBAppDocumentListQuery as W, MindooDBAppDocumentListResult as X, MindooDBAppDocumentSummary as Y, MindooDBAppHistoricalDocument as Z, MindooDBAppHistoryQuery as _, MindooDBAppBridge as a, MindooDBAppLaunchContext as a0, MindooDBAppReadableAttachmentStream as a1, MindooDBAppResolvedViewDefinition as a2, MindooDBAppResolvedViewSource as a3, MindooDBAppRuntime as a4, MindooDBAppSession as a5, MindooDBAppThemeMode as a6, MindooDBAppUpdateDocumentInput as a7, MindooDBAppViewHandle as a8, MindooDBAppViewport as a9, MindooDBAppWritableAttachmentStream as aa, MindooDBAppAttachmentApi as b, MindooDBAppAttachmentChunk as c, MindooDBAppAttachmentInfo as d, MindooDBAppAttachmentPreviewOptions as e, MindooDBAppBridgeConnectMessage as f, MindooDBAppBridgeConnectOptions as g, MindooDBAppBridgeConnectedMessage as h, MindooDBAppBridgeErrorPayload as i, MindooDBAppBridgePortMessage as j, MindooDBAppBridgeRpcError as k, MindooDBAppBridgeRpcMessage as l, MindooDBAppBridgeRpcRequest as m, MindooDBAppBridgeRpcSuccess as n, MindooDBAppBridgeStreamAbortRequest as o, MindooDBAppBridgeStreamAck as p, MindooDBAppBridgeStreamCloseRequest as q, MindooDBAppBridgeStreamError as r, MindooDBAppBridgeStreamMessage as s, MindooDBAppBridgeStreamOpenResult as t, MindooDBAppBridgeStreamReadRequest as u, MindooDBAppBridgeStreamWriteRequest as v, MindooDBAppBridgeThemeChangedMessage as w, MindooDBAppBridgeViewportChangedMessage as x, MindooDBAppCapability as y, MindooDBAppConfiguredViewCategorizationStyle as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindoodb-app-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "MindooDB app SDK for building apps that connect to the Haven host bridge",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "Mindoo GmbH",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"prepublishOnly": "npm run build && npm run test"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"mindoodb-view-language": "
|
|
43
|
+
"mindoodb-view-language": "file:../mindoodb-view-language"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^25.5.0",
|