mindoodb-app-sdk 0.0.47 → 0.0.48
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 +40 -3
- package/TESTING.md +35 -0
- package/dist/{chunk-D662SK2G.js → chunk-TPYDERAK.js} +18 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +379 -42
- package/dist/{types-C2WDj-Tv.d.ts → types-C-eyC839.d.ts} +108 -7
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1084,6 +1084,43 @@ if (handled) {
|
|
|
1084
1084
|
}
|
|
1085
1085
|
```
|
|
1086
1086
|
|
|
1087
|
+
**Nested lookups (`include`)** fetch related documents alongside the matching rows — from the same database or from any other database the app is mapped to. The host resolves a slot with **one scan per slot**, not one query per row, so a list with its related records is a single round trip:
|
|
1088
|
+
|
|
1089
|
+
```ts
|
|
1090
|
+
const result = await db.documents.query<{
|
|
1091
|
+
customer: MindooDBAppQueryRow | null;
|
|
1092
|
+
lines: MindooDBAppQueryRow[];
|
|
1093
|
+
}>({
|
|
1094
|
+
filter: 'v.eq(v.field("type"), "invoice")',
|
|
1095
|
+
fields: ["total", "customerId"],
|
|
1096
|
+
include: {
|
|
1097
|
+
customer: {
|
|
1098
|
+
databaseId: "customers", // another mapped database; omit for this one
|
|
1099
|
+
cardinality: "one", // → a row or null
|
|
1100
|
+
localKey: "customerId", // this row's field holds the customer's id
|
|
1101
|
+
fields: ["name"],
|
|
1102
|
+
},
|
|
1103
|
+
lines: {
|
|
1104
|
+
cardinality: "many", // → an array (possibly empty, never null)
|
|
1105
|
+
filter: 'v.eq(v.field("invoiceId"), v.parentDocId())',
|
|
1106
|
+
sortBy: [{ field: "position", direction: "ascending" }],
|
|
1107
|
+
limit: 50,
|
|
1108
|
+
},
|
|
1109
|
+
},
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
for (const row of result.rows) {
|
|
1113
|
+
console.log(row.fields.total, row.includes?.customer?.fields.name);
|
|
1114
|
+
console.log(row.includes?.lines.length);
|
|
1115
|
+
}
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
- Related documents live under `row.includes[slot]`, never as sibling keys, so a slot name can never collide with `docId` / `fields` / `lastModified`. Pass the slot types to `query<TIncludes>()` to have them typed.
|
|
1119
|
+
- The join condition relates the related document to the parent row: `v.parentDocId()` for the parent's id, `v.parent("<path>")` for one of its fields. `localKey` is shorthand for "this row's field holds the related document's id" (an array value joins every element). Exactly one such equality is allowed per slot — further conditions may narrow the related documents but must not mention the parent.
|
|
1120
|
+
- Slots nest (`row.includes.customer.includes.address`) up to three levels.
|
|
1121
|
+
- `databaseId` is checked like any other database parameter: the app must be mapped to it with the `read` capability, at every level. Unmapped or view-only ids are rejected with `database-not-found`, a missing capability with `forbidden`.
|
|
1122
|
+
- Hydration happens after sorting and paging, so only the returned rows are joined and `total` stays the unpaged match count. Per-slot `limit` is capped at 1000, and a query may carry at most 10 slots in total.
|
|
1123
|
+
|
|
1087
1124
|
**Live queries** keep a query result up to date. The callback receives the initial result and runs again whenever the result actually changed — the host coalesces bursts of writes and fingerprints results, so you only hear about real changes:
|
|
1088
1125
|
|
|
1089
1126
|
```ts
|
|
@@ -1101,7 +1138,7 @@ await subscription.refresh();
|
|
|
1101
1138
|
await subscription.dispose();
|
|
1102
1139
|
```
|
|
1103
1140
|
|
|
1104
|
-
Live query results are pushed from the host over the bridge port — no polling. Subscriptions are cleaned up automatically when the app disconnects, but dispose them explicitly when the UI that consumes them unmounts.
|
|
1141
|
+
Live query results are pushed from the host over the bridge port — no polling. Subscriptions are cleaned up automatically when the app disconnects, but dispose them explicitly when the UI that consumes them unmounts. A live query with `include` also watches every related database, so a change to a joined document delivers a new result too.
|
|
1105
1142
|
|
|
1106
1143
|
### Incremental sync
|
|
1107
1144
|
|
|
@@ -1638,8 +1675,8 @@ Host-kept key/value state, the only durable storage a hosted app has. See [Stora
|
|
|
1638
1675
|
|
|
1639
1676
|
| Method | Returns |
|
|
1640
1677
|
| ---------------------------------- | -------------------------------------------- |
|
|
1641
|
-
| `query(query?)`
|
|
1642
|
-
| `liveQuery(query, onResult)`
|
|
1678
|
+
| `query<TIncludes>(query?)` | `Promise<MindooDBAppQueryResult<TIncludes>>` |
|
|
1679
|
+
| `liveQuery<TIncludes>(query, onResult)` | `Promise<MindooDBAppLiveQuerySubscription>` |
|
|
1643
1680
|
| `list(query?)` | `Promise<MindooDBAppDocumentListResult>` |
|
|
1644
1681
|
| `listInaccessible(query?)` | `Promise<MindooDBAppInaccessibleDocumentListResult>` |
|
|
1645
1682
|
| `get(docId)` | `Promise<MindooDBAppDocument \| null>` |
|
package/TESTING.md
CHANGED
|
@@ -183,6 +183,41 @@ await db.documents.create({ set: { type: "invoice", total: 50 } });
|
|
|
183
183
|
await sub.dispose();
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
+
Nested lookups (`include`) work too, including slots that name another mocked
|
|
187
|
+
database by its id, and they mirror the host's rules — one parent equality per
|
|
188
|
+
slot, `cardinality: "one"` failing loudly when several documents match, per-slot
|
|
189
|
+
`sortBy`/`limit`, and nesting. A write to a joined database re-fires the live
|
|
190
|
+
queries that join it, so cross-database joins can be tested end to end:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const mock = createMockMindooDBAppBridge({
|
|
194
|
+
databases: [
|
|
195
|
+
{
|
|
196
|
+
info: { id: "billing", title: "Billing", capabilities: ["read", "create"] },
|
|
197
|
+
documents: [{ id: "inv_1", data: { type: "invoice", customerId: "cust_1" } }],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
info: { id: "customers", title: "Customers", capabilities: ["read"] },
|
|
201
|
+
documents: [{ id: "cust_1", data: { name: "Acme" } }],
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const session = await mock.bridge.connect();
|
|
207
|
+
const billing = await session.openDatabase("billing");
|
|
208
|
+
|
|
209
|
+
const result = await billing.documents.query<{ customer: MindooDBAppQueryRow | null }>({
|
|
210
|
+
filter: 'v.eq(v.field("type"), "invoice")',
|
|
211
|
+
include: {
|
|
212
|
+
customer: { databaseId: "customers", cardinality: "one", localKey: "customerId" },
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
expect(result.rows[0].includes?.customer?.fields.name).toBe("Acme");
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
An include slot naming a database that was not seeded fails, the same way Haven
|
|
219
|
+
rejects a database the app is not mapped to.
|
|
220
|
+
|
|
186
221
|
## Level 2 example
|
|
187
222
|
|
|
188
223
|
This pattern keeps the real `createMindooDBAppBridge()` code path and replaces only the host side.
|
|
@@ -658,14 +658,28 @@ function normalizeDocumentQuery(query) {
|
|
|
658
658
|
if (!query) {
|
|
659
659
|
return {};
|
|
660
660
|
}
|
|
661
|
-
const { filter, ...rest } = query;
|
|
661
|
+
const { filter, include, ...rest } = query;
|
|
662
662
|
return {
|
|
663
663
|
...rest,
|
|
664
|
-
...filter !== void 0 ? {
|
|
665
|
-
|
|
666
|
-
} : {}
|
|
664
|
+
...filter !== void 0 ? { filter: normalizeQueryFilter(filter) } : {},
|
|
665
|
+
...include !== void 0 ? { include: normalizeQueryIncludes(include) } : {}
|
|
667
666
|
};
|
|
668
667
|
}
|
|
668
|
+
function normalizeQueryFilter(filter) {
|
|
669
|
+
return typeof filter === "string" ? parseMindooDBFormulaBooleanExpression(filter) : filter;
|
|
670
|
+
}
|
|
671
|
+
function normalizeQueryIncludes(includes) {
|
|
672
|
+
const normalized = {};
|
|
673
|
+
for (const [slot, include] of Object.entries(includes)) {
|
|
674
|
+
const { filter, include: nested, ...rest } = include;
|
|
675
|
+
normalized[slot] = {
|
|
676
|
+
...rest,
|
|
677
|
+
...filter !== void 0 ? { filter: normalizeQueryFilter(filter) } : {},
|
|
678
|
+
...nested !== void 0 ? { include: normalizeQueryIncludes(nested) } : {}
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
return normalized;
|
|
682
|
+
}
|
|
669
683
|
function isThemeChangedMessage(message) {
|
|
670
684
|
return message.kind === "theme-changed";
|
|
671
685
|
}
|
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 MindooDBAppDatabase, j as MindooDBAppDocument, k as MindooDBAppRichTextSpan, l as MindooDBAppRichTextSnapshot } from './types-
|
|
2
|
-
export { m as MINDOODB_APP_DEFINITION_FILE_NAME, n as MINDOODB_APP_DEFINITION_FORMAT, o as MINDOODB_APP_DEFINITION_PERMISSIONS, p as MINDOODB_APP_DEFINITION_REGISTRATION_PERMISSIONS, q as MINDOODB_APP_DEFINITION_VERSION, r as MINDOODB_APP_SEAL_SIGNING_DOMAIN, s as MINDOODB_APP_WELL_KNOWN_DRAG_TYPES, t as MindooDBAppAccessDecision, u as MindooDBAppAccessTier, v as MindooDBAppAttachmentApi, w as MindooDBAppAttachmentChunk, x as MindooDBAppAttachmentInfo, y as MindooDBAppAttachmentPreviewOptions, z as MindooDBAppAttachmentPreviewSession, A as MindooDBAppAutomergeChangesPatch, B as MindooDBAppAutomergeChangesSince, C as MindooDBAppAutomergeGetOptions, D as MindooDBAppAutomergePatchResult, E as MindooDBAppAutomergeSnapshot, F as MindooDBAppBridgeBeforeCloseAck, G as MindooDBAppBridgeBeforeCloseMessage, H as MindooDBAppBridgeConnectMessage, I as MindooDBAppBridgeConnectOptions, J as MindooDBAppBridgeConnectedMessage, K as MindooDBAppBridgeDragDropMessage, L as MindooDBAppBridgeDragLeaveMessage, N as MindooDBAppBridgeDragOverMessage, O as MindooDBAppBridgeErrorPayload, P as MindooDBAppBridgeHandshakeErrorMessage, Q as MindooDBAppBridgeLocaleChangedMessage, R as MindooDBAppBridgePortMessage, S as MindooDBAppBridgeQueryResultMessage, T as MindooDBAppBridgeRpcError, U as MindooDBAppBridgeRpcMessage, V as MindooDBAppBridgeRpcRequest, W as MindooDBAppBridgeRpcSuccess, X as MindooDBAppBridgeShortcutInvokedMessage, Y as MindooDBAppBridgeShortcutsChangedMessage, Z as MindooDBAppBridgeStreamAbortRequest, _ as MindooDBAppBridgeStreamAck, $ as MindooDBAppBridgeStreamCloseRequest, a0 as MindooDBAppBridgeStreamError, a1 as MindooDBAppBridgeStreamMessage, a2 as MindooDBAppBridgeStreamOpenResult, a3 as MindooDBAppBridgeStreamReadRequest, a4 as MindooDBAppBridgeStreamWriteRequest, a5 as MindooDBAppBridgeThemeChangedMessage, a6 as MindooDBAppBridgeUiPreferencesChangedMessage, a7 as MindooDBAppBridgeViewChangedMessage, a8 as MindooDBAppBridgeViewportChangedMessage, a9 as MindooDBAppCapability, aa as MindooDBAppConfiguredViewCategorizationStyle, ab as MindooDBAppConfiguredViewColumn, ac as MindooDBAppConfiguredViewColumnRole, ad as MindooDBAppConfiguredViewExpressionMode, ae as MindooDBAppConfiguredViewFieldExpression, af as MindooDBAppConfiguredViewFilterDefinition, ag as MindooDBAppConfiguredViewFilterMode, ah as MindooDBAppConfiguredViewFilterRule, ai as MindooDBAppConfiguredViewFormulaExpression, aj as MindooDBAppConfiguredViewFormulaFilterDefinition, ak as MindooDBAppConfiguredViewPreviewMode, al as MindooDBAppConfiguredViewRuleFilterDefinition, am as MindooDBAppConfiguredViewRuleMatchMode, an as MindooDBAppConfiguredViewRuleOperator, ao as MindooDBAppConfiguredViewValueExpression, ap as MindooDBAppCreateDocumentInput, aq as MindooDBAppCreateKeyInfo, ar as MindooDBAppCreateViewInput, as as MindooDBAppCreateViewNavigatorInput, at as MindooDBAppDatabaseInfo, au as MindooDBAppDefinition, av as MindooDBAppDefinitionDatabase, aw as MindooDBAppDefinitionPermission, ax as MindooDBAppDefinitionRegistrationPermission, ay as MindooDBAppDefinitionValidation, az as MindooDBAppDirectoryApi, aA as MindooDBAppDirectoryEntry, aB as MindooDBAppDocumentApi, aC as MindooDBAppDocumentHeadCursorResult, aD as MindooDBAppDocumentHistoryEntry, aE as MindooDBAppDocumentListQuery, aF as MindooDBAppDocumentListResult, aG as MindooDBAppDocumentQuery, aH as MindooDBAppDocumentRevisionId, aI as MindooDBAppDocumentScanPreset, aJ as MindooDBAppDocumentSummary, aK as MindooDBAppDragApi, aL as MindooDBAppDragCancelReason, aM as MindooDBAppDragDropEvent, aN as MindooDBAppDragEffect, aO as MindooDBAppDragHoverResult, aP as MindooDBAppDragOffer, aQ as MindooDBAppDragOverEvent, aR as MindooDBAppDragPointer, aS as MindooDBAppDragProfile, aT as MindooDBAppEntryAttachmentRef, aU as MindooDBAppEntryProvenance, aV as MindooDBAppExtractDocumentTextInput, aW as MindooDBAppExtractDocumentTextResult, aX as MindooDBAppExtractTextFormat, aY as MindooDBAppExtractionSetup, aZ as MindooDBAppFulltextSetup, a_ as MindooDBAppHistoricalDocument, a$ as MindooDBAppHistoryQuery, b0 as MindooDBAppHostTheme, b1 as MindooDBAppIdentityApi, b2 as MindooDBAppInaccessibleDocument, b3 as MindooDBAppInaccessibleDocumentListQuery, b4 as MindooDBAppInaccessibleDocumentListResult, b5 as MindooDBAppJsonListDeletePatch, b6 as MindooDBAppJsonListInsertPatch, b7 as MindooDBAppJsonPatch, b8 as MindooDBAppJsonSetPatch, b9 as MindooDBAppJsonTextMarkPatch, ba as MindooDBAppJsonTextSplicePatch, bb as MindooDBAppJsonTextUnmarkPatch, bc as MindooDBAppJsonUnsetPatch, bd as MindooDBAppLaunchContext, be as MindooDBAppLiveQuerySubscription, bf as MindooDBAppMenuAnchor, bg as MindooDBAppMenuApi, bh as MindooDBAppMenuCommandItem, bi as MindooDBAppMenuDismissReason, bj as MindooDBAppMenuDismissedResult, bk as MindooDBAppMenuItem, bl as MindooDBAppMenuKind, bm as MindooDBAppMenuPlacement, bn as MindooDBAppMenuPointAnchor, bo as MindooDBAppMenuRect, bp as MindooDBAppMenuRectAnchor, bq as MindooDBAppMenuSelectionResult, br as MindooDBAppMenuSeparatorItem, bs as MindooDBAppProposeAppInput, bt as MindooDBAppProposeAppResult, bu as MindooDBAppQueryCoverage, bv as
|
|
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 MindooDBAppDatabase, j as MindooDBAppDocument, k as MindooDBAppRichTextSpan, l as MindooDBAppRichTextSnapshot } from './types-C-eyC839.js';
|
|
2
|
+
export { m as MINDOODB_APP_DEFINITION_FILE_NAME, n as MINDOODB_APP_DEFINITION_FORMAT, o as MINDOODB_APP_DEFINITION_PERMISSIONS, p as MINDOODB_APP_DEFINITION_REGISTRATION_PERMISSIONS, q as MINDOODB_APP_DEFINITION_VERSION, r as MINDOODB_APP_SEAL_SIGNING_DOMAIN, s as MINDOODB_APP_WELL_KNOWN_DRAG_TYPES, t as MindooDBAppAccessDecision, u as MindooDBAppAccessTier, v as MindooDBAppAttachmentApi, w as MindooDBAppAttachmentChunk, x as MindooDBAppAttachmentInfo, y as MindooDBAppAttachmentPreviewOptions, z as MindooDBAppAttachmentPreviewSession, A as MindooDBAppAutomergeChangesPatch, B as MindooDBAppAutomergeChangesSince, C as MindooDBAppAutomergeGetOptions, D as MindooDBAppAutomergePatchResult, E as MindooDBAppAutomergeSnapshot, F as MindooDBAppBridgeBeforeCloseAck, G as MindooDBAppBridgeBeforeCloseMessage, H as MindooDBAppBridgeConnectMessage, I as MindooDBAppBridgeConnectOptions, J as MindooDBAppBridgeConnectedMessage, K as MindooDBAppBridgeDragDropMessage, L as MindooDBAppBridgeDragLeaveMessage, N as MindooDBAppBridgeDragOverMessage, O as MindooDBAppBridgeErrorPayload, P as MindooDBAppBridgeHandshakeErrorMessage, Q as MindooDBAppBridgeLocaleChangedMessage, R as MindooDBAppBridgePortMessage, S as MindooDBAppBridgeQueryResultMessage, T as MindooDBAppBridgeRpcError, U as MindooDBAppBridgeRpcMessage, V as MindooDBAppBridgeRpcRequest, W as MindooDBAppBridgeRpcSuccess, X as MindooDBAppBridgeShortcutInvokedMessage, Y as MindooDBAppBridgeShortcutsChangedMessage, Z as MindooDBAppBridgeStreamAbortRequest, _ as MindooDBAppBridgeStreamAck, $ as MindooDBAppBridgeStreamCloseRequest, a0 as MindooDBAppBridgeStreamError, a1 as MindooDBAppBridgeStreamMessage, a2 as MindooDBAppBridgeStreamOpenResult, a3 as MindooDBAppBridgeStreamReadRequest, a4 as MindooDBAppBridgeStreamWriteRequest, a5 as MindooDBAppBridgeThemeChangedMessage, a6 as MindooDBAppBridgeUiPreferencesChangedMessage, a7 as MindooDBAppBridgeViewChangedMessage, a8 as MindooDBAppBridgeViewportChangedMessage, a9 as MindooDBAppCapability, aa as MindooDBAppConfiguredViewCategorizationStyle, ab as MindooDBAppConfiguredViewColumn, ac as MindooDBAppConfiguredViewColumnRole, ad as MindooDBAppConfiguredViewExpressionMode, ae as MindooDBAppConfiguredViewFieldExpression, af as MindooDBAppConfiguredViewFilterDefinition, ag as MindooDBAppConfiguredViewFilterMode, ah as MindooDBAppConfiguredViewFilterRule, ai as MindooDBAppConfiguredViewFormulaExpression, aj as MindooDBAppConfiguredViewFormulaFilterDefinition, ak as MindooDBAppConfiguredViewPreviewMode, al as MindooDBAppConfiguredViewRuleFilterDefinition, am as MindooDBAppConfiguredViewRuleMatchMode, an as MindooDBAppConfiguredViewRuleOperator, ao as MindooDBAppConfiguredViewValueExpression, ap as MindooDBAppCreateDocumentInput, aq as MindooDBAppCreateKeyInfo, ar as MindooDBAppCreateViewInput, as as MindooDBAppCreateViewNavigatorInput, at as MindooDBAppDatabaseInfo, au as MindooDBAppDefinition, av as MindooDBAppDefinitionDatabase, aw as MindooDBAppDefinitionPermission, ax as MindooDBAppDefinitionRegistrationPermission, ay as MindooDBAppDefinitionValidation, az as MindooDBAppDirectoryApi, aA as MindooDBAppDirectoryEntry, aB as MindooDBAppDocumentApi, aC as MindooDBAppDocumentHeadCursorResult, aD as MindooDBAppDocumentHistoryEntry, aE as MindooDBAppDocumentListQuery, aF as MindooDBAppDocumentListResult, aG as MindooDBAppDocumentQuery, aH as MindooDBAppDocumentRevisionId, aI as MindooDBAppDocumentScanPreset, aJ as MindooDBAppDocumentSummary, aK as MindooDBAppDragApi, aL as MindooDBAppDragCancelReason, aM as MindooDBAppDragDropEvent, aN as MindooDBAppDragEffect, aO as MindooDBAppDragHoverResult, aP as MindooDBAppDragOffer, aQ as MindooDBAppDragOverEvent, aR as MindooDBAppDragPointer, aS as MindooDBAppDragProfile, aT as MindooDBAppEntryAttachmentRef, aU as MindooDBAppEntryProvenance, aV as MindooDBAppExtractDocumentTextInput, aW as MindooDBAppExtractDocumentTextResult, aX as MindooDBAppExtractTextFormat, aY as MindooDBAppExtractionSetup, aZ as MindooDBAppFulltextSetup, a_ as MindooDBAppHistoricalDocument, a$ as MindooDBAppHistoryQuery, b0 as MindooDBAppHostTheme, b1 as MindooDBAppIdentityApi, b2 as MindooDBAppInaccessibleDocument, b3 as MindooDBAppInaccessibleDocumentListQuery, b4 as MindooDBAppInaccessibleDocumentListResult, b5 as MindooDBAppJsonListDeletePatch, b6 as MindooDBAppJsonListInsertPatch, b7 as MindooDBAppJsonPatch, b8 as MindooDBAppJsonSetPatch, b9 as MindooDBAppJsonTextMarkPatch, ba as MindooDBAppJsonTextSplicePatch, bb as MindooDBAppJsonTextUnmarkPatch, bc as MindooDBAppJsonUnsetPatch, bd as MindooDBAppLaunchContext, be as MindooDBAppLiveQuerySubscription, bf as MindooDBAppMenuAnchor, bg as MindooDBAppMenuApi, bh as MindooDBAppMenuCommandItem, bi as MindooDBAppMenuDismissReason, bj as MindooDBAppMenuDismissedResult, bk as MindooDBAppMenuItem, bl as MindooDBAppMenuKind, bm as MindooDBAppMenuPlacement, bn as MindooDBAppMenuPointAnchor, bo as MindooDBAppMenuRect, bp as MindooDBAppMenuRectAnchor, bq as MindooDBAppMenuSelectionResult, br as MindooDBAppMenuSeparatorItem, bs as MindooDBAppProposeAppInput, bt as MindooDBAppProposeAppResult, bu as MindooDBAppQueryCoverage, bv as MindooDBAppQueryInclude, bw as MindooDBAppQueryIncludeCardinality, bx as MindooDBAppQueryIncludeSlots, by as MindooDBAppQueryResult, bz as MindooDBAppQueryRow, bA as MindooDBAppQuerySortKey, bB as MindooDBAppQueryTextClause, bC as MindooDBAppReadableAttachmentStream, bD as MindooDBAppRecipientOptions, bE as MindooDBAppResolvedViewDefinition, bF as MindooDBAppResolvedViewSource, bG as MindooDBAppRevisionPhase, bH as MindooDBAppRevisionVerification, bI as MindooDBAppRichTextBlockSpan, bJ as MindooDBAppRichTextGetOptions, bK as MindooDBAppRichTextImmutableString, bL as MindooDBAppRichTextMarkRange, bM as MindooDBAppRichTextMaterializeValue, bN as MindooDBAppRichTextPatch, bO as MindooDBAppRichTextScalar, bP as MindooDBAppRichTextSpliceStep, bQ as MindooDBAppRichTextStep, bR as MindooDBAppRichTextStepPatch, bS as MindooDBAppRichTextTextSpan, bT as MindooDBAppRuntime, bU as MindooDBAppScanAttachmentOptions, bV as MindooDBAppScanAttachmentResult, bW as MindooDBAppScopedDocId, bX as MindooDBAppScopedDocumentSummary, bY as MindooDBAppSealIntent, bZ as MindooDBAppSealedChannelOpenInput, b_ as MindooDBAppSealedChannelOpenResult, b$ as MindooDBAppSealedChannelRequestInput, c0 as MindooDBAppSession, c1 as MindooDBAppShowMenuInput, c2 as MindooDBAppShowMenuResult, c3 as MindooDBAppSignPreview, c4 as MindooDBAppSignPreviewScope, c5 as MindooDBAppSignStatementInput, c6 as MindooDBAppSignStatementResult, c7 as MindooDBAppStorageApi, c8 as MindooDBAppTextEdit, c9 as MindooDBAppTextPatch, ca as MindooDBAppThemeMode, cb as MindooDBAppTimestampApi, cc as MindooDBAppTimestampInput, cd as MindooDBAppTimestampProvider, ce as MindooDBAppTimestampResult, cf as MindooDBAppUiPreferences, cg as MindooDBAppUpdateDocumentInput, ch as MindooDBAppViewCursorDocumentListResult, ci as MindooDBAppViewCursorResult, cj as MindooDBAppViewEntry, ck as MindooDBAppViewEntryKind, cl as MindooDBAppViewNavigator, cm as MindooDBAppViewNavigatorExpansionState, cn as MindooDBAppViewNavigatorOpenOptions, co as MindooDBAppViewNavigatorPageOptions, cp as MindooDBAppViewNavigatorPageResult, cq as MindooDBAppViewNavigatorRangeQuery, cr as MindooDBAppViewNavigatorSelectionState, cs as MindooDBAppViewUpdateStats, ct as MindooDBAppViewport, cu as MindooDBAppWellKnownDragType, cv as MindooDBAppWritableAttachmentStream, cw as resolveMindooDBAppDefinitionUrl, cx as validateMindooDBAppDefinition } from './types-C-eyC839.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';
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
releaseMindooDBAppBridgeSessions,
|
|
22
22
|
sanitizeHostShortcutBindings,
|
|
23
23
|
snapshotElementToPng
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-TPYDERAK.js";
|
|
25
25
|
import {
|
|
26
26
|
MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME,
|
|
27
27
|
MINDOODB_APP_BUNDLE_MANIFEST_FILE_NAME,
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { as as MindooDBAppCreateViewNavigatorInput,
|
|
1
|
+
import { as as MindooDBAppCreateViewNavigatorInput, cl as MindooDBAppViewNavigator, bd as MindooDBAppLaunchContext, at as MindooDBAppDatabaseInfo, aB as MindooDBAppDocumentApi, cn as MindooDBAppViewNavigatorOpenOptions, v as MindooDBAppAttachmentApi, b1 as MindooDBAppIdentityApi, cb as MindooDBAppTimestampApi, az as MindooDBAppDirectoryApi, j as MindooDBAppDocument, aZ as MindooDBAppFulltextSetup, aY as MindooDBAppExtractionSetup, bs as MindooDBAppProposeAppInput, bt as MindooDBAppProposeAppResult, e as MindooDBAppBridge, c0 as MindooDBAppSession, V as MindooDBAppBridgeRpcRequest, b0 as MindooDBAppHostTheme, ct as MindooDBAppViewport, cf as MindooDBAppUiPreferences, by as MindooDBAppQueryResult, cs as MindooDBAppViewUpdateStats, R as MindooDBAppBridgePortMessage, c as MindooDBAppDragStartResult, aS as MindooDBAppDragProfile } from '../types-C-eyC839.js';
|
|
2
2
|
import * as mindoodb from 'mindoodb';
|
|
3
3
|
import 'mindoodb-view-language';
|
|
4
4
|
|
package/dist/testing/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
releaseMindooDBAppBridgeSessions
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-TPYDERAK.js";
|
|
4
4
|
|
|
5
5
|
// src/testing/index.ts
|
|
6
6
|
import * as Automerge from "@automerge/automerge";
|
|
7
7
|
import {
|
|
8
8
|
evaluateExpression as evaluateExpression2,
|
|
9
|
+
formatMindooDBFormulaExpression,
|
|
9
10
|
parseMindooDBFormulaBooleanExpression
|
|
10
11
|
} from "mindoodb-view-language";
|
|
11
12
|
|
|
@@ -27,14 +28,16 @@ function toFormulaBoolean(value) {
|
|
|
27
28
|
}
|
|
28
29
|
return Boolean(value);
|
|
29
30
|
}
|
|
30
|
-
function matchesFilter(mindoodb, definition,
|
|
31
|
+
function matchesFilter(mindoodb, definition, document) {
|
|
31
32
|
void mindoodb;
|
|
32
33
|
if (!definition.filter) return true;
|
|
34
|
+
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } = document;
|
|
33
35
|
return toFormulaBoolean(
|
|
34
36
|
evaluateExpression(definition.filter.expression, {
|
|
35
37
|
doc,
|
|
36
38
|
values: doc,
|
|
37
39
|
origin,
|
|
40
|
+
docId,
|
|
38
41
|
createdAt,
|
|
39
42
|
lastModifiedAt,
|
|
40
43
|
witnessed,
|
|
@@ -43,7 +46,8 @@ function matchesFilter(mindoodb, definition, doc, origin, createdAt, lastModifie
|
|
|
43
46
|
})
|
|
44
47
|
);
|
|
45
48
|
}
|
|
46
|
-
function computeColumnValues(definition,
|
|
49
|
+
function computeColumnValues(definition, document) {
|
|
50
|
+
const { data: doc, origin, docId, createdAt, lastModifiedAt, witnessed, awaitingWitness } = document;
|
|
47
51
|
const values = {};
|
|
48
52
|
for (const [key, value] of Object.entries(doc)) {
|
|
49
53
|
if (!key.startsWith("_")) values[key] = value;
|
|
@@ -54,6 +58,7 @@ function computeColumnValues(definition, doc, origin, createdAt, lastModifiedAt,
|
|
|
54
58
|
doc,
|
|
55
59
|
values,
|
|
56
60
|
origin,
|
|
61
|
+
docId,
|
|
57
62
|
createdAt,
|
|
58
63
|
lastModifiedAt,
|
|
59
64
|
witnessed,
|
|
@@ -167,31 +172,11 @@ async function buildVirtualView(mindoodb, definition, documents, categorizationS
|
|
|
167
172
|
const view = await builder.build();
|
|
168
173
|
const changes = /* @__PURE__ */ new Map();
|
|
169
174
|
for (const document of documents) {
|
|
170
|
-
if (!matchesFilter(
|
|
171
|
-
mindoodb,
|
|
172
|
-
definition,
|
|
173
|
-
document.data,
|
|
174
|
-
document.origin,
|
|
175
|
-
document.createdAt,
|
|
176
|
-
document.lastModifiedAt,
|
|
177
|
-
document.witnessed,
|
|
178
|
-
document.awaitingWitness
|
|
179
|
-
)) {
|
|
175
|
+
if (!matchesFilter(mindoodb, definition, document)) {
|
|
180
176
|
continue;
|
|
181
177
|
}
|
|
182
178
|
const change = changes.get(document.origin) ?? new mindoodb.VirtualViewDataChange(document.origin);
|
|
183
|
-
change.addEntry(
|
|
184
|
-
document.docId,
|
|
185
|
-
computeColumnValues(
|
|
186
|
-
definition,
|
|
187
|
-
document.data,
|
|
188
|
-
document.origin,
|
|
189
|
-
document.createdAt,
|
|
190
|
-
document.lastModifiedAt,
|
|
191
|
-
document.witnessed,
|
|
192
|
-
document.awaitingWitness
|
|
193
|
-
)
|
|
194
|
-
);
|
|
179
|
+
change.addEntry(document.docId, computeColumnValues(definition, document));
|
|
195
180
|
changes.set(document.origin, change);
|
|
196
181
|
}
|
|
197
182
|
for (const change of changes.values()) {
|
|
@@ -951,7 +936,7 @@ function computeMockTextScore(document, clause) {
|
|
|
951
936
|
const matches = combineWith === "AND" ? matchedTerms === terms.length : matchedTerms > 0;
|
|
952
937
|
return matches ? score : void 0;
|
|
953
938
|
}
|
|
954
|
-
function runMockDocumentQuery(storedDocuments, databaseId, query) {
|
|
939
|
+
function runMockDocumentQuery(storedDocuments, databaseId, query, resolveDatabase) {
|
|
955
940
|
const filter = typeof query?.filter === "string" ? parseMindooDBFormulaBooleanExpression(query.filter) : query?.filter;
|
|
956
941
|
const sortBy = query?.sortBy && query.sortBy.length > 0 ? query.sortBy : query?.text ? [{ special: "textScore", direction: "descending" }] : [];
|
|
957
942
|
const matches = [];
|
|
@@ -970,6 +955,7 @@ function runMockDocumentQuery(storedDocuments, databaseId, query) {
|
|
|
970
955
|
doc: document.data,
|
|
971
956
|
values: {},
|
|
972
957
|
origin: databaseId,
|
|
958
|
+
docId: document.id,
|
|
973
959
|
variables: {}
|
|
974
960
|
};
|
|
975
961
|
if (filter && !mockExpressionToBoolean(evaluateExpression2(filter, context))) {
|
|
@@ -1001,19 +987,343 @@ function runMockDocumentQuery(storedDocuments, databaseId, query) {
|
|
|
1001
987
|
}
|
|
1002
988
|
const offset = Math.max(0, query?.offset ?? 0);
|
|
1003
989
|
const limit = Math.max(1, query?.limit ?? 200);
|
|
1004
|
-
const
|
|
990
|
+
const page = matches.slice(offset, offset + limit);
|
|
991
|
+
const rows = page.map(({ document, textScore }) => ({
|
|
1005
992
|
docId: document.id,
|
|
1006
|
-
fields: query?.fields
|
|
1007
|
-
|
|
1008
|
-
field,
|
|
1009
|
-
getFieldValue2(document.data, field)
|
|
1010
|
-
])
|
|
1011
|
-
) : structuredClone(document.data),
|
|
1012
|
-
lastModified: document.updatedAt ? Date.parse(document.updatedAt) || 0 : 0,
|
|
993
|
+
fields: projectMockFields(document.data, query?.fields),
|
|
994
|
+
lastModified: mockLastModified(document),
|
|
1013
995
|
...textScore === void 0 ? {} : { textScore }
|
|
1014
996
|
}));
|
|
997
|
+
if (query?.include) {
|
|
998
|
+
hydrateMockIncludes({
|
|
999
|
+
includes: query.include,
|
|
1000
|
+
parents: page.map(({ document }, index) => ({
|
|
1001
|
+
row: rows[index],
|
|
1002
|
+
docId: document.id,
|
|
1003
|
+
data: document.data
|
|
1004
|
+
})),
|
|
1005
|
+
parentDatabaseId: databaseId,
|
|
1006
|
+
parentDocuments: storedDocuments,
|
|
1007
|
+
resolveDatabase,
|
|
1008
|
+
depth: 1,
|
|
1009
|
+
slotPath: ""
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1015
1012
|
return { rows, total: matches.length, coverage: "full" };
|
|
1016
1013
|
}
|
|
1014
|
+
function projectMockFields(data, fields) {
|
|
1015
|
+
return fields ? Object.fromEntries(fields.map((field) => [field, getFieldValue2(data, field)])) : structuredClone(data);
|
|
1016
|
+
}
|
|
1017
|
+
function mockLastModified(document) {
|
|
1018
|
+
return document.updatedAt ? Date.parse(document.updatedAt) || 0 : 0;
|
|
1019
|
+
}
|
|
1020
|
+
var MOCK_MAX_INCLUDE_DEPTH = 3;
|
|
1021
|
+
var MOCK_DEFAULT_INCLUDE_LIMIT = 200;
|
|
1022
|
+
function mockIncludeFilter(include) {
|
|
1023
|
+
return typeof include.filter === "string" ? parseMindooDBFormulaBooleanExpression(include.filter) : include.filter;
|
|
1024
|
+
}
|
|
1025
|
+
function flattenMockConjuncts(expression) {
|
|
1026
|
+
return expression.kind === "operation" && expression.op === "and" ? expression.args.flatMap((arg) => flattenMockConjuncts(arg)) : [expression];
|
|
1027
|
+
}
|
|
1028
|
+
function mockReferencesParent(expression) {
|
|
1029
|
+
if (expression.kind === "parent") {
|
|
1030
|
+
return true;
|
|
1031
|
+
}
|
|
1032
|
+
if (expression.kind === "operation") {
|
|
1033
|
+
return expression.op === "parentDocId" || expression.args.some((arg) => mockReferencesParent(arg));
|
|
1034
|
+
}
|
|
1035
|
+
if (expression.kind === "if") {
|
|
1036
|
+
return [expression.condition, expression.whenTrue, expression.whenFalse].some(
|
|
1037
|
+
(part) => mockReferencesParent(part)
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
if (expression.kind === "let") {
|
|
1041
|
+
return Object.values(expression.bindings).some((value) => mockReferencesParent(value)) || mockReferencesParent(expression.result);
|
|
1042
|
+
}
|
|
1043
|
+
return false;
|
|
1044
|
+
}
|
|
1045
|
+
function mockChildJoinSide(expression) {
|
|
1046
|
+
if (expression.kind === "field") {
|
|
1047
|
+
return { kind: "field", path: expression.path };
|
|
1048
|
+
}
|
|
1049
|
+
if (expression.kind === "operation" && expression.op === "docId") {
|
|
1050
|
+
return { kind: "docId" };
|
|
1051
|
+
}
|
|
1052
|
+
return null;
|
|
1053
|
+
}
|
|
1054
|
+
function mockParentJoinSide(expression) {
|
|
1055
|
+
if (expression.kind === "parent") {
|
|
1056
|
+
return { kind: "field", path: expression.path };
|
|
1057
|
+
}
|
|
1058
|
+
if (expression.kind === "operation" && expression.op === "parentDocId") {
|
|
1059
|
+
return { kind: "docId" };
|
|
1060
|
+
}
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
function combineMockConjuncts(conjuncts) {
|
|
1064
|
+
if (conjuncts.length === 0) {
|
|
1065
|
+
return null;
|
|
1066
|
+
}
|
|
1067
|
+
if (conjuncts.length === 1) {
|
|
1068
|
+
return conjuncts[0];
|
|
1069
|
+
}
|
|
1070
|
+
return {
|
|
1071
|
+
kind: "operation",
|
|
1072
|
+
op: "and",
|
|
1073
|
+
args: conjuncts
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
function planMockInclude(label, include, filter) {
|
|
1077
|
+
if (include.localKey !== void 0) {
|
|
1078
|
+
if (filter && mockReferencesParent(filter)) {
|
|
1079
|
+
throw new Error(
|
|
1080
|
+
`Include "${label}" combines localKey with a filter that also references the parent document. Use either localKey or a parent join condition, not both.`
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
return {
|
|
1084
|
+
child: { kind: "docId" },
|
|
1085
|
+
parent: { kind: "field", path: include.localKey },
|
|
1086
|
+
residualFilter: filter ?? null
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
const conjuncts = flattenMockConjuncts(filter);
|
|
1090
|
+
const parentConjuncts = conjuncts.filter((conjunct) => mockReferencesParent(conjunct));
|
|
1091
|
+
const parentFree = conjuncts.filter((conjunct) => !mockReferencesParent(conjunct));
|
|
1092
|
+
if (parentConjuncts.length === 0) {
|
|
1093
|
+
throw new Error(
|
|
1094
|
+
`Include "${label}" cannot be joined because it does not reference the parent document. Add the join condition v.eq(v.field("<child field>"), v.parentDocId()) (or use localKey).`
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
if (parentConjuncts.length > 1) {
|
|
1098
|
+
throw new Error(
|
|
1099
|
+
`Include "${label}" cannot be joined because it references the parent document in ${parentConjuncts.length} separate conditions. Exactly one parent equality can be used as the join key.`
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
const join = parentConjuncts[0];
|
|
1103
|
+
if (join.kind !== "operation" || join.op !== "eq" || join.args.length !== 2) {
|
|
1104
|
+
throw new Error(
|
|
1105
|
+
`Include "${label}" cannot be joined because the condition referencing the parent is not an equality: ${formatMindooDBFormulaExpression(join)}. Only v.eq(v.field("<child field>"), v.parentDocId()) and friends can be used as the join key.`
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
const [left, right] = join.args;
|
|
1109
|
+
const sides = mockJoinSides(left, right) ?? mockJoinSides(right, left) ?? null;
|
|
1110
|
+
if (!sides) {
|
|
1111
|
+
throw new Error(
|
|
1112
|
+
`Include "${label}" cannot be joined because the join equality compares ${formatMindooDBFormulaExpression(join)}. One side must read the related document (v.field(...) or v.docId()), the other the parent (v.parent(...) or v.parentDocId()).`
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
return { ...sides, residualFilter: combineMockConjuncts(parentFree) };
|
|
1116
|
+
}
|
|
1117
|
+
function mockJoinSides(childCandidate, parentCandidate) {
|
|
1118
|
+
const child = mockChildJoinSide(childCandidate);
|
|
1119
|
+
const parent = mockParentJoinSide(parentCandidate);
|
|
1120
|
+
return child && parent ? { child, parent } : null;
|
|
1121
|
+
}
|
|
1122
|
+
function mockJoinValues(value) {
|
|
1123
|
+
if (value === void 0 || value === null) {
|
|
1124
|
+
return [];
|
|
1125
|
+
}
|
|
1126
|
+
return (Array.isArray(value) ? value : [value]).filter(
|
|
1127
|
+
(item) => item !== void 0 && item !== null
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
function validateMockInclude(slot, label, include, depth) {
|
|
1131
|
+
if (slot.trim() === "") {
|
|
1132
|
+
throw new Error("Include slot names must not be empty.");
|
|
1133
|
+
}
|
|
1134
|
+
if (depth > MOCK_MAX_INCLUDE_DEPTH) {
|
|
1135
|
+
throw new Error(
|
|
1136
|
+
`Include "${label}" nests ${depth} levels deep, more than the maximum of ${MOCK_MAX_INCLUDE_DEPTH}.`
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
if (include.cardinality !== "one" && include.cardinality !== "many") {
|
|
1140
|
+
throw new Error(
|
|
1141
|
+
`Include "${label}" needs an explicit cardinality of "one" or "many" (got ${JSON.stringify(include.cardinality)}).`
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
if (include.localKey === void 0 && include.filter === void 0) {
|
|
1145
|
+
throw new Error(
|
|
1146
|
+
`Include "${label}" needs a localKey or a filter to relate documents to the parent row.`
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
if (include.localKey !== void 0 && include.localKey.trim() === "") {
|
|
1150
|
+
throw new Error(`Include "${label}" has an empty localKey.`);
|
|
1151
|
+
}
|
|
1152
|
+
if (include.cardinality === "one") {
|
|
1153
|
+
if (include.sortBy !== void 0) {
|
|
1154
|
+
throw new Error(
|
|
1155
|
+
`Include "${label}" has cardinality "one", which resolves to a single row \u2014 sortBy is meaningless there.`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
if (include.limit !== void 0) {
|
|
1159
|
+
throw new Error(
|
|
1160
|
+
`Include "${label}" has cardinality "one", which resolves to a single row \u2014 limit is meaningless there.`
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
if (include.limit !== void 0 && (!Number.isFinite(include.limit) || include.limit < 0)) {
|
|
1165
|
+
throw new Error(`Include "${label}" has an invalid limit (${include.limit}).`);
|
|
1166
|
+
}
|
|
1167
|
+
for (const sortKey of include.sortBy ?? []) {
|
|
1168
|
+
if (sortKey.special === "textScore") {
|
|
1169
|
+
throw new Error(
|
|
1170
|
+
`Include "${label}" sorts by textScore, but includes have no text clause to score against.`
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
function hydrateMockIncludes(params) {
|
|
1176
|
+
const { includes, parents, parentDocuments, resolveDatabase, depth, slotPath } = params;
|
|
1177
|
+
for (const [slot, include] of Object.entries(includes)) {
|
|
1178
|
+
const label = slotPath ? `${slotPath}.${slot}` : slot;
|
|
1179
|
+
validateMockInclude(slot, label, include, depth);
|
|
1180
|
+
const filter = mockIncludeFilter(include);
|
|
1181
|
+
const plan = planMockInclude(label, include, filter);
|
|
1182
|
+
const childDatabaseId = include.databaseId ?? params.parentDatabaseId;
|
|
1183
|
+
let childDocuments = parentDocuments;
|
|
1184
|
+
if (include.databaseId !== void 0) {
|
|
1185
|
+
const resolved = resolveDatabase?.(include.databaseId);
|
|
1186
|
+
if (!resolved) {
|
|
1187
|
+
throw new Error(
|
|
1188
|
+
`Include "${label}" refers to the database "${include.databaseId}", which this app is not mapped to.`
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1191
|
+
childDocuments = resolved;
|
|
1192
|
+
}
|
|
1193
|
+
if (parents.length === 0) {
|
|
1194
|
+
continue;
|
|
1195
|
+
}
|
|
1196
|
+
const parentsByKey = /* @__PURE__ */ new Map();
|
|
1197
|
+
for (const parent of parents) {
|
|
1198
|
+
const parentValue = plan.parent.kind === "docId" ? parent.docId : getFieldValue2(parent.data, plan.parent.path);
|
|
1199
|
+
for (const key of mockJoinValues(parentValue)) {
|
|
1200
|
+
const bucket = parentsByKey.get(key);
|
|
1201
|
+
if (bucket) {
|
|
1202
|
+
bucket.push(parent);
|
|
1203
|
+
} else {
|
|
1204
|
+
parentsByKey.set(key, [parent]);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
const sortBy = include.sortBy ?? [];
|
|
1209
|
+
const childrenByKey = /* @__PURE__ */ new Map();
|
|
1210
|
+
if (parentsByKey.size > 0) {
|
|
1211
|
+
for (const document of childDocuments.values()) {
|
|
1212
|
+
if (document.isDeleted || document.inaccessible) {
|
|
1213
|
+
continue;
|
|
1214
|
+
}
|
|
1215
|
+
const childValue = plan.child.kind === "docId" ? document.id : getFieldValue2(document.data, plan.child.path);
|
|
1216
|
+
const matchedKeys = mockJoinValues(childValue).filter((key) => parentsByKey.has(key));
|
|
1217
|
+
if (matchedKeys.length === 0) {
|
|
1218
|
+
continue;
|
|
1219
|
+
}
|
|
1220
|
+
const context = {
|
|
1221
|
+
doc: document.data,
|
|
1222
|
+
values: {},
|
|
1223
|
+
origin: childDatabaseId,
|
|
1224
|
+
docId: document.id,
|
|
1225
|
+
variables: {}
|
|
1226
|
+
};
|
|
1227
|
+
if (plan.residualFilter && !mockExpressionToBoolean(evaluateExpression2(plan.residualFilter, context))) {
|
|
1228
|
+
continue;
|
|
1229
|
+
}
|
|
1230
|
+
const candidate = {
|
|
1231
|
+
docId: document.id,
|
|
1232
|
+
data: document.data,
|
|
1233
|
+
row: {
|
|
1234
|
+
docId: document.id,
|
|
1235
|
+
fields: projectMockFields(document.data, include.fields),
|
|
1236
|
+
lastModified: mockLastModified(document)
|
|
1237
|
+
},
|
|
1238
|
+
sortValues: sortBy.map(
|
|
1239
|
+
(key) => key.expression ? evaluateExpression2(key.expression, context) : getFieldValue2(document.data, key.field ?? "")
|
|
1240
|
+
)
|
|
1241
|
+
};
|
|
1242
|
+
for (const key of matchedKeys) {
|
|
1243
|
+
const bucket = childrenByKey.get(key);
|
|
1244
|
+
if (bucket) {
|
|
1245
|
+
bucket.push(candidate);
|
|
1246
|
+
} else {
|
|
1247
|
+
childrenByKey.set(key, [candidate]);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
const childParents = attachMockIncludeSlot(
|
|
1253
|
+
slot,
|
|
1254
|
+
label,
|
|
1255
|
+
include,
|
|
1256
|
+
plan,
|
|
1257
|
+
parents,
|
|
1258
|
+
childrenByKey,
|
|
1259
|
+
sortBy
|
|
1260
|
+
);
|
|
1261
|
+
if (include.include && childParents.length > 0) {
|
|
1262
|
+
hydrateMockIncludes({
|
|
1263
|
+
includes: include.include,
|
|
1264
|
+
parents: childParents,
|
|
1265
|
+
parentDatabaseId: childDatabaseId,
|
|
1266
|
+
parentDocuments: childDocuments,
|
|
1267
|
+
resolveDatabase,
|
|
1268
|
+
depth: depth + 1,
|
|
1269
|
+
slotPath: label
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
function attachMockIncludeSlot(slot, label, include, plan, parents, childrenByKey, sortBy) {
|
|
1275
|
+
const limit = include.limit ?? MOCK_DEFAULT_INCLUDE_LIMIT;
|
|
1276
|
+
const nextParents = [];
|
|
1277
|
+
for (const parent of parents) {
|
|
1278
|
+
const parentValue = plan.parent.kind === "docId" ? parent.docId : getFieldValue2(parent.data, plan.parent.path);
|
|
1279
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1280
|
+
const matches = [];
|
|
1281
|
+
for (const key of mockJoinValues(parentValue)) {
|
|
1282
|
+
for (const candidate of childrenByKey.get(key) ?? []) {
|
|
1283
|
+
if (seen.has(candidate.docId)) {
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
seen.add(candidate.docId);
|
|
1287
|
+
matches.push(candidate);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
const slots = parent.row.includes ??= {};
|
|
1291
|
+
if (include.cardinality === "one") {
|
|
1292
|
+
if (matches.length > 1) {
|
|
1293
|
+
const sample = matches.slice(0, 3).map((match2) => match2.docId).join(", ");
|
|
1294
|
+
throw new Error(
|
|
1295
|
+
`Include "${label}" has cardinality "one", but document "${parent.docId}" matched ${matches.length} related documents (${sample}${matches.length > 3 ? ", \u2026" : ""}). Use cardinality "many" if several matches are expected.`
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
if (matches.length === 0) {
|
|
1299
|
+
slots[slot] = null;
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
const match = matches[0];
|
|
1303
|
+
const row = structuredClone(match.row);
|
|
1304
|
+
slots[slot] = row;
|
|
1305
|
+
nextParents.push({ row, docId: match.docId, data: match.data });
|
|
1306
|
+
continue;
|
|
1307
|
+
}
|
|
1308
|
+
matches.sort((left, right) => {
|
|
1309
|
+
for (let i = 0; i < sortBy.length; i++) {
|
|
1310
|
+
const result = compareMockQueryValues(left.sortValues[i], right.sortValues[i]);
|
|
1311
|
+
if (result !== 0) {
|
|
1312
|
+
return sortBy[i].direction === "descending" ? -result : result;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
return left.docId.localeCompare(right.docId);
|
|
1316
|
+
});
|
|
1317
|
+
const rows = [];
|
|
1318
|
+
for (const candidate of matches.slice(0, limit)) {
|
|
1319
|
+
const row = structuredClone(candidate.row);
|
|
1320
|
+
rows.push(row);
|
|
1321
|
+
nextParents.push({ row, docId: candidate.docId, data: candidate.data });
|
|
1322
|
+
}
|
|
1323
|
+
slots[slot] = rows;
|
|
1324
|
+
}
|
|
1325
|
+
return nextParents;
|
|
1326
|
+
}
|
|
1017
1327
|
function createDefaultViewNavigator() {
|
|
1018
1328
|
const definition = {
|
|
1019
1329
|
title: "Mock View",
|
|
@@ -1230,7 +1540,7 @@ async function mockSha256Hex(value) {
|
|
|
1230
1540
|
const digest = await subtle.digest("SHA-256", new TextEncoder().encode(value));
|
|
1231
1541
|
return Array.from(new Uint8Array(digest)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1232
1542
|
}
|
|
1233
|
-
function createDatabaseHandle(definition) {
|
|
1543
|
+
function createDatabaseHandle(definition, peers) {
|
|
1234
1544
|
let createCounter = 0;
|
|
1235
1545
|
let changeCounter = 0;
|
|
1236
1546
|
const defaultViewFactory = async () => createDefaultViewNavigator();
|
|
@@ -1250,12 +1560,13 @@ function createDatabaseHandle(definition) {
|
|
|
1250
1560
|
});
|
|
1251
1561
|
}
|
|
1252
1562
|
const liveQuerySubscriptions = /* @__PURE__ */ new Set();
|
|
1253
|
-
const
|
|
1563
|
+
const refreshLiveQueries = () => {
|
|
1254
1564
|
for (const subscription of liveQuerySubscriptions) {
|
|
1255
1565
|
const result = runMockDocumentQuery(
|
|
1256
1566
|
storedDocuments,
|
|
1257
1567
|
definition.info.id,
|
|
1258
|
-
subscription.query
|
|
1568
|
+
subscription.query,
|
|
1569
|
+
peers.getDocuments
|
|
1259
1570
|
);
|
|
1260
1571
|
const resultJson = JSON.stringify(result);
|
|
1261
1572
|
if (resultJson !== subscription.lastResultJson) {
|
|
@@ -1264,6 +1575,9 @@ function createDatabaseHandle(definition) {
|
|
|
1264
1575
|
}
|
|
1265
1576
|
}
|
|
1266
1577
|
};
|
|
1578
|
+
const notifyLiveQueries = () => {
|
|
1579
|
+
peers.refreshAllLiveQueries();
|
|
1580
|
+
};
|
|
1267
1581
|
function mockEncryptForMap(names) {
|
|
1268
1582
|
const encryptFor = {};
|
|
1269
1583
|
for (const name of names) {
|
|
@@ -1304,13 +1618,19 @@ function createDatabaseHandle(definition) {
|
|
|
1304
1618
|
}
|
|
1305
1619
|
const defaultDocuments = {
|
|
1306
1620
|
async query(query) {
|
|
1307
|
-
return runMockDocumentQuery(
|
|
1621
|
+
return runMockDocumentQuery(
|
|
1622
|
+
storedDocuments,
|
|
1623
|
+
definition.info.id,
|
|
1624
|
+
query,
|
|
1625
|
+
peers.getDocuments
|
|
1626
|
+
);
|
|
1308
1627
|
},
|
|
1309
1628
|
async liveQuery(query, onResult) {
|
|
1310
1629
|
const initial = runMockDocumentQuery(
|
|
1311
1630
|
storedDocuments,
|
|
1312
1631
|
definition.info.id,
|
|
1313
|
-
query
|
|
1632
|
+
query,
|
|
1633
|
+
peers.getDocuments
|
|
1314
1634
|
);
|
|
1315
1635
|
const subscription = {
|
|
1316
1636
|
query,
|
|
@@ -1327,7 +1647,8 @@ function createDatabaseHandle(definition) {
|
|
|
1327
1647
|
const result = runMockDocumentQuery(
|
|
1328
1648
|
storedDocuments,
|
|
1329
1649
|
definition.info.id,
|
|
1330
|
-
query
|
|
1650
|
+
query,
|
|
1651
|
+
peers.getDocuments
|
|
1331
1652
|
);
|
|
1332
1653
|
subscription.lastResultJson = JSON.stringify(result);
|
|
1333
1654
|
onResult(result);
|
|
@@ -1845,7 +2166,9 @@ function createDatabaseHandle(definition) {
|
|
|
1845
2166
|
docId: document.id,
|
|
1846
2167
|
data: structuredClone(document.data),
|
|
1847
2168
|
createdAt: document.updatedAt ?? null
|
|
1848
|
-
}))
|
|
2169
|
+
})),
|
|
2170
|
+
documents: storedDocuments,
|
|
2171
|
+
notifyLiveQueries: refreshLiveQueries
|
|
1849
2172
|
};
|
|
1850
2173
|
}
|
|
1851
2174
|
function createMockSessionState(options = {}) {
|
|
@@ -1857,6 +2180,16 @@ function createMockSessionState(options = {}) {
|
|
|
1857
2180
|
const beforeCloseListeners = /* @__PURE__ */ new Set();
|
|
1858
2181
|
const databaseHandles = /* @__PURE__ */ new Map();
|
|
1859
2182
|
const databaseViewDocumentLists = /* @__PURE__ */ new Map();
|
|
2183
|
+
const databaseDocumentStores = /* @__PURE__ */ new Map();
|
|
2184
|
+
const databaseLiveQueryRefreshers = /* @__PURE__ */ new Map();
|
|
2185
|
+
const databasePeers = {
|
|
2186
|
+
getDocuments: (databaseId) => databaseDocumentStores.get(databaseId),
|
|
2187
|
+
refreshAllLiveQueries: () => {
|
|
2188
|
+
for (const refresh of databaseLiveQueryRefreshers.values()) {
|
|
2189
|
+
refresh();
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
1860
2193
|
const databaseViewApis = /* @__PURE__ */ new Map();
|
|
1861
2194
|
const sessionViews = /* @__PURE__ */ new Map();
|
|
1862
2195
|
let activeMenuResolve = null;
|
|
@@ -1931,14 +2264,18 @@ function createMockSessionState(options = {}) {
|
|
|
1931
2264
|
databaseHandles.clear();
|
|
1932
2265
|
databaseViewDocumentLists.clear();
|
|
1933
2266
|
databaseViewApis.clear();
|
|
2267
|
+
databaseDocumentStores.clear();
|
|
2268
|
+
databaseLiveQueryRefreshers.clear();
|
|
1934
2269
|
databaseInfos = definitions.map((definition) => ({
|
|
1935
2270
|
...definition.info,
|
|
1936
2271
|
capabilities: [...definition.info.capabilities]
|
|
1937
2272
|
}));
|
|
1938
2273
|
for (const definition of definitions) {
|
|
1939
|
-
const created = createDatabaseHandle(definition);
|
|
2274
|
+
const created = createDatabaseHandle(definition, databasePeers);
|
|
1940
2275
|
databaseHandles.set(definition.info.id, created.handle);
|
|
1941
2276
|
databaseViewDocumentLists.set(definition.info.id, created.listViewDocuments);
|
|
2277
|
+
databaseDocumentStores.set(definition.info.id, created.documents);
|
|
2278
|
+
databaseLiveQueryRefreshers.set(definition.info.id, created.notifyLiveQueries);
|
|
1942
2279
|
databaseViewApis.set(definition.info.id, {
|
|
1943
2280
|
async create(input) {
|
|
1944
2281
|
const documents = input.databaseIds.flatMap((databaseId) => {
|
|
@@ -1450,8 +1450,80 @@ interface MindooDBAppExtractionSetup {
|
|
|
1450
1450
|
* `'v.and(v.eq(v.field("type"), "invoice"), v.gt(v.field("total"), 100))'`),
|
|
1451
1451
|
* which the SDK parses locally; only JSON travels across the bridge.
|
|
1452
1452
|
*/
|
|
1453
|
+
/**
|
|
1454
|
+
* Cardinality of a {@link MindooDBAppQueryInclude}: whether the slot
|
|
1455
|
+
* resolves to a single related document or a list of them. Always
|
|
1456
|
+
* explicit — a lookup that silently picks the first of several matches is
|
|
1457
|
+
* a bug waiting to happen.
|
|
1458
|
+
*/
|
|
1459
|
+
type MindooDBAppQueryIncludeCardinality = "one" | "many";
|
|
1460
|
+
/**
|
|
1461
|
+
* One nested lookup ("join") of a {@link MindooDBAppDocumentQuery}: the
|
|
1462
|
+
* related documents are fetched alongside the matching rows and attached
|
|
1463
|
+
* under {@link MindooDBAppQueryRow.includes}.
|
|
1464
|
+
*
|
|
1465
|
+
* Mirrors mindoodb's `MindooQueryInclude` with one substitution: core
|
|
1466
|
+
* takes a live `MindooDB` instance, which cannot cross the bridge, so a
|
|
1467
|
+
* related database is named by its logical {@link databaseId} instead.
|
|
1468
|
+
*
|
|
1469
|
+
* ```typescript
|
|
1470
|
+
* await database.documents.query({
|
|
1471
|
+
* filter: 'v.eq(v.field("type"), "invoice")',
|
|
1472
|
+
* include: {
|
|
1473
|
+
* customer: { databaseId: "customers", cardinality: "one", localKey: "customerId" },
|
|
1474
|
+
* lines: { cardinality: "many", filter: 'v.eq(v.field("invoiceId"), v.parentDocId())' },
|
|
1475
|
+
* },
|
|
1476
|
+
* });
|
|
1477
|
+
* ```
|
|
1478
|
+
*/
|
|
1479
|
+
interface MindooDBAppQueryInclude {
|
|
1480
|
+
/**
|
|
1481
|
+
* The database the related documents live in, addressed by the same
|
|
1482
|
+
* logical id `openDatabase()` takes. Omit for the database the query
|
|
1483
|
+
* itself runs against. The app must be mapped to it with read access.
|
|
1484
|
+
*/
|
|
1485
|
+
databaseId?: string;
|
|
1486
|
+
cardinality: MindooDBAppQueryIncludeCardinality;
|
|
1487
|
+
/**
|
|
1488
|
+
* Field of the PARENT document holding the related document's id —
|
|
1489
|
+
* sugar for `v.eq(v.docId(), v.parent("<localKey>"))`. An array value
|
|
1490
|
+
* joins every element.
|
|
1491
|
+
*/
|
|
1492
|
+
localKey?: string;
|
|
1493
|
+
/**
|
|
1494
|
+
* Join condition, as an expression or formula source text. Exactly one
|
|
1495
|
+
* equality must relate the related document to the parent row
|
|
1496
|
+
* (`v.parentDocId()` for the parent's id, `v.parent(path)` for one of
|
|
1497
|
+
* its fields); any further conditions narrow the related documents.
|
|
1498
|
+
*/
|
|
1499
|
+
filter?: MindooDBAppBooleanExpression | string;
|
|
1500
|
+
/** Projection for the related rows. Defaults to all summary fields. */
|
|
1501
|
+
fields?: string[];
|
|
1502
|
+
/** Ordering of the related rows. Only valid for `cardinality: "many"`. */
|
|
1503
|
+
sortBy?: MindooDBAppQuerySortKey[];
|
|
1504
|
+
/**
|
|
1505
|
+
* Maximum number of related rows per parent row. Only valid for
|
|
1506
|
+
* `cardinality: "many"`; the host enforces a cap.
|
|
1507
|
+
*/
|
|
1508
|
+
limit?: number;
|
|
1509
|
+
/** Nested lookups on the related documents. */
|
|
1510
|
+
include?: Record<string, MindooDBAppQueryInclude>;
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* The related documents attached to a row, keyed by include slot name: a
|
|
1514
|
+
* single row (or `null`) for `cardinality: "one"`, an array — possibly
|
|
1515
|
+
* empty, never `null` — for `"many"`.
|
|
1516
|
+
*/
|
|
1517
|
+
type MindooDBAppQueryIncludeSlots = Record<string, MindooDBAppQueryRow | MindooDBAppQueryRow[] | null>;
|
|
1453
1518
|
interface MindooDBAppDocumentQuery {
|
|
1454
1519
|
filter?: MindooDBAppBooleanExpression | string;
|
|
1520
|
+
/**
|
|
1521
|
+
* Nested lookups, keyed by the slot name the related documents appear
|
|
1522
|
+
* under in {@link MindooDBAppQueryRow.includes}. Resolved for the
|
|
1523
|
+
* returned page only, at one scan per slot rather than one query per
|
|
1524
|
+
* row.
|
|
1525
|
+
*/
|
|
1526
|
+
include?: Record<string, MindooDBAppQueryInclude>;
|
|
1455
1527
|
/**
|
|
1456
1528
|
* Full-text clause: additionally require documents to match this
|
|
1457
1529
|
* full-text search (combined with `filter` as a logical AND). Adds a
|
|
@@ -1474,7 +1546,7 @@ interface MindooDBAppDocumentQuery {
|
|
|
1474
1546
|
fields?: string[];
|
|
1475
1547
|
}
|
|
1476
1548
|
/** One result row of a summary-backed document query. */
|
|
1477
|
-
interface MindooDBAppQueryRow {
|
|
1549
|
+
interface MindooDBAppQueryRow<TIncludes extends MindooDBAppQueryIncludeSlots = MindooDBAppQueryIncludeSlots> {
|
|
1478
1550
|
docId: string;
|
|
1479
1551
|
fields: Record<string, unknown>;
|
|
1480
1552
|
lastModified: number;
|
|
@@ -1483,6 +1555,15 @@ interface MindooDBAppQueryRow {
|
|
|
1483
1555
|
* Only present when the query had a `text` clause.
|
|
1484
1556
|
*/
|
|
1485
1557
|
textScore?: number;
|
|
1558
|
+
/**
|
|
1559
|
+
* Related documents fetched through the query's `include` clause, keyed
|
|
1560
|
+
* by slot name. Absent when the query carried no `include`, so results
|
|
1561
|
+
* of plain queries keep exactly the shape they always had.
|
|
1562
|
+
*
|
|
1563
|
+
* Included rows are ordinary rows, so a nested lookup reads as
|
|
1564
|
+
* `row.includes.customer.includes.address`.
|
|
1565
|
+
*/
|
|
1566
|
+
includes?: TIncludes;
|
|
1486
1567
|
}
|
|
1487
1568
|
/**
|
|
1488
1569
|
* Which data answered the query: `"full"` when the summary buffer is
|
|
@@ -1490,9 +1571,22 @@ interface MindooDBAppQueryRow {
|
|
|
1490
1571
|
* be incomplete), `"full-scan"` when documents were materialized.
|
|
1491
1572
|
*/
|
|
1492
1573
|
type MindooDBAppQueryCoverage = "full" | "rebuilding" | "full-scan";
|
|
1493
|
-
/**
|
|
1494
|
-
|
|
1495
|
-
|
|
1574
|
+
/**
|
|
1575
|
+
* Result of a summary-backed document query.
|
|
1576
|
+
*
|
|
1577
|
+
* Slot types of an `include` clause are not inferred from the query
|
|
1578
|
+
* object; callers who want them pass them explicitly:
|
|
1579
|
+
*
|
|
1580
|
+
* ```typescript
|
|
1581
|
+
* const result = await database.documents.query<{
|
|
1582
|
+
* customer: MindooDBAppQueryRow | null;
|
|
1583
|
+
* lines: MindooDBAppQueryRow[];
|
|
1584
|
+
* }>({ ... });
|
|
1585
|
+
* result.rows[0]?.includes?.lines[0]?.fields.amount;
|
|
1586
|
+
* ```
|
|
1587
|
+
*/
|
|
1588
|
+
interface MindooDBAppQueryResult<TIncludes extends MindooDBAppQueryIncludeSlots = MindooDBAppQueryIncludeSlots> {
|
|
1589
|
+
rows: MindooDBAppQueryRow<TIncludes>[];
|
|
1496
1590
|
/** Number of matching documents before `offset`/`limit` were applied. */
|
|
1497
1591
|
total: number;
|
|
1498
1592
|
coverage: MindooDBAppQueryCoverage;
|
|
@@ -1523,15 +1617,22 @@ interface MindooDBAppDocumentApi {
|
|
|
1523
1617
|
* `query-not-supported` error. A `text` clause requires full-text
|
|
1524
1618
|
* indexing to be enabled for the database, otherwise the query is
|
|
1525
1619
|
* rejected with `fulltext-not-enabled`.
|
|
1620
|
+
*
|
|
1621
|
+
* An `include` clause additionally fetches related documents, from this
|
|
1622
|
+
* or another mapped database; pass the slot types as `TIncludes` to
|
|
1623
|
+
* type `row.includes`.
|
|
1526
1624
|
*/
|
|
1527
|
-
query(query?: MindooDBAppDocumentQuery): Promise<MindooDBAppQueryResult
|
|
1625
|
+
query<TIncludes extends MindooDBAppQueryIncludeSlots = MindooDBAppQueryIncludeSlots>(query?: MindooDBAppDocumentQuery): Promise<MindooDBAppQueryResult<TIncludes>>;
|
|
1528
1626
|
/**
|
|
1529
1627
|
* Live variant of {@link query}: delivers the initial result, then keeps
|
|
1530
1628
|
* watching the database and calls `onResult` again whenever the result
|
|
1531
1629
|
* actually changed (membership, order, or row content). Updates are
|
|
1532
1630
|
* coalesced on the host, so bursts of writes produce a single push.
|
|
1631
|
+
*
|
|
1632
|
+
* With an `include` clause the subscription also watches every related
|
|
1633
|
+
* database, so a change to a joined document pushes a new result too.
|
|
1533
1634
|
*/
|
|
1534
|
-
liveQuery(query: MindooDBAppDocumentQuery, onResult: (result: MindooDBAppQueryResult) => void): Promise<MindooDBAppLiveQuerySubscription>;
|
|
1635
|
+
liveQuery<TIncludes extends MindooDBAppQueryIncludeSlots = MindooDBAppQueryIncludeSlots>(query: MindooDBAppDocumentQuery, onResult: (result: MindooDBAppQueryResult<TIncludes>) => void): Promise<MindooDBAppLiveQuerySubscription>;
|
|
1535
1636
|
/**
|
|
1536
1637
|
* Page through the database's changefeed. Pass the returned `nextCursor`
|
|
1537
1638
|
* back in to resume — this is the primitive for incremental sync and
|
|
@@ -2549,4 +2650,4 @@ interface MindooDBAppBridge {
|
|
|
2549
2650
|
connect(options?: MindooDBAppBridgeConnectOptions): Promise<MindooDBAppSession>;
|
|
2550
2651
|
}
|
|
2551
2652
|
|
|
2552
|
-
export { type MindooDBAppBridgeStreamCloseRequest as $, type MindooDBAppAutomergeChangesPatch as A, type MindooDBAppAutomergeChangesSince as B, type MindooDBAppAutomergeGetOptions as C, type MindooDBAppAutomergePatchResult as D, type MindooDBAppAutomergeSnapshot as E, type MindooDBAppBridgeBeforeCloseAck as F, type MindooDBAppBridgeBeforeCloseMessage as G, type MindooDBAppBridgeConnectMessage as H, type MindooDBAppBridgeConnectOptions as I, type MindooDBAppBridgeConnectedMessage as J, type MindooDBAppBridgeDragDropMessage as K, type MindooDBAppBridgeDragLeaveMessage as L, type MindooDBAppAttachmentPreviewMode as M, type MindooDBAppBridgeDragOverMessage as N, type MindooDBAppBridgeErrorPayload as O, type MindooDBAppBridgeHandshakeErrorMessage as P, type MindooDBAppBridgeLocaleChangedMessage as Q, type MindooDBAppBridgePortMessage as R, type MindooDBAppBridgeQueryResultMessage as S, type MindooDBAppBridgeRpcError as T, type MindooDBAppBridgeRpcMessage as U, type MindooDBAppBridgeRpcRequest as V, type MindooDBAppBridgeRpcSuccess as W, type MindooDBAppBridgeShortcutInvokedMessage as X, type MindooDBAppBridgeShortcutsChangedMessage as Y, type MindooDBAppBridgeStreamAbortRequest as Z, type MindooDBAppBridgeStreamAck as _, type MindooDBAppDragBindSourceOptions as a, type MindooDBAppHistoryQuery as a$, type MindooDBAppBridgeStreamError as a0, type MindooDBAppBridgeStreamMessage as a1, type MindooDBAppBridgeStreamOpenResult as a2, type MindooDBAppBridgeStreamReadRequest as a3, type MindooDBAppBridgeStreamWriteRequest as a4, type MindooDBAppBridgeThemeChangedMessage as a5, type MindooDBAppBridgeUiPreferencesChangedMessage as a6, type MindooDBAppBridgeViewChangedMessage as a7, type MindooDBAppBridgeViewportChangedMessage as a8, type MindooDBAppCapability as a9, type MindooDBAppDirectoryEntry as aA, type MindooDBAppDocumentApi as aB, type MindooDBAppDocumentHeadCursorResult as aC, type MindooDBAppDocumentHistoryEntry as aD, type MindooDBAppDocumentListQuery as aE, type MindooDBAppDocumentListResult as aF, type MindooDBAppDocumentQuery as aG, type MindooDBAppDocumentRevisionId as aH, type MindooDBAppDocumentScanPreset as aI, type MindooDBAppDocumentSummary as aJ, type MindooDBAppDragApi as aK, type MindooDBAppDragCancelReason as aL, type MindooDBAppDragDropEvent as aM, type MindooDBAppDragEffect as aN, type MindooDBAppDragHoverResult as aO, type MindooDBAppDragOffer as aP, type MindooDBAppDragOverEvent as aQ, type MindooDBAppDragPointer as aR, type MindooDBAppDragProfile as aS, type MindooDBAppEntryAttachmentRef as aT, type MindooDBAppEntryProvenance as aU, type MindooDBAppExtractDocumentTextInput as aV, type MindooDBAppExtractDocumentTextResult as aW, type MindooDBAppExtractTextFormat as aX, type MindooDBAppExtractionSetup as aY, type MindooDBAppFulltextSetup as aZ, type MindooDBAppHistoricalDocument as a_, type MindooDBAppConfiguredViewCategorizationStyle as aa, type MindooDBAppConfiguredViewColumn as ab, type MindooDBAppConfiguredViewColumnRole as ac, type MindooDBAppConfiguredViewExpressionMode as ad, type MindooDBAppConfiguredViewFieldExpression as ae, type MindooDBAppConfiguredViewFilterDefinition as af, type MindooDBAppConfiguredViewFilterMode as ag, type MindooDBAppConfiguredViewFilterRule as ah, type MindooDBAppConfiguredViewFormulaExpression as ai, type MindooDBAppConfiguredViewFormulaFilterDefinition as aj, type MindooDBAppConfiguredViewPreviewMode as ak, type MindooDBAppConfiguredViewRuleFilterDefinition as al, type MindooDBAppConfiguredViewRuleMatchMode as am, type MindooDBAppConfiguredViewRuleOperator as an, type MindooDBAppConfiguredViewValueExpression as ao, type MindooDBAppCreateDocumentInput as ap, type MindooDBAppCreateKeyInfo as aq, type MindooDBAppCreateViewInput as ar, type MindooDBAppCreateViewNavigatorInput as as, type MindooDBAppDatabaseInfo as at, type MindooDBAppDefinition as au, type MindooDBAppDefinitionDatabase as av, type MindooDBAppDefinitionPermission as aw, type MindooDBAppDefinitionRegistrationPermission as ax, type MindooDBAppDefinitionValidation as ay, type MindooDBAppDirectoryApi as az, type MindooDBAppDragStartInput as b, type
|
|
2653
|
+
export { type MindooDBAppBridgeStreamCloseRequest as $, type MindooDBAppAutomergeChangesPatch as A, type MindooDBAppAutomergeChangesSince as B, type MindooDBAppAutomergeGetOptions as C, type MindooDBAppAutomergePatchResult as D, type MindooDBAppAutomergeSnapshot as E, type MindooDBAppBridgeBeforeCloseAck as F, type MindooDBAppBridgeBeforeCloseMessage as G, type MindooDBAppBridgeConnectMessage as H, type MindooDBAppBridgeConnectOptions as I, type MindooDBAppBridgeConnectedMessage as J, type MindooDBAppBridgeDragDropMessage as K, type MindooDBAppBridgeDragLeaveMessage as L, type MindooDBAppAttachmentPreviewMode as M, type MindooDBAppBridgeDragOverMessage as N, type MindooDBAppBridgeErrorPayload as O, type MindooDBAppBridgeHandshakeErrorMessage as P, type MindooDBAppBridgeLocaleChangedMessage as Q, type MindooDBAppBridgePortMessage as R, type MindooDBAppBridgeQueryResultMessage as S, type MindooDBAppBridgeRpcError as T, type MindooDBAppBridgeRpcMessage as U, type MindooDBAppBridgeRpcRequest as V, type MindooDBAppBridgeRpcSuccess as W, type MindooDBAppBridgeShortcutInvokedMessage as X, type MindooDBAppBridgeShortcutsChangedMessage as Y, type MindooDBAppBridgeStreamAbortRequest as Z, type MindooDBAppBridgeStreamAck as _, type MindooDBAppDragBindSourceOptions as a, type MindooDBAppHistoryQuery as a$, type MindooDBAppBridgeStreamError as a0, type MindooDBAppBridgeStreamMessage as a1, type MindooDBAppBridgeStreamOpenResult as a2, type MindooDBAppBridgeStreamReadRequest as a3, type MindooDBAppBridgeStreamWriteRequest as a4, type MindooDBAppBridgeThemeChangedMessage as a5, type MindooDBAppBridgeUiPreferencesChangedMessage as a6, type MindooDBAppBridgeViewChangedMessage as a7, type MindooDBAppBridgeViewportChangedMessage as a8, type MindooDBAppCapability as a9, type MindooDBAppDirectoryEntry as aA, type MindooDBAppDocumentApi as aB, type MindooDBAppDocumentHeadCursorResult as aC, type MindooDBAppDocumentHistoryEntry as aD, type MindooDBAppDocumentListQuery as aE, type MindooDBAppDocumentListResult as aF, type MindooDBAppDocumentQuery as aG, type MindooDBAppDocumentRevisionId as aH, type MindooDBAppDocumentScanPreset as aI, type MindooDBAppDocumentSummary as aJ, type MindooDBAppDragApi as aK, type MindooDBAppDragCancelReason as aL, type MindooDBAppDragDropEvent as aM, type MindooDBAppDragEffect as aN, type MindooDBAppDragHoverResult as aO, type MindooDBAppDragOffer as aP, type MindooDBAppDragOverEvent as aQ, type MindooDBAppDragPointer as aR, type MindooDBAppDragProfile as aS, type MindooDBAppEntryAttachmentRef as aT, type MindooDBAppEntryProvenance as aU, type MindooDBAppExtractDocumentTextInput as aV, type MindooDBAppExtractDocumentTextResult as aW, type MindooDBAppExtractTextFormat as aX, type MindooDBAppExtractionSetup as aY, type MindooDBAppFulltextSetup as aZ, type MindooDBAppHistoricalDocument as a_, type MindooDBAppConfiguredViewCategorizationStyle as aa, type MindooDBAppConfiguredViewColumn as ab, type MindooDBAppConfiguredViewColumnRole as ac, type MindooDBAppConfiguredViewExpressionMode as ad, type MindooDBAppConfiguredViewFieldExpression as ae, type MindooDBAppConfiguredViewFilterDefinition as af, type MindooDBAppConfiguredViewFilterMode as ag, type MindooDBAppConfiguredViewFilterRule as ah, type MindooDBAppConfiguredViewFormulaExpression as ai, type MindooDBAppConfiguredViewFormulaFilterDefinition as aj, type MindooDBAppConfiguredViewPreviewMode as ak, type MindooDBAppConfiguredViewRuleFilterDefinition as al, type MindooDBAppConfiguredViewRuleMatchMode as am, type MindooDBAppConfiguredViewRuleOperator as an, type MindooDBAppConfiguredViewValueExpression as ao, type MindooDBAppCreateDocumentInput as ap, type MindooDBAppCreateKeyInfo as aq, type MindooDBAppCreateViewInput as ar, type MindooDBAppCreateViewNavigatorInput as as, type MindooDBAppDatabaseInfo as at, type MindooDBAppDefinition as au, type MindooDBAppDefinitionDatabase as av, type MindooDBAppDefinitionPermission as aw, type MindooDBAppDefinitionRegistrationPermission as ax, type MindooDBAppDefinitionValidation as ay, type MindooDBAppDirectoryApi as az, type MindooDBAppDragStartInput as b, type MindooDBAppSealedChannelRequestInput as b$, type MindooDBAppHostTheme as b0, type MindooDBAppIdentityApi as b1, type MindooDBAppInaccessibleDocument as b2, type MindooDBAppInaccessibleDocumentListQuery as b3, type MindooDBAppInaccessibleDocumentListResult as b4, type MindooDBAppJsonListDeletePatch as b5, type MindooDBAppJsonListInsertPatch as b6, type MindooDBAppJsonPatch as b7, type MindooDBAppJsonSetPatch as b8, type MindooDBAppJsonTextMarkPatch as b9, type MindooDBAppQuerySortKey as bA, type MindooDBAppQueryTextClause as bB, type MindooDBAppReadableAttachmentStream as bC, type MindooDBAppRecipientOptions as bD, type MindooDBAppResolvedViewDefinition as bE, type MindooDBAppResolvedViewSource as bF, type MindooDBAppRevisionPhase as bG, type MindooDBAppRevisionVerification as bH, type MindooDBAppRichTextBlockSpan as bI, type MindooDBAppRichTextGetOptions as bJ, type MindooDBAppRichTextImmutableString as bK, type MindooDBAppRichTextMarkRange as bL, type MindooDBAppRichTextMaterializeValue as bM, type MindooDBAppRichTextPatch as bN, type MindooDBAppRichTextScalar as bO, type MindooDBAppRichTextSpliceStep as bP, type MindooDBAppRichTextStep as bQ, type MindooDBAppRichTextStepPatch as bR, type MindooDBAppRichTextTextSpan as bS, type MindooDBAppRuntime as bT, type MindooDBAppScanAttachmentOptions as bU, type MindooDBAppScanAttachmentResult as bV, type MindooDBAppScopedDocId as bW, type MindooDBAppScopedDocumentSummary as bX, type MindooDBAppSealIntent as bY, type MindooDBAppSealedChannelOpenInput as bZ, type MindooDBAppSealedChannelOpenResult as b_, type MindooDBAppJsonTextSplicePatch as ba, type MindooDBAppJsonTextUnmarkPatch as bb, type MindooDBAppJsonUnsetPatch as bc, type MindooDBAppLaunchContext as bd, type MindooDBAppLiveQuerySubscription as be, type MindooDBAppMenuAnchor as bf, type MindooDBAppMenuApi as bg, type MindooDBAppMenuCommandItem as bh, type MindooDBAppMenuDismissReason as bi, type MindooDBAppMenuDismissedResult as bj, type MindooDBAppMenuItem as bk, type MindooDBAppMenuKind as bl, type MindooDBAppMenuPlacement as bm, type MindooDBAppMenuPointAnchor as bn, type MindooDBAppMenuRect as bo, type MindooDBAppMenuRectAnchor as bp, type MindooDBAppMenuSelectionResult as bq, type MindooDBAppMenuSeparatorItem as br, type MindooDBAppProposeAppInput as bs, type MindooDBAppProposeAppResult as bt, type MindooDBAppQueryCoverage as bu, type MindooDBAppQueryInclude as bv, type MindooDBAppQueryIncludeCardinality as bw, type MindooDBAppQueryIncludeSlots as bx, type MindooDBAppQueryResult as by, type MindooDBAppQueryRow as bz, type MindooDBAppDragStartResult as c, type MindooDBAppSession as c0, type MindooDBAppShowMenuInput as c1, type MindooDBAppShowMenuResult as c2, type MindooDBAppSignPreview as c3, type MindooDBAppSignPreviewScope as c4, type MindooDBAppSignStatementInput as c5, type MindooDBAppSignStatementResult as c6, type MindooDBAppStorageApi as c7, type MindooDBAppTextEdit as c8, type MindooDBAppTextPatch as c9, type MindooDBAppThemeMode as ca, type MindooDBAppTimestampApi as cb, type MindooDBAppTimestampInput as cc, type MindooDBAppTimestampProvider as cd, type MindooDBAppTimestampResult as ce, type MindooDBAppUiPreferences as cf, type MindooDBAppUpdateDocumentInput as cg, type MindooDBAppViewCursorDocumentListResult as ch, type MindooDBAppViewCursorResult as ci, type MindooDBAppViewEntry as cj, type MindooDBAppViewEntryKind as ck, type MindooDBAppViewNavigator as cl, type MindooDBAppViewNavigatorExpansionState as cm, type MindooDBAppViewNavigatorOpenOptions as cn, type MindooDBAppViewNavigatorPageOptions as co, type MindooDBAppViewNavigatorPageResult as cp, type MindooDBAppViewNavigatorRangeQuery as cq, type MindooDBAppViewNavigatorSelectionState as cr, type MindooDBAppViewUpdateStats as cs, type MindooDBAppViewport as ct, type MindooDBAppWellKnownDragType as cu, type MindooDBAppWritableAttachmentStream as cv, resolveMindooDBAppDefinitionUrl as cw, validateMindooDBAppDefinition as cx, type MindooDBAppDragPreview as d, type MindooDBAppBridge as e, type MindooDBAppHostShortcutBinding as f, type MindooDBAppHostShortcutAction as g, type MindooDBAppHostingMode as h, type MindooDBAppDatabase as i, type MindooDBAppDocument as j, type MindooDBAppRichTextSpan as k, type MindooDBAppRichTextSnapshot as l, MINDOODB_APP_DEFINITION_FILE_NAME as m, MINDOODB_APP_DEFINITION_FORMAT as n, MINDOODB_APP_DEFINITION_PERMISSIONS as o, MINDOODB_APP_DEFINITION_REGISTRATION_PERMISSIONS as p, MINDOODB_APP_DEFINITION_VERSION as q, MINDOODB_APP_SEAL_SIGNING_DOMAIN as r, MINDOODB_APP_WELL_KNOWN_DRAG_TYPES as s, type MindooDBAppAccessDecision as t, type MindooDBAppAccessTier as u, type MindooDBAppAttachmentApi as v, type MindooDBAppAttachmentChunk as w, type MindooDBAppAttachmentInfo as x, type MindooDBAppAttachmentPreviewOptions as y, type MindooDBAppAttachmentPreviewSession 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.48",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.13.0"
|
|
6
6
|
},
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"mindoodb-view-language": "0.0.
|
|
44
|
+
"mindoodb-view-language": "0.0.18"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@automerge/automerge": "^3.3.2",
|
|
48
|
-
"mindoodb": ">=0.0.
|
|
48
|
+
"mindoodb": ">=0.0.64"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"@automerge/automerge": {
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@automerge/automerge": "^3.3.2",
|
|
60
|
-
"mindoodb": "^0.0.
|
|
60
|
+
"mindoodb": "^0.0.64",
|
|
61
61
|
"@types/node": "25.5.0",
|
|
62
62
|
"jsdom": "^29.0.1",
|
|
63
63
|
"tsup": "^8.5.1",
|