Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/quick-bats-queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@proofkit/webviewer": minor
"@proofkit/fmdapi": minor
---

Add default WebViewerAdapter batching with per-request `batch: true`/`batch: false` controls and a maximum batch size of 20.
`batch: false` now disables request coalescing while still sending single-request batch payloads, falling back to the older direct request path only after an installed FileMaker add-on script reports that batching is unsupported.
`listAll` and `findAll` now page through bounded `read` requests in the adapter, batching follow-up pages when enabled, and older FileMaker add-on scripts fall back to unbatched requests with a warning that links to batching docs.
Docs include tuning guidance for benchmarking batch size, page size, payload size, script execution path, and ProofKit add-on version requirements against real FileMaker layouts and found sets.
90 changes: 90 additions & 0 deletions apps/docs/content/docs/webviewer/batching.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: Batching Data API Requests
description: Coalesce FileMaker Data API requests from a Web Viewer in fewer script calls
---

import { Callout } from "fumadocs-ui/components/callout";
import { Badge } from "@/components/ui/badge";

<div className="not-prose mb-6 flex flex-wrap gap-2">
<Badge appearance="light" variant="primary">
@proofkit/webviewer 3.2.0+
</Badge>
<Badge appearance="light" variant="primary">
@proofkit/fmdapi 5.2.0+
</Badge>
<Badge appearance="light" variant="primary">
ProofKit add-on 3.0+
</Badge>
</div>

`WebViewerAdapter` batches Data API calls by default, coalescing requests that happen within a short window into one FileMaker script call. This can reduce Web Viewer bridge round trips, but FileMaker still executes the enclosed Data API operations sequentially inside your script. This is mostly done for better developer experience to avoid so many scripts in your call stack, but can sometimes also improve data loading speed (especially when calling `Execute Data API` in a server-side script).

<Callout type="info" title="Benchmark with your own layouts">
FileMaker performance depends heavily on whether the script runs locally or on FileMaker Server, plus the layout, table, found set, and amount of data returned. Benchmark both `maxSize` and page `limit` with your own layouts, including field count, portal rows, and container fields, before assuming the defaults are fastest for every file.
</Callout>

```ts title="client.ts"
import { DataApi } from "@proofkit/fmdapi";
import { WebViewerAdapter } from "@proofkit/webviewer/adapter";

export const client = DataApi({
adapter: new WebViewerAdapter({
scriptName: "ExecuteDataApi",
batch: {
windowMs: 16,
maxSize: 10,
},
}),
layout: "API_Customers",
});
```

## Per-request control

Use `batch: false` on a request to keep that call out of coalesced batches:

```ts
await client.list({ batch: false, limit: 10 });
```

Use `batch: true` on a request to coalesce that call even when adapter-level coalescing was disabled:

```ts
await client.find({
batch: true,
query: { status: "Active" },
});
```

Per-request batching uses the adapter's configured batch settings when present. If the adapter was configured with `batch: false`, `batch: true` uses the default 8 ms window and maximum batch size of 20.

To disable coalescing for every request unless it opts in, set `batch: false` on the adapter:

```ts
new WebViewerAdapter({
scriptName: "ExecuteDataApi",
batch: false,
});
```

When coalescing is disabled, ProofKit still uses the batch-compatible FileMaker script format one request at a time. It only uses the older direct request format after a FileMaker file reports that its installed ProofKit add-on script does not support batched Data API requests.

## All-record helpers

`listAll()` and `findAll()` never send `readAll` or `findAll` actions to FileMaker. The adapter sends one bounded `read` request first, uses `dataInfo.foundCount` to calculate the remaining pages, and then fetches those pages with bounded `read` requests.

When batching is enabled, the follow-up page requests can be batched in chunks up to `maxSize`. This reduces Web Viewer bridge round trips without asking the FileMaker script to load an unknown number of records into script variables.

<Callout type="warn" title="Tune page size separately">
`maxSize` controls how many page requests can share one script call. The request `limit` controls how many records each page returns.
For `listAll()`, `findAll()`, or your own manual paging, test page sizes such as `25`, `50`, `100`, `250`, and `500` with records from your own tables. Larger tables, wide layouts, portal-heavy layouts, or layouts with container fields may perform better with smaller pages.
</Callout>

