amplifyquery 1.0.17 β†’ 1.0.19

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 CHANGED
@@ -8,9 +8,11 @@ A library that combines AWS Amplify and React Query, making it easier to manage
8
8
  - πŸ”„ **React Query Integration**: Leverage all React Query features like caching, retries, background updates, etc.
9
9
  - πŸ“± **Offline Support**: Persistent query caching via MMKV for fast data loading even offline.
10
10
  - πŸͺ **Convenient Hooks API**: Abstract complex data synchronization into simple Hooks.
11
+ - πŸ”΄ **Realtime Subscriptions**: Built-in support for AWS Amplify realtime updates with automatic cache synchronization.
11
12
  - πŸ›‘ **Auth Mode Support**: Supports various AWS Amplify authentication modes (API Key, IAM, Cognito, etc.).
12
13
  - βš™οΈ **Global Configuration**: Set model mappings and auth modes once - no more repetitive configuration.
13
14
  - ⚑ **Performance Optimized**: Maximize performance with request batching and intelligent caching.
15
+ - πŸ”„ **Automatic Cache Sync**: Mutations automatically update the cache for consistent UI state.
14
16
 
15
17
  ## Installation
16
18
 
@@ -192,6 +194,8 @@ await TodoService.delete("some-id");
192
194
 
193
195
  ### 5. Using React Hooks
194
196
 
197
+ #### Basic Usage
198
+
195
199
  ```tsx
196
200
  import React from "react";
197
201
  import { View, Text, Button } from "react-native";
@@ -206,11 +210,16 @@ function TodoScreen() {
206
210
  create,
207
211
  update,
208
212
  delete: deleteTodo,
213
+ getItem,
209
214
  } = TodoService.useHook();
210
215
 
211
216
  // Hook for managing a single item
212
- const { item: settings, update: updateSettings } =
213
- UserSettingsService.useItemHook(); // Assuming UserSettingsService is defined
217
+ const {
218
+ item: settings,
219
+ isLoading: isSettingsLoading,
220
+ update: updateSettings,
221
+ refresh: refreshSettings,
222
+ } = UserSettingsService.useItemHook("settings-id");
214
223
 
215
224
  if (isLoading) return <Text>Loading...</Text>;
216
225
  if (error) return <Text>Error: {error.message}</Text>;
@@ -237,8 +246,118 @@ function TodoScreen() {
237
246
  }
238
247
  ```
239
248
 
249
+ #### Realtime Subscriptions
250
+
251
+ Enable real-time updates using AWS Amplify's `observeQuery` feature:
252
+
253
+ ```tsx
254
+ function TodoScreen() {
255
+ // Enable realtime for list updates
256
+ const {
257
+ items: todos,
258
+ isLoading,
259
+ isSynced, // true when realtime subscription is active
260
+ create,
261
+ update,
262
+ delete: deleteTodo,
263
+ } = TodoService.useHook({
264
+ realtime: {
265
+ enabled: true,
266
+ // Optional: filter events to subscribe to
267
+ events: ["create", "update", "delete"],
268
+ },
269
+ });
270
+
271
+ // Enable realtime for single item updates
272
+ const {
273
+ item: todo,
274
+ isSynced: isItemSynced,
275
+ update: updateTodo,
276
+ } = TodoService.useItemHook(todoId, {
277
+ realtime: {
278
+ enabled: true,
279
+ },
280
+ });
281
+
282
+ return (
283
+ <View>
284
+ {isSynced && <Text>🟒 Live updates active</Text>}
285
+ {todos.map((todo) => (
286
+ <Text key={todo.id}>{todo.name}</Text>
287
+ ))}
288
+ </View>
289
+ );
290
+ }
291
+ ```
292
+
293
+ **Realtime Features:**
294
+ - βœ… Automatic cache synchronization when data changes
295
+ - βœ… Works across multiple devices/sessions
296
+ - βœ… `isSynced` flag indicates subscription status
297
+ - βœ… Optimistic updates are immediately reflected
298
+ - βœ… No manual refresh needed for real-time changes
299
+
300
+ **Note:** When `realtime.enabled` is `true`, the initial fetch is skipped to avoid duplicate data. The subscription provides the initial data set.
301
+
240
302
  ## Advanced Features
241
303
 
