@legendapp/state 3.0.0-alpha.8 → 3.0.0-beta.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.
Files changed (86) hide show
  1. package/.DS_Store +0 -0
  2. package/config/configureLegendState.d.mts +13 -0
  3. package/config/configureLegendState.d.ts +13 -0
  4. package/config/configureLegendState.js +45 -0
  5. package/config/configureLegendState.mjs +43 -0
  6. package/config/enable$GetSet.js +2 -1
  7. package/config/enable$GetSet.mjs +2 -1
  8. package/config/enableReactTracking.js +2 -1
  9. package/config/enableReactTracking.mjs +2 -1
  10. package/config/enableReactUse.js +2 -1
  11. package/config/enableReactUse.mjs +2 -1
  12. package/config/enable_PeekAssign.js +2 -1
  13. package/config/enable_PeekAssign.mjs +2 -1
  14. package/helpers/trackHistory.js +2 -2
  15. package/helpers/trackHistory.mjs +2 -2
  16. package/index.d.mts +104 -80
  17. package/index.d.ts +104 -80
  18. package/index.js +328 -318
  19. package/index.mjs +325 -316
  20. package/package.json +36 -1
  21. package/persist-plugins/async-storage.d.mts +6 -3
  22. package/persist-plugins/async-storage.d.ts +6 -3
  23. package/persist-plugins/async-storage.js +8 -4
  24. package/persist-plugins/async-storage.mjs +8 -5
  25. package/persist-plugins/indexeddb.d.mts +6 -4
  26. package/persist-plugins/indexeddb.d.ts +6 -4
  27. package/persist-plugins/indexeddb.js +35 -15
  28. package/persist-plugins/indexeddb.mjs +35 -16
  29. package/persist-plugins/mmkv.d.mts +5 -1
  30. package/persist-plugins/mmkv.d.ts +5 -1
  31. package/persist-plugins/mmkv.js +10 -5
  32. package/persist-plugins/mmkv.mjs +10 -6
  33. package/react-reactive/enableReactComponents.d.mts +9 -0
  34. package/react-reactive/enableReactComponents.d.ts +9 -0
  35. package/react-reactive/enableReactComponents.js +19 -0
  36. package/react-reactive/enableReactComponents.mjs +17 -0
  37. package/react-reactive/enableReactNativeComponents.d.mts +22 -0
  38. package/react-reactive/enableReactNativeComponents.d.ts +22 -0
  39. package/react-reactive/enableReactNativeComponents.js +53 -0
  40. package/react-reactive/enableReactNativeComponents.mjs +51 -0
  41. package/react-reactive/enableReactive.d.mts +5 -0
  42. package/react-reactive/enableReactive.d.ts +5 -0
  43. package/react-reactive/enableReactive.js +24 -0
  44. package/react-reactive/enableReactive.mjs +22 -0
  45. package/react-reactive/enableReactive.native.d.mts +5 -0
  46. package/react-reactive/enableReactive.native.d.ts +5 -0
  47. package/react-reactive/enableReactive.native.js +58 -0
  48. package/react-reactive/enableReactive.native.mjs +56 -0
  49. package/react-reactive/enableReactive.web.d.mts +5 -0
  50. package/react-reactive/enableReactive.web.d.ts +5 -0
  51. package/react-reactive/enableReactive.web.js +58 -0
  52. package/react-reactive/enableReactive.web.mjs +56 -0
  53. package/react.d.mts +39 -34
  54. package/react.d.ts +39 -34
  55. package/react.js +39 -17
  56. package/react.mjs +39 -17
  57. package/sync-plugins/crud.d.mts +21 -24
  58. package/sync-plugins/crud.d.ts +21 -24
  59. package/sync-plugins/crud.js +241 -140
  60. package/sync-plugins/crud.mjs +243 -142
  61. package/sync-plugins/fetch.js +12 -8
  62. package/sync-plugins/fetch.mjs +13 -9
  63. package/sync-plugins/firebase.d.mts +27 -0
  64. package/sync-plugins/firebase.d.ts +27 -0
  65. package/sync-plugins/firebase.js +373 -0
  66. package/sync-plugins/firebase.mjs +368 -0
  67. package/sync-plugins/keel.d.mts +43 -26
  68. package/sync-plugins/keel.d.ts +43 -26
  69. package/sync-plugins/keel.js +145 -100
  70. package/sync-plugins/keel.mjs +147 -100
  71. package/sync-plugins/supabase.d.mts +19 -9
  72. package/sync-plugins/supabase.d.ts +19 -9
  73. package/sync-plugins/supabase.js +52 -22
  74. package/sync-plugins/supabase.mjs +53 -23
  75. package/sync-plugins/tanstack-query.d.mts +2 -2
  76. package/sync-plugins/tanstack-query.d.ts +2 -2
  77. package/sync-plugins/tanstack-query.js +22 -5
  78. package/sync-plugins/tanstack-query.mjs +22 -5
  79. package/sync-plugins/tanstack-react-query.d.mts +1 -1
  80. package/sync-plugins/tanstack-react-query.d.ts +1 -1
  81. package/sync-plugins/tanstack-react-query.js +8 -1
  82. package/sync-plugins/tanstack-react-query.mjs +8 -1
  83. package/sync.d.mts +74 -200
  84. package/sync.d.ts +74 -200
  85. package/sync.js +492 -293
  86. package/sync.mjs +498 -299