Benchmarks showed page size can matter more than batch size for local `PK_execute_data_api` calls, while server-side script execution may benefit more from batching. Treat the defaults as a starting point, not a universal rule.

## ProofKit add-on version

Batching requires ProofKit add-on version 3.0 or later so the FileMaker scripts installed by the add-on understand batched Data API requests. If your FileMaker file has an older ProofKit add-on, ProofKit may run requests through the older direct request path until the add-on scripts are updated.

Install the latest ProofKit add-on in each FileMaker file where you want to take advantage of batched Data API requests. See [Updating ProofKit](/docs/ai/updating-proofkit) for the add-on update flow.
34 changes: 34 additions & 0 deletions apps/docs/content/docs/webviewer/fmdapi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,37 @@ const users = await UsersClient.findOne({ query: { id: "===1234" } });
```

For examples of all methods, see the [@proofkit/fmdapi](/docs/fmdapi) documentation.

## Batched Web Viewer Requests

`WebViewerAdapter` coalesces Data API calls that happen within a short window into one FileMaker script call by default. See [Batching Data API Requests](/docs/webviewer/batching) for per-request controls, tuning guidance, and add-on update requirements.

```ts title="client.ts"
import { DataApi } from "@proofkit/fmdapi";
import { WebViewerAdapter } from "@proofkit/webviewer/adapter";

export const client = DataApi({
adapter: new WebViewerAdapter({
scriptName: "ExecuteDataApi",
batch: {
windowMs: 16,
maxSize: 10,
},
}),
layout: "API_Customers",
});
```

Default coalescing uses an 8 ms window and maximum batch size of 20. Use `batch: false` on the adapter or an individual request to send requests one at a time through the batch-compatible FileMaker script format. Benchmark with your own file before assuming batching improves speed; a local `Execute FileMaker Data API` script may see little benefit compared with a script that runs on FileMaker Server.

## Adapter Pagination

For `client.listAll()` and `client.findAll()`, `WebViewerAdapter` does not send `readAll` or `findAll` actions to FileMaker. It sends a bounded first `read` request to get `dataInfo.foundCount`, then requests the remaining pages with the same limit.

If batching is enabled, those follow-up page requests can share FileMaker script calls. Each request is still a bounded `read` operation:

<Callout type="info" title="Page size is layout-specific">
For all-record helpers and manual paging, tune `limit` with your real FileMaker layouts, tables, and found sets. Try lower values such as `25` or `50` for layouts with many fields, portal rows, or container fields, then compare against larger pages such as `100`, `250`, and `500`.
</Callout>

This keeps all-record helpers from loading an unbounded result set into FileMaker variables before anything is returned to the Web Viewer.
1 change: 1 addition & 0 deletions apps/docs/content/docs/webviewer/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"filemaker-scripts-as-backend",
"commands",
"initial-props",
"batching",
"platform-notes",
"deployment-methods",
"---Reference---",
Expand Down
3 changes: 3 additions & 0 deletions packages/fmdapi/src/adapters/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
} from "../client-types.js";

export interface BaseRequest {
batch?: boolean;
layout: string;
fetch?: RequestInit;
timeout?: number;
Expand Down Expand Up @@ -53,8 +54,10 @@ export type LayoutMetadataOptions = BaseRequest;

export interface Adapter {
list: (opts: ListOptions) => Promise<GetResponse>;
listAll?: (opts: ListOptions) => Promise<GetResponse>;
get: (opts: GetOptions) => Promise<GetResponse>;
find: (opts: FindOptions) => Promise<GetResponse>;
findAll?: (opts: FindOptions) => Promise<GetResponse>;
create: (opts: CreateOptions) => Promise<CreateResponse>;
update: (opts: UpdateOptions) => Promise<UpdateResponse>;
delete: (opts: DeleteOptions) => Promise<DeleteResponse>;
Expand Down
Loading
Loading