304
+ ### Realtime Subscriptions
305
+
306
+ AmplifyQuery supports real-time data synchronization using AWS Amplify's `observeQuery` API. When enabled, your UI automatically updates when data changes on the server or other devices.
307
+
308
+ #### useHook Realtime Options
309
+
310
+ ```typescript
311
+ const {
312
+ items,
313
+ isSynced, // true when subscription is active
314
+ create,
315
+ update,
316
+ delete: deleteItem,
317
+ } = TodoService.useHook({
318
+ realtime: {
319
+ enabled: true, // Enable realtime subscription
320
+ events: ["create", "update", "delete"], // Optional: filter events
321
+ observeOptions: {
322
+ // Optional: additional observeQuery options
323
+ filter: { completed: { eq: false } },
324
+ },
325
+ },
326
+ });
327
+ ```
328
+
329
+ #### useItemHook Realtime Options
330
+
331
+ ```typescript
332
+ const {
333
+ item,
334
+ isSynced, // true when subscription is active
335
+ update,
336
+ delete: deleteItem,
337
+ } = TodoService.useItemHook(todoId, {
338
+ realtime: {
339
+ enabled: true,
340
+ observeOptions: {
341
+ // Optional: additional observeQuery options
342
+ },
343
+ },
344
+ });
345
+ ```
346
+
347
+ #### How It Works
348
+
349
+ 1. **Initial Load**: When `realtime.enabled` is `true`, the hook subscribes to `observeQuery` instead of making a one-time fetch
350
+ 2. **Cache Updates**: All changes (create/update/delete) are automatically synchronized to the React Query cache
351
+ 3. **Cross-Device**: Changes made on other devices or sessions are immediately reflected
352
+ 4. **Optimistic Updates**: Local mutations are immediately reflected, then confirmed via realtime events
353
+
354
+ #### Best Practices
355
+
356
+ - Use realtime for collaborative features or when data changes frequently
357
+ - Monitor `isSynced` to show connection status to users
358
+ - Combine with optimistic updates for the best user experience
359
+ - Consider using `events` filter to reduce unnecessary updates
360
+
242
361
  ### Global Configuration
243
362
 
244
363
  AmplifyQuery supports global configuration to reduce code duplication and simplify service creation.
@@ -338,6 +457,25 @@ TodoService.resetCache();
338
457
  const todos = await TodoService.list({ forceRefresh: true });
339
458
  ```
340
459
 
460
+ #### Automatic Cache Synchronization
461
+
462
+ AmplifyQuery automatically synchronizes the cache when you use hook methods (`create`, `update`, `delete`):
463
+
464
+ - **Immediate Updates**: Changes are reflected in the UI immediately after successful operations
465
+ - **Consistent State**: The cache stays in sync across all hook instances
466
+ - **Optimistic Updates**: UI updates before server confirmation for better UX
467
+ - **Realtime Integration**: Works seamlessly with realtime subscriptions
468
+
469
+ ```tsx
470
+ // Create, update, delete automatically update the cache
471
+ const { create, update, delete: deleteItem } = TodoService.useHook();
472
+
473
+ // These operations immediately update the hook's items array
474
+ await create({ name: "New Todo" });
475
+ await update({ id: todoId, completed: true });
476
+ await deleteItem(todoId);
477
+ ```
478
+
341
479
  ### Authentication Modes
342
480
 
343
481
  Access data with various authentication methods.
@@ -363,10 +501,62 @@ await TodoService.list({ authMode: "iam" });
363
501
  const adminTodoService = TodoService.withAuthMode("iam");
364
502
  ```
365
503
 
