mindoodb-app-sdk 0.0.51 → 0.0.54
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 +63 -55
- package/TESTING.md +57 -0
- package/dist/{chunk-R76XXRJ6.js → chunk-6NTVTL6G.js} +1 -1
- package/dist/index.d.ts +132 -3
- package/dist/index.js +655 -17
- package/dist/testing/index.d.ts +97 -2
- package/dist/testing/index.js +412 -141
- package/dist/{types-BLyV6Ejy.d.ts → types-CX-o1Xyq.d.ts} +53 -1
- package/dist/vite/index.d.ts +18 -5
- package/dist/vite/index.js +156 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -22,26 +22,17 @@ A **MindooDB App** is any web application that uses this SDK to communicate with
|
|
|
22
22
|
|
|
23
23
|
## Architecture
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
│ │ │
|
|
37
|
-
│ ┌─────────────────────────┼─────────────────────────┐ │
|
|
38
|
-
│ │ Your App (sandboxed iframe / window) │ │
|
|
39
|
-
│ │ │ │ │
|
|
40
|
-
│ │ ┌──────────▼──────────┐ │ │
|
|
41
|
-
│ │ │ mindoodb-app-sdk │ │ │
|
|
42
|
-
│ │ └─────────────────────┘ │ │
|
|
43
|
-
│ └───────────────────────────────────────────────────┘ │
|
|
44
|
-
└─────────────────────────────────────────────────────────┘
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart TB
|
|
27
|
+
subgraph haven["Haven (browser tab)"]
|
|
28
|
+
direction TB
|
|
29
|
+
ui["Haven UI<br/>(theme, viewport)"] --> bridge["Bridge Host<br/>(RPC + streams)"]
|
|
30
|
+
bridge --> db["MindooDB<br/>(encrypted databases)"]
|
|
31
|
+
subgraph app["Your App (sandboxed iframe / window)"]
|
|
32
|
+
sdk["mindoodb-app-sdk"]
|
|
33
|
+
end
|
|
34
|
+
bridge -- "postMessage + MessagePort" --> sdk
|
|
35
|
+
end
|
|
45
36
|
```
|
|
46
37
|
|
|
47
38
|
The bridge carries RPC calls (documents, views, database info), binary attachment streams, and push events (theme changes, viewport resizes) over a single `MessagePort`.
|
|
@@ -757,23 +748,11 @@ Two layers are available:
|
|
|
757
748
|
|
|
758
749
|
The end-to-end flow is the same in both cases:
|
|
759
750
|
|
|
760
|
-
```
|
|
761
|
-
|
|
762
|
-
edit
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
│ text: [{ path, baseHeads, edits }]
|
|
766
|
-
│ })
|
|
767
|
-
▼
|
|
768
|
-
┌────────────────────────────────────────────────────┐
|
|
769
|
-
│ Haven applies edits at `baseHeads` and merges with │
|
|
770
|
-
│ concurrent changes via Automerge │
|
|
771
|
-
└─────────────────────────┬──────────────────────────┘
|
|
772
|
-
│ canonical merged document
|
|
773
|
-
▼
|
|
774
|
-
┌────────────────────────────────────────────────────┐
|
|
775
|
-
│ App reconciles its editor with the canonical text │
|
|
776
|
-
└────────────────────────────────────────────────────┘
|
|
751
|
+
```mermaid
|
|
752
|
+
flowchart TB
|
|
753
|
+
edit(["edit"]) --> buffer["App buffer<br/>(local string + pending splices)"]
|
|
754
|
+
buffer -- "flush: documents.update({ text: [{ path, baseHeads, edits }] })" --> merge["Haven applies edits at baseHeads<br/>and merges with concurrent changes via Automerge"]
|
|
755
|
+
merge -- "canonical merged document" --> reconcile["App reconciles its editor<br/>with the canonical text"]
|
|
777
756
|
```
|
|
778
757
|
|
|
779
758
|
#### Text patch shape
|
|
@@ -1003,24 +982,14 @@ If you must use binary sync, Haven decrypts the canonical document, merges incom
|
|
|
1003
982
|
|
|
1004
983
|
Typical flow:
|
|
1005
984
|
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
|
-
open
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
▼
|
|
1015
|
-
┌────────────────────────────────────────────────────┐
|
|
1016
|
-
save ──► │ applyAutomergeChanges({ baseHeads, replicaHeads, │
|
|
1017
|
-
│ changes }) │
|
|
1018
|
-
└─────────────────────────┬──────────────────────────┘
|
|
1019
|
-
│ Haven merges + persists
|
|
1020
|
-
▼
|
|
1021
|
-
┌────────────────────────────────────────────────────┐
|
|
1022
|
-
│ Apply result.changesSince locally (or skip if empty) │
|
|
1023
|
-
└────────────────────────────────────────────────────┘
|
|
985
|
+
```mermaid
|
|
986
|
+
flowchart TB
|
|
987
|
+
open(["open"]) --> snapshot["getAutomergeSnapshot<br/>→ load local replica"]
|
|
988
|
+
snapshot --> local["Local Automerge doc<br/>(or span edits applied locally)"]
|
|
989
|
+
editStep(["edit"]) --> local
|
|
990
|
+
local -- "getChangesSince(baseHeads)" --> apply["applyAutomergeChanges({<br/>baseHeads, replicaHeads, changes })"]
|
|
991
|
+
saveStep(["save"]) --> apply
|
|
992
|
+
apply -- "Haven merges + persists" --> result["Apply result.changesSince locally<br/>(or skip if empty)"]
|
|
1024
993
|
```
|
|
1025
994
|
|
|
1026
995
|
Bridge RPCs: `documents.automerge.getSnapshot` and `documents.automerge.applyChanges`.
|
|
@@ -1679,6 +1648,45 @@ wrangler deploy
|
|
|
1679
1648
|
|
|
1680
1649
|
Other static hosting options work just as well: Netlify, Vercel, any web server serving your `dist/` folder.
|
|
1681
1650
|
|
|
1651
|
+
### Sharing an app by its URL
|
|
1652
|
+
|
|
1653
|
+
Anyone who opens your app's address directly — not from inside Haven — has no host to talk to. Instead of letting the bridge handshake time out into an error, branch on `isLaunchedByHaven()` before mounting and show a landing page:
|
|
1654
|
+
|
|
1655
|
+
```ts
|
|
1656
|
+
import { isLaunchedByHaven, renderHavenAppLandingPage } from "mindoodb-app-sdk";
|
|
1657
|
+
|
|
1658
|
+
if (isLaunchedByHaven()) {
|
|
1659
|
+
createApp(App).mount("#app");
|
|
1660
|
+
} else {
|
|
1661
|
+
void renderHavenAppLandingPage();
|
|
1662
|
+
}
|
|
1663
|
+
```
|
|
1664
|
+
|
|
1665
|
+
Haven puts `mindoodbAppLaunchId` into every launch URL, so the check is synchronous. `renderHavenAppLandingPage()` reads `haven-app.json` from the same origin and shows the app's name, summary, description and screenshots, plus a button to `https://haven.mindoodb.com/?app=<your app URL>` (pass `havenUrl` for another Haven instance). Haven then walks a new user through setup with your app installed at the end, or offers an existing user to add it.
|
|
1666
|
+
|
|
1667
|
+
What the page shows comes from the optional `listing` in `haven-app.json`. Haven's setup wizard shows the same fields:
|
|
1668
|
+
|
|
1669
|
+
```json
|
|
1670
|
+
{
|
|
1671
|
+
"listing": {
|
|
1672
|
+
"summary": { "en": "Plan trips together.", "de": "Reisen gemeinsam planen." },
|
|
1673
|
+
"description": { "en": "First paragraph.\n\nSecond paragraph." },
|
|
1674
|
+
"descriptionMarkdown": { "en": "**Plan** together.\n\n- Shared board\n- [Website](https://trips.example.com)" },
|
|
1675
|
+
"icon": "icon.svg",
|
|
1676
|
+
"screenshots": [{ "file": "screenshots/board.webp", "caption": { "en": "The trip board" } }],
|
|
1677
|
+
"publisher": { "name": "Mindoo GmbH", "url": "https://mindoo.de" }
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
```
|
|
1681
|
+
|
|
1682
|
+
Texts are a string or a per-locale map with an `en` fallback. Image paths are relative to the app origin or absolute `https:` URLs. The listing is display-only and grants nothing.
|
|
1683
|
+
|
|
1684
|
+
Opening the app URL directly also puts share tags into `index.html` (`twitter:card` = `summary`, plus the Open Graph tags other apps read), with the app icon as the image. A production build takes the absolute URL from `publicUrl` in `haven-app.json`. `vite dev` uses the dev server's own origin instead, so `http://127.0.0.1:<port>/` previews against itself. Crawlers do not run the landing page's JavaScript, which is why the tags are in the HTML file.
|
|
1685
|
+
|
|
1686
|
+
`description` is plain text. `descriptionMarkdown` is the same text with formatting, in a small Markdown subset: paragraphs, headings, bullet and numbered lists, `**bold**`, `_italic_`, `` `code` ``, `[text](https://…)`, `[text](mailto:…)` and bare `https://…` links. Links to any other scheme render as plain text. Readers that know `descriptionMarkdown` show it instead of `description`; older Haven versions ignore it, so set both if they matter. `listingMarkdownToPlainText()` derives the plain version. A publisher `url` (`https:` only) turns the publisher name into a link.
|
|
1687
|
+
|
|
1688
|
+
For automated and manual tests use a separate test URL that frames the app with a mock host instead — see "Browser test host" in [`TESTING.md`](./TESTING.md). End users never see that page, and they never see mock data.
|
|
1689
|
+
|
|
1682
1690
|
### Haven-hosted bundles
|
|
1683
1691
|
|
|
1684
1692
|
Instead of Haven loading your app from your server on every launch, you can hand Haven the build itself. Haven stores it in its own cache and serves it from a service worker on an opaque origin, so the app loads offline and runs in a stricter sandbox than an external URL gets.
|
package/TESTING.md
CHANGED
|
@@ -219,6 +219,30 @@ expect(result.rows[0].includes?.customer?.fields.name).toBe("Acme");
|
|
|
219
219
|
An include slot naming a database that was not seeded fails, the same way Haven
|
|
220
220
|
rejects a database the app is not mapped to.
|
|
221
221
|
|
|
222
|
+
### Host focus and notifications
|
|
223
|
+
|
|
224
|
+
A mock launch starts without host focus. `session.requestHostFocus()` sets it
|
|
225
|
+
and fires `onHostFocusChange` listeners; `mock.emitHostFocusChange(focused)`
|
|
226
|
+
simulates Haven moving focus to or away from the launch, so you can test code
|
|
227
|
+
that only notifies while the user is looking elsewhere. `session.notify()` shows
|
|
228
|
+
nothing and resolves with the passed `id`, or a fresh one when `id` is omitted:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const mock = createMockMindooDBAppSession();
|
|
232
|
+
|
|
233
|
+
const seen: boolean[] = [];
|
|
234
|
+
const stop = mock.session.onHostFocusChange((focused) => seen.push(focused));
|
|
235
|
+
|
|
236
|
+
await mock.session.requestHostFocus();
|
|
237
|
+
mock.emitHostFocusChange(false);
|
|
238
|
+
expect(await mock.session.hasHostFocus()).toBe(false);
|
|
239
|
+
expect(seen).toEqual([true, false]);
|
|
240
|
+
stop();
|
|
241
|
+
|
|
242
|
+
const { id } = await mock.session.notify({ id: "sync", severity: "info", text: "Sync finished" });
|
|
243
|
+
expect(id).toBe("sync");
|
|
244
|
+
```
|
|
245
|
+
|
|
222
246
|
## Level 2 example
|
|
223
247
|
|
|
224
248
|
This pattern keeps the real `createMindooDBAppBridge()` code path and replaces only the host side.
|
|
@@ -288,12 +312,45 @@ Useful Level 2 methods:
|
|
|
288
312
|
- `emitViewportChange()`
|
|
289
313
|
- `emitQueryResult()` — push a `query-result` message to live query subscribers
|
|
290
314
|
- `emitViewChanged()` — push a `view-changed` message to navigator `onDidUpdate` listeners
|
|
315
|
+
- `emitHostFocusChange()` — set host focus and push a `host-focus-changed` message to `session.onHostFocusChange()` listeners
|
|
291
316
|
- `setRequestHandler()`
|
|
292
317
|
- `clearRequestHandler()`
|
|
293
318
|
- `postPortMessage()`
|
|
294
319
|
|
|
295
320
|
The built-in request handling also covers `documents.query` and the `documents.liveQuery.*` RPCs against the seeded documents, so `db.documents.query()` / `db.documents.liveQuery()` and `navigator.onDidUpdate()` work end-to-end over the real bridge transport in Level 2 tests.
|
|
296
321
|
|
|
322
|
+
## Browser test host
|
|
323
|
+
|
|
324
|
+
Level 1 and 2 run in Node/jsdom. To run the real app in a real browser — for Playwright, or to click through it yourself — mount the browser test host on a separate page. It frames the app exactly as Haven does (an iframe with `?mindoodbAppLaunchId=…`) and answers the bridge with the same mock state as the Vitest helpers:
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
// src/testHost/main.ts, loaded by /__haven-test/index.html
|
|
328
|
+
import { mockDatabasesFromDefinition, mountHavenTestHost } from "mindoodb-app-sdk/testing";
|
|
329
|
+
import definition from "../../public/haven-app.json";
|
|
330
|
+
|
|
331
|
+
mountHavenTestHost({
|
|
332
|
+
appUrl: "/",
|
|
333
|
+
title: definition.label,
|
|
334
|
+
databases: mockDatabasesFromDefinition(definition, {
|
|
335
|
+
main: [{ id: "welcome", data: { type: "note", title: "Seeded note" } }],
|
|
336
|
+
}),
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
The page shows the app next to a control panel: theme and host-focus toggles, a file picker that decides what the app's next `attachments.scan()` returns (none means the user cancelled), and a live log of notifications, attachment previews, scans and every RPC request. The same controls are scriptable as `window.__havenTestHost`:
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
await page.goto("/__haven-test/");
|
|
344
|
+
const app = page.frameLocator('[data-testid="haven-test-app-frame"]');
|
|
345
|
+
await page.evaluate(() => window.__havenTestHost!.setNextScan({ fileName: "receipt.pdf", mimeType: "application/pdf", size: 1024 }));
|
|
346
|
+
await app.getByRole("button", { name: "Scan" }).click();
|
|
347
|
+
expect(await page.evaluate(() => window.__havenTestHost!.log.scans)).toHaveLength(1);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Lower-level pieces, if you build your own page: `createBrowserTestHost({ frame, appUrl, ...mockOptions })` wires one iframe to a fake host, and `host.acceptConnection(message, ports)` answers a handshake you received yourself.
|
|
351
|
+
|
|
352
|
+
Keep the test page out of production builds. The starter template builds it only for `vite dev` and when `HAVEN_TEST_HOST=1` is set (for preview deployments), so the app's public URL keeps showing its landing page.
|
|
353
|
+
|
|
297
354
|
## When to use which level
|
|
298
355
|
|
|
299
356
|
Choose Level 1 when:
|
|
@@ -494,7 +494,7 @@ function applyHostedDocumentOverscrollContain(doc = globalThis.document) {
|
|
|
494
494
|
if (!doc?.documentElement) {
|
|
495
495
|
return;
|
|
496
496
|
}
|
|
497
|
-
doc.documentElement.style.overscrollBehavior = "
|
|
497
|
+
doc.documentElement.style.overscrollBehavior = "none";
|
|
498
498
|
if (doc.body) {
|
|
499
499
|
doc.body.style.overscrollBehavior = "contain";
|
|
500
500
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MindooDBAppAttachmentPreviewMode, a as MindooDBAppDragBindSourceOptions, b as MindooDBAppDragStartInput, c as MindooDBAppDragStartResult, d as MindooDBAppDragPreview, e as MindooDBAppBridge, f as MindooDBAppHostShortcutBinding, g as MindooDBAppHostShortcutAction, h as MindooDBAppHostingMode, i as
|
|
2
|
-
export {
|
|
1
|
+
import { M as MindooDBAppAttachmentPreviewMode, a as MindooDBAppDragBindSourceOptions, b as MindooDBAppDragStartInput, c as MindooDBAppDragStartResult, d as MindooDBAppDragPreview, e as MindooDBAppBridge, f as MindooDBAppHostShortcutBinding, g as MindooDBAppHostShortcutAction, h as MindooDBAppHostingMode, i as MindooDBAppDefinition, j as MindooDBAppDatabase, k as MindooDBAppDocument, l as MindooDBAppRichTextSpan, m as MindooDBAppRichTextSnapshot, n as MindooDBAppCreateDocumentInput } from './types-CX-o1Xyq.js';
|
|
2
|
+
export { o as MINDOODB_APP_DEFINITION_FILE_NAME, p as MINDOODB_APP_DEFINITION_FORMAT, q as MINDOODB_APP_DEFINITION_PERMISSIONS, r as MINDOODB_APP_DEFINITION_REGISTRATION_PERMISSIONS, s as MINDOODB_APP_DEFINITION_VERSION, t as MINDOODB_APP_LISTING_DESCRIPTION_MAX, u as MINDOODB_APP_LISTING_MAX_SCREENSHOTS, v as MINDOODB_APP_LISTING_SUMMARY_MAX, w as MINDOODB_APP_SEAL_SIGNING_DOMAIN, x as MINDOODB_APP_WELL_KNOWN_DRAG_TYPES, y as MindooDBAppAccessDecision, z as MindooDBAppAccessTier, A as MindooDBAppAttachmentApi, B as MindooDBAppAttachmentChunk, C as MindooDBAppAttachmentInfo, D as MindooDBAppAttachmentPreviewOptions, E as MindooDBAppAttachmentPreviewSession, F as MindooDBAppAutomergeChangesPatch, G as MindooDBAppAutomergeChangesSince, H as MindooDBAppAutomergeGetOptions, I as MindooDBAppAutomergePatchResult, J as MindooDBAppAutomergeSnapshot, K as MindooDBAppBridgeBeforeCloseAck, L as MindooDBAppBridgeBeforeCloseMessage, N as MindooDBAppBridgeConnectMessage, O as MindooDBAppBridgeConnectOptions, P as MindooDBAppBridgeConnectedMessage, Q as MindooDBAppBridgeDragDropMessage, R as MindooDBAppBridgeDragLeaveMessage, S as MindooDBAppBridgeDragOverMessage, T as MindooDBAppBridgeErrorPayload, U as MindooDBAppBridgeHandshakeErrorMessage, V as MindooDBAppBridgeHostFocusChangedMessage, W as MindooDBAppBridgeLocaleChangedMessage, X as MindooDBAppBridgePortMessage, Y as MindooDBAppBridgeQueryResultMessage, Z as MindooDBAppBridgeRpcError, _ as MindooDBAppBridgeRpcMessage, $ as MindooDBAppBridgeRpcRequest, a0 as MindooDBAppBridgeRpcSuccess, a1 as MindooDBAppBridgeShortcutInvokedMessage, a2 as MindooDBAppBridgeShortcutsChangedMessage, a3 as MindooDBAppBridgeStreamAbortRequest, a4 as MindooDBAppBridgeStreamAck, a5 as MindooDBAppBridgeStreamCloseRequest, a6 as MindooDBAppBridgeStreamError, a7 as MindooDBAppBridgeStreamMessage, a8 as MindooDBAppBridgeStreamOpenResult, a9 as MindooDBAppBridgeStreamReadRequest, aa as MindooDBAppBridgeStreamWriteRequest, ab as MindooDBAppBridgeThemeChangedMessage, ac as MindooDBAppBridgeUiPreferencesChangedMessage, ad as MindooDBAppBridgeViewChangedMessage, ae as MindooDBAppBridgeViewportChangedMessage, af as MindooDBAppBridgeWorkspaceFocusRequestedMessage, ag as MindooDBAppCapability, ah as MindooDBAppConfiguredViewCategorizationStyle, ai as MindooDBAppConfiguredViewColumn, aj as MindooDBAppConfiguredViewColumnRole, ak as MindooDBAppConfiguredViewExpressionMode, al as MindooDBAppConfiguredViewFieldExpression, am as MindooDBAppConfiguredViewFilterDefinition, an as MindooDBAppConfiguredViewFilterMode, ao as MindooDBAppConfiguredViewFilterRule, ap as MindooDBAppConfiguredViewFormulaExpression, aq as MindooDBAppConfiguredViewFormulaFilterDefinition, ar as MindooDBAppConfiguredViewPreviewMode, as as MindooDBAppConfiguredViewRuleFilterDefinition, at as MindooDBAppConfiguredViewRuleMatchMode, au as MindooDBAppConfiguredViewRuleOperator, av as MindooDBAppConfiguredViewValueExpression, aw as MindooDBAppCreateKeyInfo, ax as MindooDBAppCreateViewInput, ay as MindooDBAppCreateViewNavigatorInput, az as MindooDBAppDatabaseInfo, aA as MindooDBAppDefinitionDatabase, aB as MindooDBAppDefinitionListing, aC as MindooDBAppDefinitionPermission, aD as MindooDBAppDefinitionRegistrationPermission, aE as MindooDBAppDefinitionScreenshot, aF as MindooDBAppDefinitionValidation, aG as MindooDBAppDirectoryApi, aH as MindooDBAppDirectoryEntry, aI as MindooDBAppDocumentApi, aJ as MindooDBAppDocumentHeadCursorResult, aK as MindooDBAppDocumentHistoryEntry, aL as MindooDBAppDocumentListQuery, aM as MindooDBAppDocumentListResult, aN as MindooDBAppDocumentQuery, aO as MindooDBAppDocumentRevisionId, aP as MindooDBAppDocumentScanPreset, aQ as MindooDBAppDocumentSummary, aR as MindooDBAppDragApi, aS as MindooDBAppDragCancelReason, aT as MindooDBAppDragDropEvent, aU as MindooDBAppDragEffect, aV as MindooDBAppDragHoverResult, aW as MindooDBAppDragOffer, aX as MindooDBAppDragOverEvent, aY as MindooDBAppDragPointer, aZ as MindooDBAppDragProfile, a_ as MindooDBAppEntryAttachmentRef, a$ as MindooDBAppEntryProvenance, b0 as MindooDBAppExtractDocumentTextInput, b1 as MindooDBAppExtractDocumentTextResult, b2 as MindooDBAppExtractTextFormat, b3 as MindooDBAppExtractionSetup, b4 as MindooDBAppFulltextSetup, b5 as MindooDBAppHistoricalDocument, b6 as MindooDBAppHistoryQuery, b7 as MindooDBAppHostTheme, b8 as MindooDBAppIdentityApi, b9 as MindooDBAppInaccessibleDocument, ba as MindooDBAppInaccessibleDocumentListQuery, bb as MindooDBAppInaccessibleDocumentListResult, bc as MindooDBAppJsonCounterIncrementPatch, bd as MindooDBAppJsonListDeletePatch, be as MindooDBAppJsonListInsertPatch, bf as MindooDBAppJsonPatch, bg as MindooDBAppJsonSetPatch, bh as MindooDBAppJsonTextMarkPatch, bi as MindooDBAppJsonTextSplicePatch, bj as MindooDBAppJsonTextUnmarkPatch, bk as MindooDBAppJsonUnsetPatch, bl as MindooDBAppLaunchContext, bm as MindooDBAppLiveQuerySubscription, bn as MindooDBAppLocalizedText, bo as MindooDBAppMenuAnchor, bp as MindooDBAppMenuApi, bq as MindooDBAppMenuCommandItem, br as MindooDBAppMenuDismissReason, bs as MindooDBAppMenuDismissedResult, bt as MindooDBAppMenuItem, bu as MindooDBAppMenuKind, bv as MindooDBAppMenuPlacement, bw as MindooDBAppMenuPointAnchor, bx as MindooDBAppMenuRect, by as MindooDBAppMenuRectAnchor, bz as MindooDBAppMenuSelectionResult, bA as MindooDBAppMenuSeparatorItem, bB as MindooDBAppNotificationSeverity, bC as MindooDBAppNotifyInput, bD as MindooDBAppNotifyResult, bE as MindooDBAppProposeAppInput, bF as MindooDBAppProposeAppResult, bG as MindooDBAppQueryCoverage, bH as MindooDBAppQueryInclude, bI as MindooDBAppQueryIncludeCardinality, bJ as MindooDBAppQueryIncludeSlots, bK as MindooDBAppQueryResult, bL as MindooDBAppQueryRow, bM as MindooDBAppQuerySortKey, bN as MindooDBAppQueryTextClause, bO as MindooDBAppReadableAttachmentStream, bP as MindooDBAppRecipientOptions, bQ as MindooDBAppResolvedViewDefinition, bR as MindooDBAppResolvedViewSource, bS as MindooDBAppRevisionPhase, bT as MindooDBAppRevisionVerification, bU as MindooDBAppRichTextBlockSpan, bV as MindooDBAppRichTextGetOptions, bW as MindooDBAppRichTextImmutableString, bX as MindooDBAppRichTextMarkRange, bY as MindooDBAppRichTextMaterializeValue, bZ as MindooDBAppRichTextPatch, b_ as MindooDBAppRichTextScalar, b$ as MindooDBAppRichTextSpliceStep, c0 as MindooDBAppRichTextStep, c1 as MindooDBAppRichTextStepPatch, c2 as MindooDBAppRichTextTextSpan, c3 as MindooDBAppRuntime, c4 as MindooDBAppScanAttachmentOptions, c5 as MindooDBAppScanAttachmentResult, c6 as MindooDBAppScopedDocId, c7 as MindooDBAppScopedDocumentSummary, c8 as MindooDBAppSealIntent, c9 as MindooDBAppSealedChannelOpenInput, ca as MindooDBAppSealedChannelOpenResult, cb as MindooDBAppSealedChannelRequestInput, cc as MindooDBAppSession, cd as MindooDBAppShowMenuInput, ce as MindooDBAppShowMenuResult, cf as MindooDBAppSignPreview, cg as MindooDBAppSignPreviewScope, ch as MindooDBAppSignStatementInput, ci as MindooDBAppSignStatementResult, cj as MindooDBAppStorageApi, ck as MindooDBAppSummarySetup, cl as MindooDBAppTextCursorOptions, cm as MindooDBAppTextCursorPosition, cn as MindooDBAppTextCursorPositionsResult, co as MindooDBAppTextCursorsResult, cp as MindooDBAppTextEdit, cq as MindooDBAppTextPatch, cr as MindooDBAppThemeMode, cs as MindooDBAppTimestampApi, ct as MindooDBAppTimestampInput, cu as MindooDBAppTimestampProvider, cv as MindooDBAppTimestampResult, cw as MindooDBAppUiPreferences, cx as MindooDBAppUpdateDocumentInput, cy as MindooDBAppViewCursorDocumentListResult, cz as MindooDBAppViewCursorResult, cA as MindooDBAppViewEntry, cB as MindooDBAppViewEntryKind, cC as MindooDBAppViewNavigator, cD as MindooDBAppViewNavigatorExpansionState, cE as MindooDBAppViewNavigatorOpenOptions, cF as MindooDBAppViewNavigatorPageOptions, cG as MindooDBAppViewNavigatorPageResult, cH as MindooDBAppViewNavigatorRangeQuery, cI as MindooDBAppViewNavigatorSelectionState, cJ as MindooDBAppViewUpdateStats, cK as MindooDBAppViewport, cL as MindooDBAppWellKnownDragType, cM as MindooDBAppWritableAttachmentStream, cN as resolveMindooDBAppDefinitionUrl, cO as resolveMindooDBAppListingAssetUrl, cP as resolveMindooDBAppLocalizedText, cQ as validateMindooDBAppDefinition } from './types-CX-o1Xyq.js';
|
|
3
3
|
export { M as MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME, a as MINDOODB_APP_BUNDLE_MANIFEST_FILE_NAME, b as MINDOODB_APP_BUNDLE_MANIFEST_FORMAT, c as MINDOODB_APP_BUNDLE_MANIFEST_VERSION, d as MindooDBAppBundleArchive, e as MindooDBAppBundleFileEntry, f as MindooDBAppBundleHash, g as MindooDBAppBundleManifest, h as MindooDBAppBundleManifestValidation, i as buildMindooDBAppBundleContentHashInput, j as isMindooDBAppBundleHash, n as normalizeMindooDBAppBundlePath, v as validateMindooDBAppBundleManifest } from './appBundleManifest-B0xfpaXG.js';
|
|
4
4
|
import { MindooDBAppBooleanExpression } from 'mindoodb-view-language';
|
|
5
5
|
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';
|
|
@@ -186,6 +186,10 @@ declare function sanitizeHostShortcutBindings(value: unknown): MindooDBAppHostSh
|
|
|
186
186
|
/**
|
|
187
187
|
* Stops wheel chaining out of a hosted app document into Haven's workspace
|
|
188
188
|
* scroller once the app page (or its `body`) has reached its end.
|
|
189
|
+
*
|
|
190
|
+
* The root gets `none`, not `contain`: `contain` still lets iOS rubber-band
|
|
191
|
+
* the frame's own root scroller, so a drag on a non-scrollable area (a fixed
|
|
192
|
+
* dialog header, say) slides every fixed overlay in the app with the finger.
|
|
189
193
|
*/
|
|
190
194
|
declare function applyHostedDocumentOverscrollContain(doc?: Document | undefined): void;
|
|
191
195
|
/**
|
|
@@ -203,6 +207,28 @@ declare function installHostShortcutCapture(options: {
|
|
|
203
207
|
* delivered before any asynchronous work has happened.
|
|
204
208
|
*/
|
|
205
209
|
declare const MINDOODB_APP_HOSTING_QUERY_PARAM = "mindoodbAppHosting";
|
|
210
|
+
/**
|
|
211
|
+
* Query parameter Haven appends to every app launch URL. The bridge handshake is keyed
|
|
212
|
+
* on it, so its absence means nobody launched this page.
|
|
213
|
+
*/
|
|
214
|
+
declare const MINDOODB_APP_LAUNCH_ID_QUERY_PARAM = "mindoodbAppLaunchId";
|
|
215
|
+
/**
|
|
216
|
+
* Reads the launch id Haven put into the current URL, or `null` when there is none.
|
|
217
|
+
*
|
|
218
|
+
* @param search Optional query string, defaults to `window.location.search`.
|
|
219
|
+
*/
|
|
220
|
+
declare function readMindooDBAppLaunchId(search?: string): string | null;
|
|
221
|
+
/**
|
|
222
|
+
* True when Haven (or a test host) launched this page, decided synchronously from the URL.
|
|
223
|
+
*
|
|
224
|
+
* Someone who opens the app's address directly — a link in an email, a shared URL — has
|
|
225
|
+
* no host to talk to. Branch on this before calling `connect()` and show a landing page
|
|
226
|
+
* instead (see `renderHavenAppLandingPage`), rather than letting the handshake time out
|
|
227
|
+
* into an error message.
|
|
228
|
+
*
|
|
229
|
+
* @param search Optional query string, defaults to `window.location.search`.
|
|
230
|
+
*/
|
|
231
|
+
declare function isLaunchedByHaven(search?: string): boolean;
|
|
206
232
|
/**
|
|
207
233
|
* Reads the hosting mode synchronously from the current URL.
|
|
208
234
|
*
|
|
@@ -224,6 +250,109 @@ declare function readMindooDBAppHostingMode(search?: string): MindooDBAppHosting
|
|
|
224
250
|
*/
|
|
225
251
|
declare function isHostedBundleRuntime(search?: string): boolean;
|
|
226
252
|
|
|
253
|
+
/**
|
|
254
|
+
* The page an app shows when someone opens its address directly instead of launching it
|
|
255
|
+
* from Haven — a link in an email, a URL the App Builder printed.
|
|
256
|
+
*
|
|
257
|
+
* Without it that person gets a half-rendered app and "could not reach the Haven host".
|
|
258
|
+
* With it they get what the app is, taken from the `listing` in `haven-app.json`, and one
|
|
259
|
+
* button that opens Haven with `?app=<this app's URL>`: Haven then sets up a new
|
|
260
|
+
* environment with the app in it, or adds the app to the one that already exists.
|
|
261
|
+
*
|
|
262
|
+
* Framework-free on purpose: it runs before (and instead of) the app's own UI, so it must
|
|
263
|
+
* not pull the app's bundle into the first paint. Every publisher-supplied string goes in
|
|
264
|
+
* through `textContent`, never as markup.
|
|
265
|
+
*/
|
|
266
|
+
declare const DEFAULT_HAVEN_URL = "https://haven.mindoodb.com";
|
|
267
|
+
interface RenderHavenAppLandingPageOptions {
|
|
268
|
+
/** Haven instance the button opens. Defaults to {@link DEFAULT_HAVEN_URL}. */
|
|
269
|
+
havenUrl?: string;
|
|
270
|
+
/**
|
|
271
|
+
* The app URL Haven installs from. Defaults to the current page without query, hash and
|
|
272
|
+
* a trailing `index.html` — the same URL that serves `haven-app.json`.
|
|
273
|
+
*/
|
|
274
|
+
appUrl?: string;
|
|
275
|
+
/** Skips the fetch of `haven-app.json`, e.g. when the app bundles its definition. */
|
|
276
|
+
definition?: MindooDBAppDefinition;
|
|
277
|
+
/** Element the page renders into. Defaults to `document.body`, which is cleared. */
|
|
278
|
+
container?: HTMLElement;
|
|
279
|
+
/** Defaults to `navigator.language`. The page itself speaks English and German. */
|
|
280
|
+
locale?: string;
|
|
281
|
+
}
|
|
282
|
+
interface HavenAppLandingPage {
|
|
283
|
+
/** The definition shown, or `null` when `haven-app.json` could not be read. */
|
|
284
|
+
definition: MindooDBAppDefinition | null;
|
|
285
|
+
/** The Haven link behind the main button. */
|
|
286
|
+
installUrl: string;
|
|
287
|
+
}
|
|
288
|
+
/** The current page as the app URL: no query, no hash, no trailing `index.html`. */
|
|
289
|
+
declare function resolveCurrentHavenAppUrl(href?: string): string;
|
|
290
|
+
/** `https://haven.mindoodb.com/?app=<appUrl>` — the link that installs `appUrl`. */
|
|
291
|
+
declare function buildHavenAppInstallUrl(appUrl: string, havenUrl?: string): string;
|
|
292
|
+
/**
|
|
293
|
+
* Replaces the page with the app's landing page. Call it instead of mounting the app
|
|
294
|
+
* when {@link isLaunchedByHaven} is `false`.
|
|
295
|
+
*/
|
|
296
|
+
declare function renderHavenAppLandingPage(options?: RenderHavenAppLandingPageOptions): Promise<HavenAppLandingPage>;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* The Markdown subset a publisher may use in `listing.descriptionMarkdown`.
|
|
300
|
+
*
|
|
301
|
+
* The text comes from a file on the publisher's server and is shown before anyone has
|
|
302
|
+
* agreed to install the app, so it is parsed into a small tree here and rendered with
|
|
303
|
+
* `createElement`/`textContent` (or Vue render functions) — never as HTML. What the
|
|
304
|
+
* subset knows:
|
|
305
|
+
*
|
|
306
|
+
* - paragraphs (blank lines), headings (`#`), bullet (`-`, `*`, `+`) and numbered lists
|
|
307
|
+
* - `**bold**`, `__bold__`, `*italic*`, `_italic_`, `` `code` ``, `\` escapes
|
|
308
|
+
* - `[text](https://…)`, `[text](mailto:…)` and bare `https://…` links
|
|
309
|
+
*
|
|
310
|
+
* Anything else stays literal text. Links are limited to `https:` and `mailto:` by
|
|
311
|
+
* {@link sanitizeListingHref}; a link with any other target renders as its text only.
|
|
312
|
+
*
|
|
313
|
+
* DOM-free on purpose, so Haven, the landing page and build scripts can share it.
|
|
314
|
+
*/
|
|
315
|
+
type ListingInline = {
|
|
316
|
+
type: "text";
|
|
317
|
+
text: string;
|
|
318
|
+
} | {
|
|
319
|
+
type: "code";
|
|
320
|
+
text: string;
|
|
321
|
+
} | {
|
|
322
|
+
type: "strong";
|
|
323
|
+
children: ListingInline[];
|
|
324
|
+
} | {
|
|
325
|
+
type: "em";
|
|
326
|
+
children: ListingInline[];
|
|
327
|
+
} | {
|
|
328
|
+
type: "link";
|
|
329
|
+
href: string;
|
|
330
|
+
children: ListingInline[];
|
|
331
|
+
};
|
|
332
|
+
type ListingBlock = {
|
|
333
|
+
type: "paragraph";
|
|
334
|
+
children: ListingInline[];
|
|
335
|
+
} | {
|
|
336
|
+
type: "heading";
|
|
337
|
+
children: ListingInline[];
|
|
338
|
+
} | {
|
|
339
|
+
type: "list";
|
|
340
|
+
ordered: boolean;
|
|
341
|
+
items: ListingInline[][];
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* `https:` and `mailto:` only. Embedded tab/LF/CR are stripped first, as browsers do,
|
|
345
|
+
* so `java\nscript:` cannot slip past the scheme check.
|
|
346
|
+
*/
|
|
347
|
+
declare function sanitizeListingHref(raw: string): string | null;
|
|
348
|
+
/** Parses a description into blocks. Unknown syntax stays text; nothing is dropped. */
|
|
349
|
+
declare function parseListingMarkdown(markdown: string): ListingBlock[];
|
|
350
|
+
/**
|
|
351
|
+
* The same text for readers that only show plain paragraphs (`listing.description`):
|
|
352
|
+
* one paragraph per block and per list item, links as "text (url)".
|
|
353
|
+
*/
|
|
354
|
+
declare function listingMarkdownToPlainText(markdown: string): string;
|
|
355
|
+
|
|
227
356
|
interface InstallHavenStorageShimOptions {
|
|
228
357
|
/**
|
|
229
358
|
* Key prefixes whose values are written through to the host and restored on the next
|
|
@@ -430,4 +559,4 @@ declare function inheritDocumentEncryption(parent: Pick<MindooDBAppDocument, "de
|
|
|
430
559
|
*/
|
|
431
560
|
declare function watchWordChunks(database: MindooDBAppDatabase, parentId: string, listener: (docIds: string[]) => void): Promise<() => Promise<void>>;
|
|
432
561
|
|
|
433
|
-
export { type CreateMindooDBRichTextHandleOptions, type CreateMindooDBTextBufferOptions, DEFAULT_DRAG_LONG_PRESS_MS, DEFAULT_DRAG_POINTER_THRESHOLD_PX, DEFAULT_HAVEN_HOST_SHORTCUTS, type HavenStorageShimHandle, type InstallHavenStorageShimOptions, MINDOODB_APP_HOSTING_QUERY_PARAM, MINDOODB_APP_MAX_DRAG_PAYLOAD_BYTES, MINDOODB_APP_MAX_DRAG_PREVIEW_BYTES, MINDOODB_APP_MAX_DRAG_PREVIEW_EDGE, MINDOODB_APP_MAX_DRAG_TYPES, MINDOODB_APP_VALUE_TAG, MINIMAL_DRAG_PREVIEW_PNG, type MindooDBAppAtomicValue, MindooDBAppAttachmentPreviewMode, MindooDBAppBridge, type MindooDBAppCounterValue, MindooDBAppCreateDocumentInput, MindooDBAppDatabase, MindooDBAppDocument, MindooDBAppDragBindSourceOptions, MindooDBAppDragInputError, MindooDBAppDragPreview, MindooDBAppDragStartInput, MindooDBAppDragStartResult, MindooDBAppHostShortcutAction, MindooDBAppHostShortcutBinding, MindooDBAppHostingMode, MindooDBAppRichTextSnapshot, MindooDBAppRichTextSpan, type MindooDBAppTimestampValue, type MindooDBAppTypedValue, MindooDBAppValue, MindooDBRichTextHandle, type MindooDBRichTextHandleChangeListener, type MindooDBRichTextHandleFlushResult, MindooDBTextBuffer, type MindooDBTextBufferFlushResult, abbreviateCanonicalName, applyHostedDocumentOverscrollContain, bindDragSource, canPreviewAttachment, createMindooDBAppBridge, createMindooDBRichTextHandle, createMindooDBTextBuffer, expandAbbreviatedName, inheritDocumentEncryption, installHavenStorageShim, installHostShortcutCapture, isHostShortcutAction, isHostedBundleRuntime, isMindooDBAppDragType, matchHostShortcut, normalizeDragAccepts, normalizeDragPointerInput, normalizeDragStartInput, queryDocuments, readMindooDBAppHostingMode, releaseMindooDBAppBridgeSessions, sanitizeHostShortcutBindings, snapshotElementToPng, watchWordChunks };
|
|
562
|
+
export { type CreateMindooDBRichTextHandleOptions, type CreateMindooDBTextBufferOptions, DEFAULT_DRAG_LONG_PRESS_MS, DEFAULT_DRAG_POINTER_THRESHOLD_PX, DEFAULT_HAVEN_HOST_SHORTCUTS, DEFAULT_HAVEN_URL, type HavenAppLandingPage, type HavenStorageShimHandle, type InstallHavenStorageShimOptions, type ListingBlock, type ListingInline, MINDOODB_APP_HOSTING_QUERY_PARAM, MINDOODB_APP_LAUNCH_ID_QUERY_PARAM, MINDOODB_APP_MAX_DRAG_PAYLOAD_BYTES, MINDOODB_APP_MAX_DRAG_PREVIEW_BYTES, MINDOODB_APP_MAX_DRAG_PREVIEW_EDGE, MINDOODB_APP_MAX_DRAG_TYPES, MINDOODB_APP_VALUE_TAG, MINIMAL_DRAG_PREVIEW_PNG, type MindooDBAppAtomicValue, MindooDBAppAttachmentPreviewMode, MindooDBAppBridge, type MindooDBAppCounterValue, MindooDBAppCreateDocumentInput, MindooDBAppDatabase, MindooDBAppDefinition, MindooDBAppDocument, MindooDBAppDragBindSourceOptions, MindooDBAppDragInputError, MindooDBAppDragPreview, MindooDBAppDragStartInput, MindooDBAppDragStartResult, MindooDBAppHostShortcutAction, MindooDBAppHostShortcutBinding, MindooDBAppHostingMode, MindooDBAppRichTextSnapshot, MindooDBAppRichTextSpan, type MindooDBAppTimestampValue, type MindooDBAppTypedValue, MindooDBAppValue, MindooDBRichTextHandle, type MindooDBRichTextHandleChangeListener, type MindooDBRichTextHandleFlushResult, MindooDBTextBuffer, type MindooDBTextBufferFlushResult, type RenderHavenAppLandingPageOptions, abbreviateCanonicalName, applyHostedDocumentOverscrollContain, bindDragSource, buildHavenAppInstallUrl, canPreviewAttachment, createMindooDBAppBridge, createMindooDBRichTextHandle, createMindooDBTextBuffer, expandAbbreviatedName, inheritDocumentEncryption, installHavenStorageShim, installHostShortcutCapture, isHostShortcutAction, isHostedBundleRuntime, isLaunchedByHaven, isMindooDBAppDragType, listingMarkdownToPlainText, matchHostShortcut, normalizeDragAccepts, normalizeDragPointerInput, normalizeDragStartInput, parseListingMarkdown, queryDocuments, readMindooDBAppHostingMode, readMindooDBAppLaunchId, releaseMindooDBAppBridgeSessions, renderHavenAppLandingPage, resolveCurrentHavenAppUrl, sanitizeHostShortcutBindings, sanitizeListingHref, snapshotElementToPng, watchWordChunks };
|