@multiplatform.one/frappe-ui 7.10.0 → 7.11.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/frappe-ui",
3
- "version": "7.10.0",
3
+ "version": "7.11.0",
4
4
  "description": "Pre-wired Tamagui components for Frappe doctypes with live data",
5
5
  "keywords": [
6
6
  "cross-platform",
@@ -72,6 +72,18 @@
72
72
  "access": "public"
73
73
  },
74
74
  "dependencies": {
75
+ "@multiplatform.one/components": "7.11.0",
76
+ "@multiplatform.one/desktop": "7.11.0",
77
+ "@multiplatform.one/forms": "7.11.0",
78
+ "@multiplatform.one/frappe": "7.11.0",
79
+ "@multiplatform.one/i18n": "7.11.0",
80
+ "@multiplatform.one/markdown": "7.11.0",
81
+ "@multiplatform.one/platform": "7.11.0",
82
+ "@multiplatform.one/rich-text": "7.11.0",
83
+ "@multiplatform.one/router": "7.11.0",
84
+ "@multiplatform.one/store": "7.11.0",
85
+ "@multiplatform.one/table": "7.11.0",
86
+ "@multiplatform.one/theme": "7.11.0",
75
87
  "@phosphor-icons/react": "^2.1.10",
76
88
  "@tamagui/colors": "2.7.6",
77
89
  "@tanstack/db": "0.6.5",
@@ -84,21 +96,12 @@
84
96
  "@tiptap/starter-kit": "^3.30.0",
85
97
  "html5-qrcode": "^2.3.8",
86
98
  "signature_pad": "^5.1.3",
87
- "tamagui": "2.7.6",
88
- "@multiplatform.one/frappe": "7.10.0",
89
- "@multiplatform.one/components": "7.10.0",
90
- "@multiplatform.one/forms": "7.10.0",
91
- "@multiplatform.one/desktop": "7.10.0",
92
- "@multiplatform.one/i18n": "7.10.0",
93
- "@multiplatform.one/router": "7.10.0",
94
- "@multiplatform.one/platform": "7.10.0",
95
- "@multiplatform.one/store": "7.10.0",
96
- "@multiplatform.one/markdown": "7.10.0",
97
- "@multiplatform.one/rich-text": "7.10.0",
98
- "@multiplatform.one/table": "7.10.0",
99
- "@multiplatform.one/theme": "7.10.0"
99
+ "tamagui": "2.7.6"
100
100
  },
101
101
  "devDependencies": {
102
+ "@multiplatform.one/config": "7.11.0",
103
+ "@multiplatform.one/storybook": "7.11.0",
104
+ "@multiplatform.one/test-utils": "7.11.0",
102
105
  "@tamagui/build": "2.7.6",
103
106
  "@testing-library/jest-dom": "^6.9.1",
104
107
  "@testing-library/react": "^16.3.2",
@@ -108,10 +111,7 @@
108
111
  "react": "19.2.5",
109
112
  "react-dom": "19.2.5",
110
113
  "react-i18next": "^16.6.6",
111
- "vitest": "^4.1.5",
112
- "@multiplatform.one/config": "7.10.0",
113
- "@multiplatform.one/storybook": "7.10.0",
114
- "@multiplatform.one/test-utils": "7.10.0"
114
+ "vitest": "^4.1.5"
115
115
  },