504
+ ### Hook API Reference
505
+
506
+ #### useHook(options?)
507
+
508
+ Returns a hook for managing a list of items.
509
+
510
+ **Options:**
511
+ - `initialFetchOptions?: { fetch?: boolean, filter?: Record<string, any> }` - Control initial data fetch
512
+ - `customList?: { queryName: string, args: Record<string, any>, forceRefresh?: boolean }` - Use custom query for list
513
+ - `realtime?: { enabled?: boolean, observeOptions?: Record<string, any>, events?: Array<"create" | "update" | "delete"> }` - Enable realtime subscriptions
514
+
515
+ **Returns:**
516
+ ```typescript
517
+ {
518
+ items: T[]; // Array of items
519
+ isLoading: boolean; // Loading state
520
+ error: Error | null; // Error state
521
+ isSynced?: boolean; // Realtime sync status (if realtime enabled)
522
+ getItem: (id: string) => T | undefined; // Get item by ID from cache
523
+ refresh: (options?: { filter?: Record<string, any> }) => Promise<T[]>; // Refresh list
524
+ create: (data: Partial<T>) => Promise<T | null>; // Create new item
525
+ update: (data: Partial<T> & { id: string }) => Promise<T | null>; // Update item
526
+ delete: (id: string) => Promise<boolean>; // Delete item
527
+ customList?: (queryName: string, args: Record<string, any>, options?: { forceRefresh?: boolean }) => Promise<T[]>; // Custom list query
528
+ }
529
+ ```
530
+
531
+ #### useItemHook(id, options?)
532
+
533
+ Returns a hook for managing a single item.
534
+
535
+ **Parameters:**
536
+ - `id: string` - The ID of the item to manage
537
+
538
+ **Options:**
539
+ - `realtime?: { enabled?: boolean, observeOptions?: Record<string, any> }` - Enable realtime subscription
540
+
541
+ **Returns:**
542
+ ```typescript
543
+ {
544
+ item: T | null; // The item (null if not found or not loaded)
545
+ isLoading: boolean; // Loading state
546
+ error: Error | null; // Error state
547
+ isSynced?: boolean; // Realtime sync status (if realtime enabled)
548
+ refresh: () => Promise<T | null>; // Refresh item
549
+ update: (data: Partial<T>) => Promise<T | null>; // Update item (id not needed)
550
+ delete: () => Promise<boolean>; // Delete item (id not needed)
551
+ }
552
+ ```
553
+
366
554
  ## Important Notes
367
555
 
368
556
  - This library is designed to be used with AWS Amplify v6 or higher.
369
557
  - Requires React Query v5 or higher.
558
+ - When `realtime.enabled` is `true`, the initial fetch is skipped to avoid duplicate data.
559
+ - All mutations (`create`, `update`, `delete`) automatically synchronize the cache.
370
560
  - Test thoroughly before using in a production project.
371
561
 
372
562
  ## License
package/dist/config.d.ts CHANGED
@@ -11,6 +11,10 @@ export declare function setModelOwnerQueryMap(queryMap: Record<string, string>):
11
11
  * @returns The global model owner query mapping or undefined if not set
12
12
  */
13
13
  export declare function getModelOwnerQueryMap(): Record<string, string> | undefined;