@@ -18,12 +18,22 @@ function configureSyncedSupabase(config) {
18
18
  }
19
19
  Object.assign(supabaseConfig, sync.removeNullUndefined(rest));
20
20
  }
21
+ function wrapSupabaseFn(fn) {
22
+ return async (...args) => {
23
+ const { data, error } = await fn(...args);
24
+ if (error) {
25
+ throw new Error(error.message);
26
+ }
27
+ return data;
28
+ };
29
+ }
21
30
  function syncedSupabase(props) {
22
31
  props = { ...supabaseConfig, ...props };
23
32
  const {
24
- supabase: client,
33
+ supabase,
25
34
  collection,
26
35
  select: selectFn,
36
+ schema,
27
37
  filter,
28
38
  actions,
29
39
  fieldCreatedAt: fieldCreatedAtParam,
@@ -36,14 +46,21 @@ function syncedSupabase(props) {
36
46
  waitFor,
37
47
  waitForSet,
38
48
  generateId,
49
+ mode,
50
+ list: listParam,
51
+ create: createParam,
52
+ update: updateParam,
53
+ delete: deleteParam,
39
54
  ...rest
40
55
  } = props;
56
+ const client = supabase;
41
57
  const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
42
58
  const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === "last-sync" ? "updated_at" : void 0);
43
59
  const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
44
- const list = !actions || actions.includes("read") ? async (params) => {
60
+ const list = !actions || actions.includes("read") ? listParam ? wrapSupabaseFn(listParam) : async (params) => {
45
61
  const { lastSync } = params;
46
- const from = client.from(collection);
62
+ const clientSchema = schema ? client.schema(schema) : client;
63
+ const from = clientSchema.from(collection);
47
64
  let select = selectFn ? selectFn(from) : from.select();
48
65
  if (changesSince === "last-sync" && lastSync) {
49
66
  const date = new Date(lastSync).toISOString();
@@ -58,8 +75,8 @@ function syncedSupabase(props) {
58
75
  }
59
76
  return data || [];
60
77
  } : void 0;
61
- const upsert = async (input) => {
62
- const res = await client.from(collection).upsert(input).select();
78
+ const create = createParam ? wrapSupabaseFn(createParam) : !actions || actions.includes("create") ? async (input) => {
79
+ const res = await client.from(collection).insert(input).select();
63
80
  const { data, error } = res;
64
81
  if (data) {
65
82
  const created = data[0];
@@ -67,10 +84,18 @@ function syncedSupabase(props) {
67
84
  } else {
68
85
  throw new Error(error == null ? void 0 : error.message);
69
86
  }
70
- };
71
- const create = !actions || actions.includes("create") ? upsert : void 0;
72
- const update = !actions || actions.includes("update") ? upsert : void 0;
73
- const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? async (input) => {
87
+ } : void 0;
88
+ const update = !actions || actions.includes("update") ? updateParam ? wrapSupabaseFn(updateParam) : async (input) => {
89
+ const res = await client.from(collection).update(input).eq("id", input.id).select();
90
+ const { data, error } = res;
91
+ if (data) {
92
+ const created = data[0];
93
+ return created;
94
+ } else {
95
+ throw new Error(error == null ? void 0 : error.message);
96
+ }
97
+ } : void 0;
98
+ const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? deleteParam ? wrapSupabaseFn(deleteParam) : async (input) => {
74
99
  const id = input.id;
75
100
  const res = await client.from(collection).delete().eq("id", id).select();
76
101
  const { data, error } = res;
@@ -82,13 +107,13 @@ function syncedSupabase(props) {
82
107
  }
83
108
  } : void 0;
84
109
  const subscribe = realtime ? ({ node, value$, update: update2 }) => {
85
- const { filter: filter2, schema } = state.isObject(realtime) ? realtime : {};
110
+ const { filter: filter2, schema: schema2 } = state.isObject(realtime) ? realtime : {};
86
111
  const channel = client.channel(`LS_${node.key || ""}${channelNum++}`).on(
87
112
  "postgres_changes",
88
113
  {
89
114
  event: "*",
90
115
  table: collection,
91
- schema: schema || "public",
116
+ schema: schema2 || "public",
92
117
  filter: filter2 || void 0
93
118
  },
94
119
  (payload) => {
@@ -96,25 +121,30 @@ function syncedSupabase(props) {
96
121
  const { eventType, new: value, old } = payload;
97
122
  if (eventType === "INSERT" || eventType === "UPDATE") {
98
123
  const cur = (_a = value$.peek()) == null ? void 0 : _a[value.id];
99
- const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
100
- const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
101
- const valueDate = +new Date(valueDateStr);
102
- if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
124
+ let isOk = !fieldUpdatedAt;
125
+ let lastSync = void 0;
126
+ if (!isOk) {
127
+ const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
128
+ const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
129
+ lastSync = +new Date(valueDateStr);
130
+ isOk = valueDateStr && (!curDateStr || lastSync > +new Date(curDateStr));
131
+ }
132
+ if (isOk) {
103
133
  update2({
104
- value: { [value.id]: value },
105
- lastSync: valueDate,
134
+ value: [value],
135
+ lastSync,
106
136
  mode: "merge"
107
137
  });
108
138
  }
109
139
  } else if (eventType === "DELETE") {
110
- const { id } = old;
140
+ old[state.symbolDelete] = true;
111
141
  update2({
112
- value: { [id]: state.symbolDelete }
142
+ value: [old]
113
143
  });
114
144
  }
115
145
  }
116
146
  ).subscribe();
117
- return channel.unsubscribe;
147
+ return () => channel.unsubscribe();
118
148
  } : void 0;
119
149
  let transform = transformParam;
120
150
  if (stringifyDates) {
@@ -123,6 +153,7 @@ function syncedSupabase(props) {
123
153
  }
124
154
  return crud.syncedCrud({
125
155
  ...rest,
156
+ mode: mode || "merge",
126
157
  list,
127
158
  create,
128
159
  update,
@@ -132,11 +163,10 @@ function syncedSupabase(props) {
132
163
  fieldUpdatedAt,
133
164
  fieldDeleted,
134
165
  updatePartial: false,
135
- onSavedUpdate: "createdUpdatedAt",
136
166
  transform,
137
167
  generateId,
138
168
  waitFor: () => isEnabled$.get() && (waitFor ? state.computeSelector(waitFor) : true),
139
- waitForSet
169
+ waitForSet: (params) => isEnabled$.get() && (waitForSet ? state.isFunction(waitForSet) ? waitForSet(params) : waitForSet : true)
140
170
  });
141
171
  }
142
172
 
@@ -1,4 +1,4 @@
1
- import { observable, computeSelector, isObject, symbolDelete } from '@legendapp/state';
1
+ import { observable, computeSelector, isFunction, isObject, symbolDelete } from '@legendapp/state';
2
2
  import { removeNullUndefined, transformStringifyDates, combineTransforms } from '@legendapp/state/sync';
3
3
  import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
4
4
 
@@ -16,12 +16,22 @@ function configureSyncedSupabase(config) {
16
16
  }
17
17
  Object.assign(supabaseConfig, removeNullUndefined(rest));
18
18
  }
19
+ function wrapSupabaseFn(fn) {
20
+ return async (...args) => {
21
+ const { data, error } = await fn(...args);
22
+ if (error) {
23
+ throw new Error(error.message);
24
+ }
25
+ return data;
26
+ };
27
+ }
19
28
  function syncedSupabase(props) {
20
29
  props = { ...supabaseConfig, ...props };
21
30
  const {
22
- supabase: client,
31
+ supabase,
23
32
  collection,
24
33
  select: selectFn,
34
+ schema,
25
35
  filter,
26
36
  actions,
27
37
  fieldCreatedAt: fieldCreatedAtParam,
@@ -34,14 +44,21 @@ function syncedSupabase(props) {
34
44
  waitFor,
35
45
  waitForSet,
36
46
  generateId,
47
+ mode,
48
+ list: listParam,
49
+ create: createParam,
50
+ update: updateParam,
51
+ delete: deleteParam,
37
52
  ...rest
38
53
  } = props;
54
+ const client = supabase;
39
55
  const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
40
56
  const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === "last-sync" ? "updated_at" : void 0);
41
57
  const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
42
- const list = !actions || actions.includes("read") ? async (params) => {
58
+ const list = !actions || actions.includes("read") ? listParam ? wrapSupabaseFn(listParam) : async (params) => {
43
59
  const { lastSync } = params;
44
- const from = client.from(collection);
60
+ const clientSchema = schema ? client.schema(schema) : client;
61
+ const from = clientSchema.from(collection);
45
62
  let select = selectFn ? selectFn(from) : from.select();
46
63
  if (changesSince === "last-sync" && lastSync) {
47
64
  const date = new Date(lastSync).toISOString();
@@ -56,8 +73,8 @@ function syncedSupabase(props) {
56
73
  }
57
74
  return data || [];
58
75
  } : void 0;
59
- const upsert = async (input) => {
60
- const res = await client.from(collection).upsert(input).select();
76
+ const create = createParam ? wrapSupabaseFn(createParam) : !actions || actions.includes("create") ? async (input) => {
77
+ const res = await client.from(collection).insert(input).select();
61
78
  const { data, error } = res;
62
79
  if (data) {
63
80
  const created = data[0];
@@ -65,10 +82,18 @@ function syncedSupabase(props) {
65
82
  } else {
66
83
  throw new Error(error == null ? void 0 : error.message);
67
84
  }
68
- };
69
- const create = !actions || actions.includes("create") ? upsert : void 0;
70
- const update = !actions || actions.includes("update") ? upsert : void 0;
71
- const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? async (input) => {
85
+ } : void 0;
86
+ const update = !actions || actions.includes("update") ? updateParam ? wrapSupabaseFn(updateParam) : async (input) => {
87
+ const res = await client.from(collection).update(input).eq("id", input.id).select();
88
+ const { data, error } = res;
89
+ if (data) {
90
+ const created = data[0];
91
+ return created;
92
+ } else {
93
+ throw new Error(error == null ? void 0 : error.message);
94
+ }
95
+ } : void 0;
96
+ const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? deleteParam ? wrapSupabaseFn(deleteParam) : async (input) => {
72
97
  const id = input.id;
73
98
  const res = await client.from(collection).delete().eq("id", id).select();
74
99
  const { data, error } = res;
@@ -80,13 +105,13 @@ function syncedSupabase(props) {
80
105
  }
81
106
  } : void 0;
82
107
  const subscribe = realtime ? ({ node, value$, update: update2 }) => {
83
- const { filter: filter2, schema } = isObject(realtime) ? realtime : {};
108
+ const { filter: filter2, schema: schema2 } = isObject(realtime) ? realtime : {};
84
109
  const channel = client.channel(`LS_${node.key || ""}${channelNum++}`).on(
85
110
  "postgres_changes",
86
111
  {
87
112
  event: "*",
88
113
  table: collection,
89
- schema: schema || "public",
114
+ schema: schema2 || "public",
90
115
  filter: filter2 || void 0
91
116
  },
92
117
  (payload) => {
@@ -94,25 +119,30 @@ function syncedSupabase(props) {
94
119
  const { eventType, new: value, old } = payload;
95
120
  if (eventType === "INSERT" || eventType === "UPDATE") {
96
121
  const cur = (_a = value$.peek()) == null ? void 0 : _a[value.id];
97
- const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
98
- const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
99
- const valueDate = +new Date(valueDateStr);
100
- if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
122
+ let isOk = !fieldUpdatedAt;
123
+ let lastSync = void 0;
124
+ if (!isOk) {
125
+ const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
126
+ const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
127
+ lastSync = +new Date(valueDateStr);
128
+ isOk = valueDateStr && (!curDateStr || lastSync > +new Date(curDateStr));
129
+ }
130
+ if (isOk) {
101
131
  update2({
102
- value: { [value.id]: value },
103
- lastSync: valueDate,
132
+ value: [value],
133
+ lastSync,
104
134
  mode: "merge"
105
135
  });
106
136
  }
107
137
  } else if (eventType === "DELETE") {
108
- const { id } = old;
138
+ old[symbolDelete] = true;
109
139
  update2({
110
- value: { [id]: symbolDelete }
140
+ value: [old]
111
141
  });
112
142
  }
113
143
  }
114
144
  ).subscribe();
115
- return channel.unsubscribe;
145
+ return () => channel.unsubscribe();
116
146
  } : void 0;
117
147
  let transform = transformParam;
118
148
  if (stringifyDates) {
@@ -121,6 +151,7 @@ function syncedSupabase(props) {
121
151
  }
122
152
  return syncedCrud({
123
153
  ...rest,
154
+ mode: mode || "merge",
124
155
  list,
125
156
  create,
126
157
  update,
@@ -130,11 +161,10 @@ function syncedSupabase(props) {
130
161
  fieldUpdatedAt,
131
162
  fieldDeleted,
132
163
  updatePartial: false,
133
- onSavedUpdate: "createdUpdatedAt",
134
164
  transform,
135
165
  generateId,
136
166
  waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
137
- waitForSet
167
+ waitForSet: (params) => isEnabled$.get() && (waitForSet ? isFunction(waitForSet) ? waitForSet(params) : waitForSet : true)
138
168
  });
139
169
  }
140
170
 
@@ -4,11 +4,11 @@ import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, D
4
4
  interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends SyncedOptions<TData> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
10
  mutation?: MutationObserverOptions<TData, TError, void>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): NonNullable<TData>;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -4,11 +4,11 @@ import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, D
4
4
  interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends SyncedOptions<TData> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
10
  mutation?: MutationObserverOptions<TData, TError, void>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): NonNullable<TData>;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -6,7 +6,7 @@ var queryCore = require('@tanstack/query-core');
6
6
 
7
7
  // src/sync-plugins/tanstack-query.ts
8
8
  function syncedQuery(params) {
9
- const { query: options, mutation: mutationOptions, queryClient } = params;
9
+ const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
10
10
  const Observer = queryCore.QueryObserver;
11
11
  const defaultedOptions = queryClient.defaultQueryOptions(
12
12
  options
@@ -14,6 +14,7 @@ function syncedQuery(params) {
14
14
  let observer = void 0;
15
15
  let latestOptions = defaultedOptions;
16
16
  let queryKeyFromFn;
17
+ let resolveInitialPromise = void 0;
17
18
  const origQueryKey = options.queryKey;
18
19
  const isKeyFunction = state.isFunction(origQueryKey);
19
20
  const updateQueryOptions = (obj) => {
@@ -33,14 +34,29 @@ function syncedQuery(params) {
33
34
  });
34
35
  }
35
36
  observer = new Observer(queryClient, latestOptions);
36
- const get = () => {
37
- const result = observer.getOptimisticResult(latestOptions);
38
- return result.data;
37
+ let isFirstRun = true;
38
+ const get = async () => {
39
+ if (isFirstRun) {
40
+ isFirstRun = false;
41
+ const result = observer.getOptimisticResult(latestOptions);
42
+ if (result.isLoading) {
43
+ await new Promise((resolve) => {
44
+ resolveInitialPromise = resolve;
45
+ });
46
+ }
47
+ return result.data;
48
+ } else {
49
+ observer.refetch();
50
+ }
39
51
  };
40
52
  const subscribe = ({ update }) => {
41
53
  const unsubscribe = observer.subscribe(
42
54
  queryCore.notifyManager.batchCalls((result) => {
43
55
  if (result.status === "success") {
56
+ if (resolveInitialPromise) {
57
+ resolveInitialPromise(result.data);
58
+ resolveInitialPromise = void 0;
59
+ }
44
60
  update({ value: result.data });
45
61
  }
46
62
  })
@@ -58,7 +74,8 @@ function syncedQuery(params) {
58
74
  return sync.synced({
59
75
  get,
60
76
  set,
61
- subscribe
77
+ subscribe,
78
+ ...rest
62
79
  });
63
80
  }
64
81
 
@@ -4,7 +4,7 @@ import { MutationObserver, QueryObserver, notifyManager } from '@tanstack/query-
4
4
 
5
5
  // src/sync-plugins/tanstack-query.ts
6
6
  function syncedQuery(params) {
7
- const { query: options, mutation: mutationOptions, queryClient } = params;
7
+ const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
8
8
  const Observer = QueryObserver;
9
9
  const defaultedOptions = queryClient.defaultQueryOptions(
10
10
  options
@@ -12,6 +12,7 @@ function syncedQuery(params) {
12
12
  let observer = void 0;
13
13
  let latestOptions = defaultedOptions;
14
14
  let queryKeyFromFn;
15
+ let resolveInitialPromise = void 0;
15
16
  const origQueryKey = options.queryKey;
16
17
  const isKeyFunction = isFunction(origQueryKey);
17
18
  const updateQueryOptions = (obj) => {
@@ -31,14 +32,29 @@ function syncedQuery(params) {
31
32
  });
32
33
  }
33
34
  observer = new Observer(queryClient, latestOptions);
34
- const get = () => {
35
- const result = observer.getOptimisticResult(latestOptions);
36
- return result.data;
35
+ let isFirstRun = true;
36
+ const get = async () => {
37
+ if (isFirstRun) {
38
+ isFirstRun = false;
39
+ const result = observer.getOptimisticResult(latestOptions);
40
+ if (result.isLoading) {
41
+ await new Promise((resolve) => {
42
+ resolveInitialPromise = resolve;
43
+ });
44
+ }
45
+ return result.data;
46
+ } else {
47
+ observer.refetch();
48
+ }
37
49
  };
38
50
  const subscribe = ({ update }) => {
39
51
  const unsubscribe = observer.subscribe(
40
52
  notifyManager.batchCalls((result) => {
41
53
  if (result.status === "success") {
54
+ if (resolveInitialPromise) {
55
+ resolveInitialPromise(result.data);
56
+ resolveInitialPromise = void 0;
57
+ }
42
58
  update({ value: result.data });
43
59
  }
44
60
  })
@@ -56,7 +72,8 @@ function syncedQuery(params) {
56
72
  return synced({
57
73
  get,
58
74
  set,
59
- subscribe
75
+ subscribe,
76
+ ...rest
60
77
  });
61
78
  }
62
79
 
@@ -3,6 +3,6 @@ import { DefaultError, QueryKey } from '@tanstack/query-core';
3
3
  import { Observable } from '@legendapp/state';
4
4
  import { Synced } from '@legendapp/state/sync';
5
5
 
6
- declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<NonNullable<Synced<TData>>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
7
7
 
8
8
  export { useObservableSyncedQuery };
@@ -3,6 +3,6 @@ import { DefaultError, QueryKey } from '@tanstack/query-core';
3
3
  import { Observable } from '@legendapp/state';
4
4
  import { Synced } from '@legendapp/state/sync';
5
5
 
6
- declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<NonNullable<Synced<TData>>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
7
7
 
8
8
  export { useObservableSyncedQuery };
@@ -2,10 +2,17 @@
2
2
 
3
3
  var react = require('@legendapp/state/react');
4
4
  var tanstackQuery = require('@legendapp/state/sync-plugins/tanstack-query');
5
+ var reactQuery = require('@tanstack/react-query');
5
6
 
6
7
  // src/sync-plugins/tanstack-react-query.ts
7
8
  function useObservableSyncedQuery(params) {
8
- return react.useObservable(tanstackQuery.syncedQuery(params));
9
+ const queryClient = params.queryClient || reactQuery.useQueryClient();
10
+ return react.useObservable(
11
+ tanstackQuery.syncedQuery({
12
+ ...params,
13
+ queryClient
14
+ })
15
+ );
9
16
  }
10
17
 
11
18
  exports.useObservableSyncedQuery = useObservableSyncedQuery;
@@ -1,9 +1,16 @@
1
1
  import { useObservable } from '@legendapp/state/react';
2
2
  import { syncedQuery } from '@legendapp/state/sync-plugins/tanstack-query';
3
+ import { useQueryClient } from '@tanstack/react-query';
3
4
 
4
5
  // src/sync-plugins/tanstack-react-query.ts
5
6
  function useObservableSyncedQuery(params) {
6
- return useObservable(syncedQuery(params));
7
+ const queryClient = params.queryClient || useQueryClient();
8
+ return useObservable(
9
+ syncedQuery({
10
+ ...params,
11
+ queryClient
12
+ })
13
+ );
7
14
  }
8
15
 
9
16
  export { useObservableSyncedQuery };