116
116
  "peerDependencies": {
117
117
  "@react-native-community/datetimepicker": ">=8.0.1",
@@ -0,0 +1,502 @@
1
+ import React, { useEffect } from "react";
2
+ import { act, cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
3
+ import { afterEach, beforeEach, expect, it, vi } from "vitest";
4
+ import {
5
+ getFrappeSyncModule,
6
+ useFrappeCatchUp,
7
+ useFrappeCollection,
8
+ useFrappeInfiniteList,
9
+ useLiveQuery,
10
+ type SyncModule,
11
+ type UseFrappeCollectionConfig,
12
+ } from "@multiplatform.one/frappe";
13
+ import { FrappeProvider, useFrappeConfig } from "./FrappeProvider";
14
+ import { BackfillScope } from "../../frappe/src/sync/types";
15
+
16
+ const { sockets } = vi.hoisted(() => ({
17
+ sockets: [] as Array<{
18
+ connected: boolean;
19
+ deliver: (event: string, payload?: unknown) => void;
20
+ }>,
21
+ }));
22
+ vi.mock("socket.io-client", () => ({
23
+ io: () => {
24
+ const listeners = new Map<string, Set<(payload?: unknown) => void>>();
25
+ const socket = {
26
+ id: "synthetic",
27
+ connected: false,
28
+ auth: {},
29
+ io: { on: vi.fn(), opts: {} },
30
+ on(event: string, handler: (payload?: unknown) => void) {
31
+ if (!listeners.has(event)) listeners.set(event, new Set());
32
+ listeners.get(event)!.add(handler);
33
+ return socket;
34
+ },
35
+ off(event: string, handler: (payload?: unknown) => void) {
36
+ listeners.get(event)?.delete(handler);
37
+ return socket;
38
+ },
39
+ emit: vi.fn(),
40
+ connect() {
41
+ socket.connected = true;
42
+ socket.deliver("connect");
43
+ return socket;
44
+ },
45
+ disconnect() {
46
+ socket.connected = false;
47
+ return socket;
48
+ },
49
+ removeAllListeners() {
50
+ listeners.clear();
51
+ return socket;
52
+ },
53
+ deliver(event: string, payload?: unknown) {
54
+ if (event === "connect") socket.connected = true;
55
+ if (event === "disconnect") socket.connected = false;
56
+ for (const listener of listeners.get(event) ?? []) listener(payload);
57
+ },
58
+ };
59
+ sockets.push(socket);
60
+ return socket;
61
+ },
62
+ }));
63
+
64
+ interface Task {
65
+ name: string;
66
+ doctype: string;
67
+ title: string;
68
+ modified: string;
69
+ }
70
+ const row = (name: string, title = name): Task => ({
71
+ name,
72
+ title,
73
+ doctype: "Task",
74
+ modified: "2026-09-09T00:00:00Z",
75
+ });
76
+ const modules = new Set<SyncModule>();
77
+ const observed = new Map<string, { sync: SyncModule; collection: unknown }>();
78
+ let sequence = 0;
79
+ function connection(): UseFrappeCollectionConfig {
80
+ return { baseURL: `https://public-catch-up-${++sequence}.test`, realtime: false };
81
+ }
82
+ function Probe({ label = "main" }: { label?: string }) {
83
+ const config = useFrappeConfig();
84
+ const sync = getFrappeSyncModule(config)!;
85
+ modules.add(sync);
86
+ const collection = useFrappeCollection<Task>(config, "Task", { filters: [["title", "!=", ""]] });
87
+ const query = useLiveQuery(
88
+ (q) => (collection ? q.from({ task: collection }) : null),
89
+ [collection],
90
+ );
91
+ const state = useFrappeCatchUp(config);
92
+ useEffect(() => {
93
+ observed.set(label, { sync, collection });
94
+ }, [label, sync, collection]);
95
+ return (
96
+ <section>
97
+ <output data-testid={`${label}-rows`}>
98
+ {query.data
99
+ ?.map((task) => `${task.name}:${task.title}`)
100
+ .sort()
101
+ .join(",")}
102
+ </output>
103
+ <output data-testid={`${label}-state`}>
104
+ {state.refreshing ? "refreshing" : "idle"}/{state.stale ? "stale" : "current"}
105
+ </output>
106
+ {state.error ? (
107
+ <p role="alert">
108
+ {state.error instanceof Error ? state.error.message : String(state.error)}
109
+ </p>
110
+ ) : null}
111
+ <button
112
+ onClick={() => {
113
+ void state.retry();
114
+ }}
115
+ >
116
+ Retry {label}
117
+ </button>
118
+ </section>
119
+ );
120
+ }
121
+ function InfiniteProbe() {
122
+ const config = useFrappeConfig();
123
+ const sync = getFrappeSyncModule(config)!;
124
+ modules.add(sync);
125
+ const list = useFrappeInfiniteList<Task>({ config, doctype: "Task" });
126
+ return (
127
+ <output data-testid="infinite">
128
+ {list.error?.message ?? list.items.map((item) => item.name).join(",")}
129
+ </output>
130
+ );
131
+ }
132
+ function server() {
133
+ let rows = [row("a"), row("b")];
134
+ let status = 200;
135
+ let cdc = {
136
+ rows: [] as Task[],
137
+ deleted: [] as { name: string }[],
138
+ checkpoint: "next",
139
+ has_more: false,
140
+ };
141
+ const urls: URL[] = [];
142
+ let gate: Promise<Response> | undefined;
143
+ const fetch = vi.fn(async (input: RequestInfo | URL) => {
144
+ const url = new URL(
145
+ typeof input === "string" ? input : input instanceof URL ? input.href : input.url,
146
+ );
147
+ urls.push(url);
148
+ if (gate) {
149
+ const pending = gate;
150
+ gate = undefined;
151
+ return pending;
152
+ }
153
+ if (status !== 200) return Response.json({ message: "Service unavailable" }, { status });
154
+ if (url.pathname === "/api/resource/Task") return Response.json({ data: rows });
155
+ if (url.pathname.startsWith("/api/resource/Task/")) {
156
+ const doc = rows.find((item) => item.name === url.pathname.split("/").at(-1));
157
+ return Response.json({ data: doc }, { status: doc ? 200 : 404 });
158
+ }
159
+ if (url.pathname === "/api/method/live.live.api.backfill")
160
+ return Response.json({ message: cdc });
161
+ return Response.json({ message: "Unsupported method" }, { status: 404 });
162
+ });
163
+ vi.stubGlobal("fetch", fetch);
164
+ return {
165
+ fetch,
166
+ urls,
167
+ setRows: (value: Task[]) => {
168
+ rows = value;
169
+ },
170
+ setStatus: (value: number) => {
171
+ status = value;
172
+ },
173
+ setCdc: (value: typeof cdc) => {
174
+ cdc = value;
175
+ },
176
+ hold: () => {
177
+ let resolve!: (value: Response) => void;
178
+ gate = new Promise<Response>((done) => {
179
+ resolve = done;
180
+ });
181
+ return resolve;
182
+ },
183
+ resources: () => urls.filter((url) => url.pathname === "/api/resource/Task"),
184
+ methods: () => urls.filter((url) => url.pathname.startsWith("/api/method/")),
185
+ };
186
+ }
187
+ async function expectRows(value: string, label = "main") {
188
+ await waitFor(() => expect(screen.getByTestId(`${label}-rows`).textContent).toBe(value));
189
+ }
190
+ async function expectIdle(label = "main") {
191
+ await waitFor(() =>
192
+ expect(screen.getByTestId(`${label}-state`).textContent).toBe("idle/current"),
193
+ );
194
+ }
195
+ beforeEach(() => {
196
+ sockets.length = 0;
197
+ observed.clear();
198
+ });
199
+ afterEach(async () => {
200
+ cleanup();
201
+ for (const sync of modules) await sync.dispose();
202
+ modules.clear();
203
+ vi.unstubAllGlobals();
204
+ vi.useRealTimers();
205
+ });
206
+
207
+ it("refreshes resource-only mounted collections for focus and online without CDC/cursor requests", async () => {
208
+ const api = server();
209
+ const config = {
210
+ ...connection(),
211
+ syncOptions: { catchUpStrategy: "snapshot" as const, cdcInterval: 60000 },
212
+ };
213
+ render(
214
+ <FrappeProvider {...config}>
215
+ <Probe />
216
+ </FrappeProvider>,
217
+ );
218
+ await expectRows("a:a,b:b");
219
+ const initial = observed.get("main")!;
220
+ api.setRows([row("a", "edited"), row("c")]);
221
+ fireEvent(window, new Event("focus"));
222
+ await expectRows("a:edited,c:c");
223
+ await expectIdle();
224
+ api.setRows([]);
225
+ fireEvent(window, new Event("online"));
226
+ await expectRows("");
227
+ await expectIdle();
228
+ expect(observed.get("main")!.collection).toBe(initial.collection);
229
+ expect(api.methods()).toEqual([]);
230
+ expect(api.resources()).toHaveLength(3);
231
+ });
232
+
233
+ it("dispatches the enabled interval through the public snapshot provider", async () => {
234
+ vi.useFakeTimers();
235
+ const api = server();
236
+ render(
237
+ <FrappeProvider
238
+ {...connection()}
239
+ syncOptions={{ catchUpStrategy: "snapshot", cdcInterval: 1000 }}
240
+ >
241
+ <Probe />
242
+ </FrappeProvider>,
243
+ );
244
+ await act(async () => {
245
+ await vi.advanceTimersByTimeAsync(50);
246
+ });
247
+ expect(screen.getByTestId("main-rows").textContent).toBe("a:a,b:b");
248
+ api.setRows([row("timer")]);
249
+ await act(async () => {
250
+ await vi.advanceTimersByTimeAsync(1000);
251
+ });
252
+ expect(screen.getByTestId("main-rows").textContent).toBe("timer:timer");
253
+ expect(api.resources()).toHaveLength(2);
254
+ expect(api.methods()).toEqual([]);
255
+ });
256
+
257
+ it("retains rows through a real HTTP 503, renders qualification, and retries without remounting", async () => {
258
+ const api = server();
259
+ const config = { ...connection(), syncOptions: { catchUpStrategy: "snapshot" as const } };
260
+ const view = render(
261
+ <FrappeProvider {...config}>
262
+ <Probe />
263
+ </FrappeProvider>,
264
+ );
265
+ await expectRows("a:a,b:b");
266
+ const initial = observed.get("main")!.collection;
267
+ const release = api.hold();
268
+ api.setStatus(503);
269
+ fireEvent(window, new Event("focus"));
270
+ await waitFor(() => expect(api.resources()).toHaveLength(2));
271
+ expect(screen.getByTestId("main-state").textContent).toBe("refreshing/current");
272
+ expect(screen.getByTestId("main-rows").textContent).toBe("a:a,b:b");
273
+ release(Response.json({ message: "Service unavailable" }, { status: 503 }));
274
+ await waitFor(() => expect(screen.getByTestId("main-state").textContent).toBe("idle/stale"), {
275
+ timeout: 4000,
276
+ });
277
+ expect(screen.getByRole("alert").textContent).toContain("Showing previous data");
278
+ expect(api.resources()).toHaveLength(5);
279
+ view.rerender(
280
+ <FrappeProvider {...config}>
281
+ <Probe />
282
+ </FrappeProvider>,
283
+ );
284
+ expect(api.resources()).toHaveLength(5);
285
+ api.setStatus(200);
286
+ api.setRows([row("recovered")]);
287
+ const retryRelease = api.hold();
288
+ fireEvent.click(screen.getByRole("button", { name: "Retry main" }));
289
+ await waitFor(() => expect(api.resources()).toHaveLength(6));
290
+ expect(screen.getByTestId("main-state").textContent).toBe("refreshing/stale");
291
+ retryRelease(Response.json({ data: [row("recovered")] }));
292
+ await expectRows("recovered:recovered");
293
+ await expectIdle();
294
+ expect(screen.queryByRole("alert")).toBeNull();
295
+ expect(observed.get("main")!.collection).toBe(initial);
296
+ expect(api.methods()).toEqual([]);
297
+ });
298
+
299
+ it.each(["snapshot", "cdc"] as const)(
300
+ "routes real socket reconnect with %s strategy and preserves realtime delivery",
301
+ async (strategy) => {
302
+ const api = server();
303
+ render(
304
+ <FrappeProvider {...connection()} realtime syncOptions={{ catchUpStrategy: strategy }}>
305
+ <Probe />
306
+ </FrappeProvider>,
307
+ );
308
+ await expectRows("a:a,b:b");
309
+ await waitFor(() => expect(sockets).toHaveLength(1));
310
+ await expectIdle();
311
+ const initialCount = api.urls.length;
312
+ api.setRows([row("socket")]);
313
+ api.setCdc({
314
+ rows: [row("socket")],
315
+ deleted: [{ name: "a" }, { name: "b" }],
316
+ checkpoint: "socket-checkpoint",
317
+ has_more: false,
318
+ });
319
+ act(() => {
320
+ sockets[0].deliver("disconnect", "transport close");
321
+ sockets[0].deliver("connect");
322
+ });
323
+ await expectRows("socket:socket");
324
+ await expectIdle();
325
+ const catchup = api.urls.slice(initialCount);
326
+ expect(
327
+ catchup.some(
328
+ (url) =>
329
+ url.pathname ===
330
+ (strategy === "snapshot" ? "/api/resource/Task" : "/api/method/live.live.api.backfill"),
331
+ ),
332
+ ).toBe(true);
333
+ if (strategy === "snapshot") expect(api.methods()).toEqual([]);
334
+ else {
335
+ expect(observed.get("main")!.sync.__debug().subscriptions[0].checkpoint).toBe(
336
+ "socket-checkpoint",
337
+ );
338
+ fireEvent(window, new Event("online"));
339
+ await waitFor(() =>
340
+ expect(api.methods().at(-1)?.searchParams.get("modified_after")).toBe("socket-checkpoint"),
341
+ );
342
+ await expectIdle();
343
+ }
344
+ api.setRows([row("socket", "realtime edit")]);
345
+ act(() => {
346
+ sockets[0].deliver("doc_update", { doctype: "Task", name: "socket" });
347
+ });
348
+ await expectRows("socket:realtime edit");
349
+ },
350
+ );
351
+
352
+ it("uses CDC when omitted, observes background rejection, and keeps explicit backfill rejecting", async () => {
353
+ const api = server();
354
+ render(
355
+ <FrappeProvider {...connection()}>
356
+ <Probe />
357
+ </FrappeProvider>,
358
+ );
359
+ await expectRows("a:a,b:b");
360
+ api.setStatus(404);
361
+ fireEvent(window, new Event("focus"));
362
+ await waitFor(() => expect(screen.getByTestId("main-state").textContent).toBe("idle/stale"));
363
+ const sync = observed.get("main")!.sync;
364
+ await expect(sync.backfill({ scope: BackfillScope.All })).rejects.toMatchObject({ status: 404 });
365
+ expect(api.methods()[0].searchParams.get("modified_after")).toBe(row("a").modified);
366
+ api.setStatus(200);
367
+ api.setCdc({
368
+ rows: [row("c")],
369
+ deleted: [{ name: "a" }],
370
+ checkpoint: "recovered-checkpoint",
371
+ has_more: false,
372
+ });
373
+ fireEvent.click(screen.getByRole("button", { name: "Retry main" }));
374
+ await expectRows("b:b,c:c");
375
+ await expectIdle();
376
+ });
377
+
378
+ it("isolates same-origin strategy providers and switches collection and state together", async () => {
379
+ const api = server();
380
+ const config = connection();
381
+ const draw = (strategy: "snapshot" | "cdc") => (
382
+ <>
383
+ <FrappeProvider {...config} syncOptions={{ catchUpStrategy: strategy }}>
384
+ <Probe label="left" />
385
+ </FrappeProvider>
386
+ <FrappeProvider {...config}>
387
+ <Probe label="right" />
388
+ </FrappeProvider>
389
+ </>
390
+ );
391
+ const view = render(draw("snapshot"));
392
+ await expectRows("a:a,b:b", "left");
393
+ await expectRows("a:a,b:b", "right");
394
+ expect(observed.get("left")!.sync).not.toBe(observed.get("right")!.sync);
395
+ expect(observed.get("left")!.collection).not.toBe(observed.get("right")!.collection);
396
+ const left = observed.get("left")!.collection;
397
+ view.rerender(draw("snapshot"));
398
+ expect(observed.get("left")!.collection).toBe(left);
399
+ api.setRows([row("snapshot")]);
400
+ api.setCdc({
401
+ rows: [row("cdc")],
402
+ deleted: [{ name: "a" }, { name: "b" }],
403
+ checkpoint: "separate",
404
+ has_more: false,
405
+ });
406
+ fireEvent(window, new Event("focus"));
407
+ await expectRows("snapshot:snapshot", "left");
408
+ await expectRows("cdc:cdc", "right");
409
+ view.rerender(draw("cdc"));
410
+ await expectRows("cdc:cdc", "left");
411
+ expect(observed.get("left")!.collection).toBe(observed.get("right")!.collection);
412
+ expect(observed.get("left")!.sync).toBe(observed.get("right")!.sync);
413
+ });
414
+
415
+ it("refuses progressive snapshot subscriptions through the public hook, with CDC control", async () => {
416
+ const api = server();
417
+ const config = connection();
418
+ const view = render(
419
+ <FrappeProvider {...config} syncOptions={{ catchUpStrategy: "snapshot" }}>
420
+ <InfiniteProbe />
421
+ </FrappeProvider>,
422
+ );
423
+ await waitFor(() =>
424
+ expect(screen.getByTestId("infinite").textContent).toContain("does not support progressive"),
425
+ );
426
+ expect(api.urls).toEqual([]);
427
+ view.rerender(
428
+ <FrappeProvider {...config}>
429
+ <InfiniteProbe />
430
+ </FrappeProvider>,
431
+ );
432
+ await waitFor(() => expect(screen.getByTestId("infinite").textContent).toBe("a,b"));
433
+ expect(api.resources()).toHaveLength(1);
434
+ });
435
+
436
+ it("keeps explicit CDC backfill rejecting even on a snapshot provider", async () => {
437
+ const api = server();
438
+ render(
439
+ <FrappeProvider {...connection()} syncOptions={{ catchUpStrategy: "snapshot" }}>
440
+ <Probe />
441
+ </FrappeProvider>,
442
+ );
443
+ await expectRows("a:a,b:b");
444
+ expect(api.methods()).toEqual([]);
445
+ api.setStatus(404);
446
+ await expect(
447
+ observed.get("main")!.sync.backfill({ scope: BackfillScope.All }),
448
+ ).rejects.toMatchObject({ status: 404 });
449
+ expect(api.methods()).toHaveLength(1);
450
+ expect(api.methods()[0].pathname).toBe("/api/method/live.live.api.backfill");
451
+ });
452
+
453
+ it("coalesces mounted lifecycle overlap into one trailing read", async () => {
454
+ const api = server();
455
+ render(
456
+ <FrappeProvider {...connection()} syncOptions={{ catchUpStrategy: "snapshot" }}>
457
+ <Probe />
458
+ </FrappeProvider>,
459
+ );
460
+ await expectRows("a:a,b:b");
461
+ const first = api.hold();
462
+ fireEvent(window, new Event("focus"));
463
+ await waitFor(() => expect(api.resources()).toHaveLength(2));
464
+ const trailing = api.hold();
465
+ fireEvent(window, new Event("online"));
466
+ fireEvent.click(screen.getByRole("button", { name: "Retry main" }));
467
+ first(Response.json({ data: [row("earlier")] }));
468
+ await waitFor(() => expect(api.resources()).toHaveLength(3));
469
+ for (let i = 0; i < 10; i++) fireEvent(window, new Event("focus"));
470
+ trailing(Response.json({ data: [row("latest")] }));
471
+ await expectRows("latest:latest");
472
+ await expectIdle();
473
+ expect(api.resources()).toHaveLength(3);
474
+ expect(api.methods()).toEqual([]);
475
+ });
476
+
477
+ it("does not publish an obsolete failure after the mounted provider is reset and unmounted", async () => {
478
+ const api = server();
479
+ const view = render(
480
+ <FrappeProvider {...connection()} syncOptions={{ catchUpStrategy: "snapshot" }}>
481
+ <Probe />
482
+ </FrappeProvider>,
483
+ );
484
+ await expectRows("a:a,b:b");
485
+ const sync = observed.get("main")!.sync;
486
+ const release = api.hold();
487
+ let pending!: ReturnType<SyncModule["catchUp"]>;
488
+ act(() => {
489
+ pending = sync.catchUp();
490
+ });
491
+ await waitFor(() => expect(api.resources()).toHaveLength(2));
492
+ view.unmount();
493
+ sync.resetCache();
494
+ const idle = sync.getCatchUpState();
495
+ const listener = vi.fn();
496
+ const unsubscribe = sync.subscribeStore(listener);
497
+ release(Response.json({ message: "obsolete" }, { status: 404 }));
498
+ await pending;
499
+ expect(sync.getCatchUpState()).toBe(idle);
500
+ expect(listener).not.toHaveBeenCalled();
501
+ unsubscribe();
502
+ });
@@ -49,7 +49,7 @@ export interface FrappeConfig {
49
49
  type?: string;
50
50
  };
51
51
  /** Sync options for the live data engine */
52
- syncOptions?: any;
52
+ syncOptions?: UseFrappeCollectionConfig["syncOptions"];
53
53
  /**
54
54
  * Extra Socket.IO client options for the realtime connection — e.g.
55
55
  * `{ transports: ["polling", "websocket"] }` behind dev proxies that
@@ -93,7 +93,7 @@ export interface FrappeProviderProps {
93
93
  type?: string;
94
94
  };
95
95
  /** Sync options for the live data engine */
96
- syncOptions?: any;
96
+ syncOptions?: UseFrappeCollectionConfig["syncOptions"];
97
97
  /** Extra Socket.IO client options for the realtime connection. */
98
98
  socketOptions?: UseFrappeCollectionConfig["socketOptions"];
99
99
  /**
@@ -48,7 +48,7 @@ export interface FrappeConfig {
48
48
  type?: string;
49
49
  };
50
50
  /** Sync options for the live data engine */
51
- syncOptions?: any;
51
+ syncOptions?: UseFrappeCollectionConfig["syncOptions"];
52
52
  /**
53
53
  * Extra Socket.IO client options for the realtime connection — e.g.
54
54
  * `{ transports: ["polling", "websocket"] }` behind dev proxies that
@@ -89,7 +89,7 @@ export interface FrappeProviderProps {
89
89
  type?: string;
90
90
  };
91
91
  /** Sync options for the live data engine */
92
- syncOptions?: any;
92
+ syncOptions?: UseFrappeCollectionConfig["syncOptions"];
93
93
  /** Extra Socket.IO client options for the realtime connection. */
94
94
  socketOptions?: UseFrappeCollectionConfig["socketOptions"];
95
95
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"FrappeProvider.d.ts","sourceRoot":"","sources":["../src/FrappeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL,gDAAgD;QAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,sFAAsF;QACtF,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,8BAA8B;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,4CAA4C;IAC5C,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAID;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,uBAAuB;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL,gDAAgD;QAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,sFAAsF;QACtF,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,8BAA8B;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,4CAA4C;IAC5C,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,kEAAkE;IAClE,aAAa,CAAC,EAAE,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,aAAa,EACb,QAAQ,GACT,EAAE,mBAAmB,2CA2BrB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,SAAS,CAE1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,SAAS,CAE3D"}
1
+ {"version":3,"file":"FrappeProvider.d.ts","sourceRoot":"","sources":["../src/FrappeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL,gDAAgD;QAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,sFAAsF;QACtF,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,8BAA8B;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,4CAA4C;IAC5C,WAAW,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACvD;;;;OAIG;IACH,aAAa,CAAC,EAAE,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAID;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,uBAAuB;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE;QACL,gDAAgD;QAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,sFAAsF;QACtF,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,8BAA8B;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,4CAA4C;IAC5C,WAAW,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACvD,kEAAkE;IAClE,aAAa,CAAC,EAAE,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,aAAa,EACb,QAAQ,GACT,EAAE,mBAAmB,2CA2BrB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,SAAS,CAE1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,SAAS,CAE3D"}