14
+ /**
15
+ * Set the global selection set mapping
16
+ * @param selectionSetMap Mapping of model names to selection sets
17
+ */
14
18
  /**
15
19
  * Get owner query name for a specific model
16
20
  * @param modelName The model name
package/dist/config.js CHANGED
@@ -26,6 +26,10 @@ function setModelOwnerQueryMap(queryMap) {
26
26
  function getModelOwnerQueryMap() {
27
27
  return globalConfig.modelOwnerQueryMap;
28
28
  }
29
+ /**
30
+ * Set the global selection set mapping
31
+ * @param selectionSetMap Mapping of model names to selection sets
32
+ */
29
33
  /**
30
34
  * Get owner query name for a specific model
31
35
  * @param modelName The model name
package/dist/service.js CHANGED
@@ -1122,7 +1122,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
1122
1122
  },
1123
1123
  // React Hook returning method - Reimplemented based on TanStack Query
1124
1124
  useHook: (options) => {
1125
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1125
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
1126
1126
  const hookQueryClient = (0, react_query_1.useQueryClient)();
1127
1127
  // Determine query key
1128
1128
  const queryKey = (0, react_1.useMemo)(() => {
@@ -1171,10 +1171,11 @@ function createAmplifyService(modelName, defaultAuthMode) {
1171
1171
  service,
1172
1172
  ]);
1173
1173
  const realtimeEnabled = ((_h = options === null || options === void 0 ? void 0 : options.realtime) === null || _h === void 0 ? void 0 : _h.enabled) === true;
1174
+ const realtimeEvents = (_k = (_j = options === null || options === void 0 ? void 0 : options.realtime) === null || _j === void 0 ? void 0 : _j.events) !== null && _k !== void 0 ? _k : ["create", "update", "delete"];
1174
1175
  const queryOptions = {
1175
1176
  queryKey,
1176
1177
  queryFn,
1177
- enabled: ((_j = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _j === void 0 ? void 0 : _j.fetch) !== false && !realtimeEnabled,
1178
+ enabled: ((_l = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _l === void 0 ? void 0 : _l.fetch) !== false && !realtimeEnabled,
1178
1179
  staleTime: 1000 * 30, // Keep fresh for 30 seconds (refresh more frequently)
1179
1180
  refetchOnMount: true, // Refetch on component mount
1180
1181
  refetchOnWindowFocus: false, // Don't auto-refetch on window focus
@@ -1183,22 +1184,63 @@ function createAmplifyService(modelName, defaultAuthMode) {
1183
1184
  const [isSynced, setIsSynced] = (0, react_1.useState)(undefined);
1184
1185
  const { data: items = [], isLoading, error, refetch, } = (0, react_query_1.useQuery)(queryOptions);
1185
1186
  (0, react_1.useEffect)(() => {
1186
- var _a, _b, _c;
1187
+ var _a, _b, _c, _d, _e, _f;
1187
1188
  if (!realtimeEnabled)
1188
1189
  return;
1189
1190
  if (options === null || options === void 0 ? void 0 : options.customList) {
1190
- console.warn(`🍬 ${modelName} useHook realtime: customList is not supported.`);
1191
- return;
1191
+ const client = (0, client_1.getClient)();
1192
+ const model = (_a = client.models) === null || _a === void 0 ? void 0 : _a[modelName];
1193
+ if (!model) {
1194
+ console.warn(`🍬 ${modelName} useHook realtime: model not available.`);
1195
+ return;
1196
+ }
1197
+ const observeOptions = Object.assign({}, (((_b = options === null || options === void 0 ? void 0 : options.realtime) === null || _b === void 0 ? void 0 : _b.observeOptions) || {}));
1198
+ if (observeOptions.filter === undefined &&
1199
+ ((_c = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _c === void 0 ? void 0 : _c.filter)) {
1200
+ observeOptions.filter = options.initialFetchOptions.filter;
1201
+ }
1202
+ const subscriptions = [
1203
+ realtimeEvents.includes("create") && model.onCreate
1204
+ ? model.onCreate(observeOptions).subscribe({
1205
+ next: () => hookQueryClient.invalidateQueries({
1206
+ queryKey,
1207
+ refetchType: "active",
1208
+ }),
1209
+ error: (err) => console.error(`🍬 ${modelName} useHook realtime onCreate error:`, err),
1210
+ })
1211
+ : null,
1212
+ realtimeEvents.includes("update") && model.onUpdate
1213
+ ? model.onUpdate(observeOptions).subscribe({
1214
+ next: () => hookQueryClient.invalidateQueries({
1215
+ queryKey,
1216
+ refetchType: "active",
1217
+ }),
1218
+ error: (err) => console.error(`🍬 ${modelName} useHook realtime onUpdate error:`, err),
1219
+ })
1220
+ : null,
1221
+ realtimeEvents.includes("delete") && model.onDelete
1222
+ ? model.onDelete(observeOptions).subscribe({
1223
+ next: () => hookQueryClient.invalidateQueries({
1224
+ queryKey,
1225
+ refetchType: "active",
1226
+ }),
1227
+ error: (err) => console.error(`🍬 ${modelName} useHook realtime onDelete error:`, err),
1228
+ })
1229
+ : null,
1230
+ ].filter(Boolean);
1231
+ return () => {
1232
+ subscriptions.forEach((sub) => { var _a; return (_a = sub === null || sub === void 0 ? void 0 : sub.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(sub); });
1233
+ };
1192
1234
  }
1193
1235
  const client = (0, client_1.getClient)();
1194
- const model = (_a = client.models) === null || _a === void 0 ? void 0 : _a[modelName];
1236
+ const model = (_d = client.models) === null || _d === void 0 ? void 0 : _d[modelName];
1195
1237
  if (!(model === null || model === void 0 ? void 0 : model.observeQuery)) {
1196
1238
  console.warn(`🍬 ${modelName} useHook realtime: observeQuery not available.`);
1197
1239
  return;
1198
1240
  }
1199
- const observeOptions = Object.assign({}, (((_b = options === null || options === void 0 ? void 0 : options.realtime) === null || _b === void 0 ? void 0 : _b.observeOptions) || {}));
1241
+ const observeOptions = Object.assign({}, (((_e = options === null || options === void 0 ? void 0 : options.realtime) === null || _e === void 0 ? void 0 : _e.observeOptions) || {}));
1200
1242
  if (observeOptions.filter === undefined &&
1201
- ((_c = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _c === void 0 ? void 0 : _c.filter)) {
1243
+ ((_f = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _f === void 0 ? void 0 : _f.filter)) {
1202
1244
  observeOptions.filter = options.initialFetchOptions.filter;
1203
1245
  }
1204
1246
  let isMounted = true;
@@ -1243,8 +1285,8 @@ function createAmplifyService(modelName, defaultAuthMode) {
1243
1285
  queryKey,
1244
1286
  hookQueryClient,
1245
1287
  options === null || options === void 0 ? void 0 : options.customList,
1246
- (_k = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _k === void 0 ? void 0 : _k.filter,
1247
- (_l = options === null || options === void 0 ? void 0 : options.realtime) === null || _l === void 0 ? void 0 : _l.observeOptions,
1288
+ (_m = options === null || options === void 0 ? void 0 : options.initialFetchOptions) === null || _m === void 0 ? void 0 : _m.filter,
1289
+ (_o = options === null || options === void 0 ? void 0 : options.realtime) === null || _o === void 0 ? void 0 : _o.observeOptions,
1248
1290
  ]);
1249
1291
  // Interface functions implementation
1250
1292
  const getItem = (0, react_1.useCallback)((id) => {
@@ -1358,9 +1400,11 @@ function createAmplifyService(modelName, defaultAuthMode) {
1358
1400
  };
1359
1401
  },
1360
1402
  // Hook for managing single item - Reimplemented based on TanStack Query
1361
- useItemHook: (id) => {
1403
+ useItemHook: (id, options) => {
1404
+ var _a, _b;
1362
1405
  const hookQueryClient = (0, react_query_1.useQueryClient)();
1363
1406
  const singleItemQueryKey = itemKey(modelName, id);
1407
+ const realtimeEnabled = ((_a = options === null || options === void 0 ? void 0 : options.realtime) === null || _a === void 0 ? void 0 : _a.enabled) === true;
1364
1408
  // First check data from cache
1365
1409
  const rawCachedData = hookQueryClient.getQueryData(singleItemQueryKey);
1366
1410
  // πŸ”§ 버그 μˆ˜μ •: 배열이 μΊμ‹œλ˜μ–΄ μžˆλŠ” 경우 처리
@@ -1392,8 +1436,83 @@ function createAmplifyService(modelName, defaultAuthMode) {
1392
1436
  staleTime: 1000 * 60, // Keep data "fresh" for 1 minute
1393
1437
  refetchOnMount: cachedData ? false : true, // Only refetch if no cached data
1394
1438
  refetchOnWindowFocus: false, // Disable window focus refetch to prevent loops
1395
- enabled: !!id, // Only enable query when id exists
1439
+ enabled: !!id && !realtimeEnabled, // Only enable query when id exists
1396
1440
  });
1441
+ const [isSynced, setIsSynced] = (0, react_1.useState)(undefined);
1442
+ (0, react_1.useEffect)(() => {
1443
+ var _a, _b;
1444
+ if (!realtimeEnabled || !id)
1445
+ return;
1446
+ const client = (0, client_1.getClient)();
1447
+ const model = (_a = client.models) === null || _a === void 0 ? void 0 : _a[modelName];
1448
+ if (!(model === null || model === void 0 ? void 0 : model.observeQuery)) {
1449
+ console.warn(`🍬 ${modelName} useItemHook realtime: observeQuery not available.`);
1450
+ return;
1451
+ }
1452
+ const observeOptions = Object.assign({}, (((_b = options === null || options === void 0 ? void 0 : options.realtime) === null || _b === void 0 ? void 0 : _b.observeOptions) || {}));
1453
+ if (!observeOptions.filter) {
1454
+ observeOptions.filter = { id: { eq: id } };
1455
+ }
1456
+ let isMounted = true;
1457
+ const subscription = model.observeQuery(observeOptions).subscribe({
1458
+ next: ({ items: nextItems, isSynced: synced }) => {
1459
+ if (!isMounted)
1460
+ return;
1461
+ const safeItems = Array.isArray(nextItems)
1462
+ ? nextItems.filter(Boolean)
1463
+ : [];
1464
+ const nextItem = safeItems.find((entry) => (entry === null || entry === void 0 ? void 0 : entry.id) === id) || null;
1465
+ const relatedQueryKeys = findRelatedQueryKeys(modelName, hookQueryClient);
1466
+ if (nextItem) {
1467
+ hookQueryClient.setQueryData(singleItemQueryKey, nextItem);
1468
+ relatedQueryKeys.forEach((queryKey) => {
1469
+ if (isItemKeyForModel(modelName, queryKey)) {
1470
+ return;
1471
+ }
1472
+ hookQueryClient.setQueryData(queryKey, (oldData) => {
1473
+ const oldItems = Array.isArray(oldData) ? oldData : [];
1474
+ const hasItem = oldItems.some((entry) => (entry === null || entry === void 0 ? void 0 : entry.id) === id);
1475
+ if (hasItem) {
1476
+ return oldItems.map((entry) => (entry === null || entry === void 0 ? void 0 : entry.id) === id ? nextItem : entry);
1477
+ }
1478
+ if (queryKey.length === 1) {
1479
+ return [...oldItems, nextItem];
1480
+ }
1481
+ return oldItems;
1482
+ });
1483
+ });
1484
+ }
1485
+ else {
1486
+ hookQueryClient.setQueryData(singleItemQueryKey, null);
1487
+ relatedQueryKeys.forEach((queryKey) => {
1488
+ if (isItemKeyForModel(modelName, queryKey)) {
1489
+ return;
1490
+ }
1491
+ hookQueryClient.setQueryData(queryKey, (oldData) => {
1492
+ const oldItems = Array.isArray(oldData) ? oldData : [];
1493
+ return oldItems.filter((entry) => (entry === null || entry === void 0 ? void 0 : entry.id) !== id);
1494
+ });
1495
+ });
1496
+ }
1497
+ setIsSynced(Boolean(synced));
1498
+ },
1499
+ error: (err) => {
1500
+ console.error(`🍬 ${modelName} useItemHook realtime subscribe error:`, err);
1501
+ },
1502
+ });
1503
+ return () => {
1504
+ var _a;
1505
+ isMounted = false;
1506
+ (_a = subscription === null || subscription === void 0 ? void 0 : subscription.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(subscription);
1507
+ };
1508
+ }, [
1509
+ realtimeEnabled,
1510
+ id,
1511
+ modelName,
1512
+ hookQueryClient,
1513
+ singleItemQueryKey,
1514
+ (_b = options === null || options === void 0 ? void 0 : options.realtime) === null || _b === void 0 ? void 0 : _b.observeOptions,
1515
+ ]);
1397
1516
  // useMutation hooks call service methods,
1398
1517
  // Service methods handle optimistic updates and cache updates/rollbacks internally.
1399
1518
  // Mutations inside useHook only serve to call service methods.
@@ -1463,6 +1582,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
1463
1582
  item: item || null,
1464
1583
  isLoading: effectiveLoading, // Not loading if cached data exists
1465
1584
  error: error, // Explicitly specify error type
1585
+ isSynced,
1466
1586
  refresh: refreshItem,
1467
1587
  update: updateItem,
1468
1588
  delete: deleteItem,
package/dist/types.d.ts CHANGED
@@ -41,6 +41,7 @@ export type ModelHook<T> = {
41
41
  export type ItemHook<T> = {
42
42
  item: T | null;
43
43
  isLoading: boolean;
44
+ isSynced?: boolean;
44
45
  error: Error | null;
45
46
  refresh: () => Promise<T | null>;
46
47
  update: (data: Partial<T>) => Promise<T | null>;
@@ -96,9 +97,15 @@ export interface AmplifyDataService<T> {
96
97
  realtime?: {
97
98
  enabled?: boolean;
98
99
  observeOptions?: Record<string, any>;
100
+ events?: Array<"create" | "update" | "delete">;
99
101
  };
100
102
  }) => ModelHook<T>;
101
- useItemHook: (id: string) => ItemHook<T>;
103
+ useItemHook: (id: string, options?: {
104
+ realtime?: {
105
+ enabled?: boolean;
106
+ observeOptions?: Record<string, any>;
107
+ };
108
+ }) => ItemHook<T>;
102
109
  modelName: string;
103
110
  withExtensions: <E>(extensions: E) => AmplifyDataService<T> & E;
104
111
  setAuthMode: (authMode: AuthMode) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amplifyquery",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "Amplify+Query",
5
5
  "keywords": [
6
6
  "Amplify",