@planningcenter/chat-react-native 3.21.2-rc.2 → 3.21.2-rc.4

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 (29) hide show
  1. package/build/hooks/use_async_storage.d.ts.map +1 -1
  2. package/build/hooks/use_async_storage.js +3 -44
  3. package/build/hooks/use_async_storage.js.map +1 -1
  4. package/build/hooks/use_jolt.d.ts.map +1 -1
  5. package/build/hooks/use_jolt.js +6 -8
  6. package/build/hooks/use_jolt.js.map +1 -1
  7. package/build/hooks/use_storage.d.ts +9 -0
  8. package/build/hooks/use_storage.d.ts.map +1 -0
  9. package/build/hooks/use_storage.js +53 -0
  10. package/build/hooks/use_storage.js.map +1 -0
  11. package/build/utils/native_adapters/configuration.d.ts +2 -0
  12. package/build/utils/native_adapters/configuration.d.ts.map +1 -1
  13. package/build/utils/native_adapters/configuration.js +7 -0
  14. package/build/utils/native_adapters/configuration.js.map +1 -1
  15. package/build/utils/native_adapters/index.d.ts +1 -0
  16. package/build/utils/native_adapters/index.d.ts.map +1 -1
  17. package/build/utils/native_adapters/index.js +1 -0
  18. package/build/utils/native_adapters/index.js.map +1 -1
  19. package/build/utils/native_adapters/storage_adapter.d.ts +17 -0
  20. package/build/utils/native_adapters/storage_adapter.d.ts.map +1 -0
  21. package/build/utils/native_adapters/storage_adapter.js +16 -0
  22. package/build/utils/native_adapters/storage_adapter.js.map +1 -0
  23. package/package.json +2 -2
  24. package/src/hooks/use_async_storage.ts +3 -52
  25. package/src/hooks/use_jolt.ts +6 -9
  26. package/src/hooks/use_storage.ts +69 -0
  27. package/src/utils/native_adapters/configuration.ts +8 -0
  28. package/src/utils/native_adapters/index.ts +1 -0
  29. package/src/utils/native_adapters/storage_adapter.ts +23 -0
@@ -1 +1 @@
1
- {"version":3,"file":"use_async_storage.d.ts","sourceRoot":"","sources":["../../src/hooks/use_async_storage.ts"],"names":[],"mappings":"AAOA,KAAK,QAAQ,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE7E,wBAAgB,eAAe,CAAC,UAAU,EACxC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,UAAU,EACxB,YAAY,GAAE,OAAe,GAC5B,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CA+CpC"}
1
+ {"version":3,"file":"use_async_storage.d.ts","sourceRoot":"","sources":["../../src/hooks/use_async_storage.ts"],"names":[],"mappings":"AAGA,KAAK,QAAQ,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE7E,wBAAgB,eAAe,CAAC,UAAU,EACxC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,UAAU,EACxB,YAAY,GAAE,OAAe,GAC5B,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAEpC"}
@@ -1,47 +1,6 @@
1
- import AsyncStorage from '@react-native-async-storage/async-storage';
2
- import { useSuspenseQuery } from '@tanstack/react-query';
3
- import { noop } from 'lodash';
4
- import { useCallback } from 'react';
5
- const cacheKeyGenerator = (key) => [`AsyncStorageResource:${key}`];
1
+ import { Storage } from '../utils/native_adapters';
2
+ import { useStorage } from './use_storage';
6
3
  export function useAsyncStorage(key, initialValue, throwOnError = false) {
7
- const cacheKey = cacheKeyGenerator(key);
8
- const { data: value, refetch } = useSuspenseQuery({
9
- queryKey: cacheKey,
10
- queryFn: () => AsyncStorage.getItem(key)
11
- .then(storedValue => {
12
- if (!storedValue)
13
- return initialValue;
14
- try {
15
- return JSON.parse(storedValue);
16
- }
17
- catch {
18
- return storedValue;
19
- }
20
- })
21
- .catch(e => {
22
- if (!throwOnError)
23
- return initialValue;
24
- return Promise.reject(e);
25
- }),
26
- });
27
- const setValue = useCallback(itemValue => {
28
- if (itemValue === null || itemValue === undefined) {
29
- return AsyncStorage.removeItem(key)
30
- .then(() => {
31
- refetch();
32
- })
33
- .catch(noop);
34
- }
35
- return AsyncStorage.setItem(key, JSON.stringify(itemValue))
36
- .then(() => {
37
- refetch();
38
- })
39
- .catch(e => {
40
- if (!throwOnError)
41
- return;
42
- return Promise.reject(e);
43
- });
44
- }, [throwOnError, key, refetch]);
45
- return [value || initialValue, setValue];
4
+ return useStorage(Storage, key, initialValue, throwOnError);
46
5
  }
47
6
  //# sourceMappingURL=use_async_storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use_async_storage.js","sourceRoot":"","sources":["../../src/hooks/use_async_storage.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,2CAA2C,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAEnC,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;AAI1E,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,YAAwB,EACxB,eAAwB,KAAK;IAE7B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IAEvC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAa;QAC5D,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,GAAG,EAAE,CACZ,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC;aACtB,IAAI,CAAC,WAAW,CAAC,EAAE;YAClB,IAAI,CAAC,WAAW;gBAAE,OAAO,YAAY,CAAA;YAErC,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,WAAW,CAAA;YACpB,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,IAAI,CAAC,YAAY;gBAAE,OAAO,YAAY,CAAA;YAEtC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC,CAAC;KACP,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAyB,WAAW,CAChD,SAAS,CAAC,EAAE;QACV,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,OAAO,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,GAAG,EAAE;gBACT,OAAO,EAAE,CAAA;YACX,CAAC,CAAC;iBACD,KAAK,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;QAED,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;aACxD,IAAI,CAAC,GAAG,EAAE;YACT,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,IAAI,CAAC,YAAY;gBAAE,OAAM;YAEzB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAA;IACN,CAAC,EACD,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,CAAC,CAC7B,CAAA;IAED,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,QAAQ,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import AsyncStorage from '@react-native-async-storage/async-storage'\nimport { useSuspenseQuery } from '@tanstack/react-query'\nimport { noop } from 'lodash'\nimport { useCallback } from 'react'\n\nconst cacheKeyGenerator = (key: string) => [`AsyncStorageResource:${key}`]\n\ntype SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<void>\n\nexport function useAsyncStorage<TCacheData>(\n key: string,\n initialValue: TCacheData,\n throwOnError: boolean = false\n): [TCacheData, SetValue<TCacheData>] {\n const cacheKey = cacheKeyGenerator(key)\n\n const { data: value, refetch } = useSuspenseQuery<TCacheData>({\n queryKey: cacheKey,\n queryFn: () =>\n AsyncStorage.getItem(key)\n .then(storedValue => {\n if (!storedValue) return initialValue\n\n try {\n return JSON.parse(storedValue)\n } catch {\n return storedValue\n }\n })\n .catch(e => {\n if (!throwOnError) return initialValue\n\n return Promise.reject(e)\n }),\n })\n\n const setValue: SetValue<TCacheData> = useCallback(\n itemValue => {\n if (itemValue === null || itemValue === undefined) {\n return AsyncStorage.removeItem(key)\n .then(() => {\n refetch()\n })\n .catch(noop)\n }\n\n return AsyncStorage.setItem(key, JSON.stringify(itemValue))\n .then(() => {\n refetch()\n })\n .catch(e => {\n if (!throwOnError) return\n\n return Promise.reject(e)\n })\n },\n [throwOnError, key, refetch]\n )\n\n return [value || initialValue, setValue]\n}\n"]}
1
+ {"version":3,"file":"use_async_storage.js","sourceRoot":"","sources":["../../src/hooks/use_async_storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI1C,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,YAAwB,EACxB,eAAwB,KAAK;IAE7B,OAAO,UAAU,CAAa,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;AACzE,CAAC","sourcesContent":["import { Storage } from '../utils/native_adapters'\nimport { useStorage } from './use_storage'\n\ntype SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<void>\n\nexport function useAsyncStorage<TCacheData>(\n key: string,\n initialValue: TCacheData,\n throwOnError: boolean = false\n): [TCacheData, SetValue<TCacheData>] {\n return useStorage<TCacheData>(Storage, key, initialValue, throwOnError)\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use_jolt.d.ts","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;AACpD,OAAO,EACL,aAAa,EAEd,MAAM,uDAAuD,CAAA;AAC9D,OAAO,EAEL,gBAAgB,EACjB,MAAM,yDAAyD,CAAA;AAchE,eAAO,MAAM,aAAa,QAAO,UAAU,GAAG,SAiG7C,CAAA;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAc,GACtB,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAwCrC;AAED,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;AAE5C,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAC5C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAO5B"}
1
+ {"version":3,"file":"use_jolt.d.ts","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;AACpD,OAAO,EACL,aAAa,EAEd,MAAM,uDAAuD,CAAA;AAC9D,OAAO,EAEL,gBAAgB,EACjB,MAAM,yDAAyD,CAAA;AAahE,eAAO,MAAM,aAAa,QAAO,UAAU,GAAG,SAmG7C,CAAA;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAc,GACtB,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAoCrC;AAED,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;AAE5C,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAC5C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAO5B"}
@@ -3,7 +3,6 @@ import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-quer
3
3
  import { useCallback, useEffect, useMemo } from 'react';
4
4
  import { useChatContext } from '../contexts/chat_context';
5
5
  import { Client, Uri } from '../utils';
6
- import { useAppState } from './use_app_state';
7
6
  export const useJoltClient = () => {
8
7
  const { session } = useChatContext();
9
8
  const sessionAccessToken = session.token?.access_token;
@@ -37,6 +36,7 @@ export const useJoltClient = () => {
37
36
  queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),
38
37
  staleTime: Infinity,
39
38
  gcTime: Infinity,
39
+ refetchOnWindowFocus: false,
40
40
  });
41
41
  const fetchAuthTokenFn = () => {
42
42
  return queryClient.fetchQuery({
@@ -78,6 +78,7 @@ export const useJoltClient = () => {
78
78
  fetchSubscribeTokenFn,
79
79
  }, { logToConsole: false });
80
80
  },
81
+ refetchOnWindowFocus: false,
81
82
  staleTime: Infinity,
82
83
  gcTime: Infinity,
83
84
  });
@@ -85,9 +86,8 @@ export const useJoltClient = () => {
85
86
  };
86
87
  export function useJoltChannel(channelName, enabled = true) {
87
88
  const jolt = useJoltClient();
88
- const appState = useAppState();
89
89
  const queryClient = useQueryClient();
90
- const ready = Boolean(jolt) && appState !== 'background' && enabled;
90
+ const ready = Boolean(jolt) && enabled;
91
91
  const handleSubscribe = useCallback(async () => {
92
92
  if (!jolt)
93
93
  return null;
@@ -100,6 +100,7 @@ export function useJoltChannel(channelName, enabled = true) {
100
100
  const { data: subscription } = useQuery({
101
101
  queryKey: ['jolt-subscription', channelName],
102
102
  queryFn: handleSubscribe,
103
+ refetchOnWindowFocus: false,
103
104
  enabled: ready,
104
105
  });
105
106
  const handleUnsubscribe = useCallback(() => {
@@ -110,11 +111,8 @@ export function useJoltChannel(channelName, enabled = true) {
110
111
  jolt?.unsubscribe(channelName);
111
112
  }, [queryClient, channelName, jolt]);
112
113
  useEffect(() => {
113
- if (appState !== 'background')
114
- return handleUnsubscribe;
115
- handleUnsubscribe();
116
- return () => null;
117
- }, [appState, handleUnsubscribe]);
114
+ return handleUnsubscribe;
115
+ }, [handleUnsubscribe]);
118
116
  return subscription;
119
117
  }
120
118
  export function useJoltEvent(channel, eventName, callback) {
@@ -1 +1 @@
1
- {"version":3,"file":"use_jolt.js","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;AASpD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAQ7C,MAAM,CAAC,MAAM,aAAa,GAAG,GAA2B,EAAE;IACxD,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,YAAY,CAAA;IACtD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1D,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CACH,IAAI,MAAM,CAAC;QACT,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;QACzB,cAAc,EAAE,GAAG,CAAC,OAAO;QAC3B,OAAO,EAAE,YAAY;KACtB,CAAC,EACJ,CAAC,GAAG,CAAC,CACN,CAAA;IAED,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,OAAO,WAAW,CAAC,UAAU,CAAC;YAC5B,QAAQ,EAAE,CAAC,YAAY,CAAC;YACxB,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,SAAS,CAAC,IAAI,CAA4B;oBAC/C,GAAG,EAAE,oBAAoB;oBACzB,IAAI,EAAE;wBACJ,IAAI,EAAE;4BACJ,IAAI,EAAE,WAAW;4BACjB,UAAU,EAAE,EAAE;yBACf;qBACF;iBACF,CAAC,CAAA;YACJ,CAAC;YACD,SAAS,EAAE,IAAI,EAAE,YAAY;SAC9B,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,wFAAwF;IACxF,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAS;QAChD,QAAQ,EAAE,CAAC,SAAS,CAAC;QACrB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5D,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;IAEF,MAAM,gBAAgB,GAAmB,GAAG,EAAE;QAC5C,OAAO,WAAW,CAAC,UAAU,CAAC;YAC5B,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SACzD,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,mBAAmB,GAAwB,CAAC,OAAe,EAAE,YAAoB,EAAE,EAAE;QACzF,OAAO,SAAS;aACb,IAAI,CAA4B;YAC/B,GAAG,EAAE,oBAAoB;YACzB,IAAI,EAAE;gBACJ,IAAI,EAAE;oBACJ,IAAI,EAAE,oBAAoB;oBAC1B,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE;iBAC3C;aACF;SACF,CAAC;aACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;aACxB,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACtB,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAA;YACzD,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;IACN,CAAC,CAAA;IAED,MAAM,qBAAqB,GAAwB,CACjD,OAAe,EACf,YAAoB,EACpB,OAAO,EACP,EAAE;QACF,OAAO,WAAW,CAAC,UAAU,CAAC;YAC5B,QAAQ,EAAE,CAAC,sBAAsB,EAAE,OAAO,EAAE,YAAY,CAAC;YACzD,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC;SACnE,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;QACpC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC;QACxB,QAAQ,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,kBAAkB,CAAC;QACrD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAA;YAE7B,OAAO,IAAI,UAAU,CACnB,MAAM,EACN;gBACE,gBAAgB;gBAChB,qBAAqB;aACtB,EACD,EAAE,YAAY,EAAE,KAAK,EAAE,CACxB,CAAA;QACH,CAAC;QACD,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;IAEF,OAAO,UAAU,CAAA;AACnB,CAAC,CAAA;AAED,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,UAAmB,IAAI;IAEvB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,QAAQ,KAAK,YAAY,IAAI,OAAO,CAAA;IAEnE,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC7C,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QAEtB,uEAAuE;QACvE,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAA;QACjF,IAAI,iBAAiB;YAAE,OAAO,iBAAiB,CAAA;QAE/C,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;IACpC,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAA;IAEvB,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,QAAQ,CAA0B;QAC/D,QAAQ,EAAE,CAAC,mBAAmB,EAAE,WAAW,CAAC;QAC5C,OAAO,EAAE,eAAe;QACxB,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;IAEF,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,WAAW,CAAC,aAAa,CAAC;YACxB,QAAQ,EAAE,CAAC,mBAAmB,EAAE,WAAW,CAAC;YAC5C,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;QAEF,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAA;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,KAAK,YAAY;YAAE,OAAO,iBAAiB,CAAA;QAEvD,iBAAiB,EAAE,CAAA;QAEnB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAA;IACnB,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAEjC,OAAO,YAAY,CAAA;AACrB,CAAC;AAID,MAAM,UAAU,YAAY,CAC1B,OAA4C,EAC5C,SAAiB,EACjB,QAA2B;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;QAE7B,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAM,CAAC,CAAC,CAAA;IACvD,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAA;AACpC,CAAC","sourcesContent":["import JoltClient from '@planningcenter/jolt-client'\nimport {\n CustomMessage,\n FetchAuthToken,\n} from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport {\n FetchSubscribeToken,\n JoltSubscription,\n} from '@planningcenter/jolt-client/dist/types/JoltSubscription'\nimport { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { useChatContext } from '../contexts/chat_context'\nimport { ApiResource } from '../types'\nimport { Client, Uri } from '../utils'\nimport { useAppState } from './use_app_state'\n\ninterface JoltResponse {\n type: 'JoltToken'\n id: string\n wssUrl: string\n}\n\nexport const useJoltClient = (): JoltClient | undefined => {\n const { session } = useChatContext()\n const sessionAccessToken = session.token?.access_token\n const queryClient = useQueryClient()\n const uri = useMemo(() => new Uri({ session }), [session])\n const apiClient = useMemo(\n () =>\n new Client({\n root: uri.api(`/chat/v2`),\n defaultHeaders: uri.headers,\n version: '2018-11-01',\n }),\n [uri]\n )\n\n const fetchJoltToken = async () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-token'],\n queryFn: () => {\n return apiClient.post<ApiResource<JoltResponse>>({\n url: '/me/jolt_authorize',\n data: {\n data: {\n type: 'JoltToken',\n attributes: {},\n },\n },\n })\n },\n staleTime: 5000, // 5 seconds\n })\n }\n\n /** The wssUrl is static and doesn't change so we can cache it to infinity and beyond */\n const { data: wssUrl } = useSuspenseQuery<string>({\n queryKey: ['wss-url'],\n queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),\n staleTime: Infinity,\n gcTime: Infinity,\n })\n\n const fetchAuthTokenFn: FetchAuthToken = () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-auth-token'],\n queryFn: () => fetchJoltToken().then(res => res.data.id),\n })\n }\n\n const fetchSubscribeToken: FetchSubscribeToken = (channel: string, connectionId: string) => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_subscribe',\n data: {\n data: {\n type: 'JoltSubscribeToken',\n attributes: { channel, cid: connectionId },\n },\n },\n })\n .then(res => res.data.id)\n .catch((res: unknown) => {\n console.error('failed to subscribe to Jolt channel', res)\n return ''\n })\n }\n\n const fetchSubscribeTokenFn: FetchSubscribeToken = (\n channel: string,\n connectionId: string,\n options\n ) => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-subscribe-token', channel, connectionId],\n queryFn: () => fetchSubscribeToken(channel, connectionId, options),\n })\n }\n\n const { data: joltClient } = useQuery({\n enabled: Boolean(wssUrl),\n queryKey: ['jolt-client', wssUrl, sessionAccessToken],\n queryFn: async () => {\n if (!wssUrl) return undefined\n\n return new JoltClient(\n wssUrl,\n {\n fetchAuthTokenFn,\n fetchSubscribeTokenFn,\n },\n { logToConsole: false }\n )\n },\n staleTime: Infinity,\n gcTime: Infinity,\n })\n\n return joltClient\n}\n\nexport function useJoltChannel(\n channelName: string,\n enabled: boolean = true\n): JoltSubscription | undefined | null {\n const jolt = useJoltClient()\n const appState = useAppState()\n const queryClient = useQueryClient()\n const ready = Boolean(jolt) && appState !== 'background' && enabled\n\n const handleSubscribe = useCallback(async () => {\n if (!jolt) return null\n\n // If the subscription already exists, we don't need to subscribe again\n const alreadySubscribed = jolt.subscriptions.find(c => c.channel === channelName)\n if (alreadySubscribed) return alreadySubscribed\n\n return jolt.subscribe(channelName)\n }, [channelName, jolt])\n\n const { data: subscription } = useQuery<JoltSubscription | null>({\n queryKey: ['jolt-subscription', channelName],\n queryFn: handleSubscribe,\n enabled: ready,\n })\n\n const handleUnsubscribe = useCallback(() => {\n queryClient.removeQueries({\n queryKey: ['jolt-subscription', channelName],\n exact: true,\n })\n\n jolt?.unsubscribe(channelName)\n }, [queryClient, channelName, jolt])\n\n useEffect(() => {\n if (appState !== 'background') return handleUnsubscribe\n\n handleUnsubscribe()\n\n return () => null\n }, [appState, handleUnsubscribe])\n\n return subscription\n}\n\ntype UserCallbackFn<T> = (_event: T) => void\n\nexport function useJoltEvent<T extends CustomMessage>(\n channel: JoltSubscription | undefined | null,\n eventName: string,\n callback: UserCallbackFn<T>\n) {\n useEffect(() => {\n if (!channel) return () => {}\n\n return channel.bind(eventName, e => callback(e as T))\n }, [channel, eventName, callback])\n}\n"]}
1
+ {"version":3,"file":"use_jolt.js","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"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","sourcesContent":["import JoltClient from '@planningcenter/jolt-client'\nimport {\n CustomMessage,\n FetchAuthToken,\n} from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport {\n FetchSubscribeToken,\n JoltSubscription,\n} from '@planningcenter/jolt-client/dist/types/JoltSubscription'\nimport { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { useChatContext } from '../contexts/chat_context'\nimport { ApiResource } from '../types'\nimport { Client, Uri } from '../utils'\n\ninterface JoltResponse {\n type: 'JoltToken'\n id: string\n wssUrl: string\n}\n\nexport const useJoltClient = (): JoltClient | undefined => {\n const { session } = useChatContext()\n const sessionAccessToken = session.token?.access_token\n const queryClient = useQueryClient()\n const uri = useMemo(() => new Uri({ session }), [session])\n const apiClient = useMemo(\n () =>\n new Client({\n root: uri.api(`/chat/v2`),\n defaultHeaders: uri.headers,\n version: '2018-11-01',\n }),\n [uri]\n )\n\n const fetchJoltToken = async () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-token'],\n queryFn: () => {\n return apiClient.post<ApiResource<JoltResponse>>({\n url: '/me/jolt_authorize',\n data: {\n data: {\n type: 'JoltToken',\n attributes: {},\n },\n },\n })\n },\n staleTime: 5000, // 5 seconds\n })\n }\n\n /** The wssUrl is static and doesn't change so we can cache it to infinity and beyond */\n const { data: wssUrl } = useSuspenseQuery<string>({\n queryKey: ['wss-url'],\n queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),\n staleTime: Infinity,\n gcTime: Infinity,\n refetchOnWindowFocus: false,\n })\n\n const fetchAuthTokenFn: FetchAuthToken = () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-auth-token'],\n queryFn: () => fetchJoltToken().then(res => res.data.id),\n })\n }\n\n const fetchSubscribeToken: FetchSubscribeToken = (channel: string, connectionId: string) => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_subscribe',\n data: {\n data: {\n type: 'JoltSubscribeToken',\n attributes: { channel, cid: connectionId },\n },\n },\n })\n .then(res => res.data.id)\n .catch((res: unknown) => {\n console.error('failed to subscribe to Jolt channel', res)\n return ''\n })\n }\n\n const fetchSubscribeTokenFn: FetchSubscribeToken = (\n channel: string,\n connectionId: string,\n options\n ) => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-subscribe-token', channel, connectionId],\n queryFn: () => fetchSubscribeToken(channel, connectionId, options),\n })\n }\n\n const { data: joltClient } = useQuery({\n enabled: Boolean(wssUrl),\n queryKey: ['jolt-client', wssUrl, sessionAccessToken],\n queryFn: async () => {\n if (!wssUrl) return undefined\n\n return new JoltClient(\n wssUrl,\n {\n fetchAuthTokenFn,\n fetchSubscribeTokenFn,\n },\n { logToConsole: false }\n )\n },\n refetchOnWindowFocus: false,\n staleTime: Infinity,\n gcTime: Infinity,\n })\n\n return joltClient\n}\n\nexport function useJoltChannel(\n channelName: string,\n enabled: boolean = true\n): JoltSubscription | undefined | null {\n const jolt = useJoltClient()\n const queryClient = useQueryClient()\n const ready = Boolean(jolt) && enabled\n\n const handleSubscribe = useCallback(async () => {\n if (!jolt) return null\n\n // If the subscription already exists, we don't need to subscribe again\n const alreadySubscribed = jolt.subscriptions.find(c => c.channel === channelName)\n if (alreadySubscribed) return alreadySubscribed\n\n return jolt.subscribe(channelName)\n }, [channelName, jolt])\n\n const { data: subscription } = useQuery<JoltSubscription | null>({\n queryKey: ['jolt-subscription', channelName],\n queryFn: handleSubscribe,\n refetchOnWindowFocus: false,\n enabled: ready,\n })\n\n const handleUnsubscribe = useCallback(() => {\n queryClient.removeQueries({\n queryKey: ['jolt-subscription', channelName],\n exact: true,\n })\n\n jolt?.unsubscribe(channelName)\n }, [queryClient, channelName, jolt])\n\n useEffect(() => {\n return handleUnsubscribe\n }, [handleUnsubscribe])\n\n return subscription\n}\n\ntype UserCallbackFn<T> = (_event: T) => void\n\nexport function useJoltEvent<T extends CustomMessage>(\n channel: JoltSubscription | undefined | null,\n eventName: string,\n callback: UserCallbackFn<T>\n) {\n useEffect(() => {\n if (!channel) return () => {}\n\n return channel.bind(eventName, e => callback(e as T))\n }, [channel, eventName, callback])\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { StorageAdapter } from '../utils/native_adapters';
2
+ type SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<any>;
3
+ /**
4
+ * Hook for using a storage adapter with React Query caching.
5
+ * Similar to useAsyncStorage but accepts a StorageAdapter instead of using AsyncStorage directly.
6
+ */
7
+ export declare function useStorage<TCacheData>(storage: StorageAdapter, key: string, initialValue: TCacheData, throwOnError?: boolean): [TCacheData, SetValue<TCacheData>];
8
+ export {};
9
+ //# sourceMappingURL=use_storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_storage.d.ts","sourceRoot":"","sources":["../../src/hooks/use_storage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAIzD,KAAK,QAAQ,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;AAE5E;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EACnC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,UAAU,EACxB,YAAY,GAAE,OAAe,GAC5B,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAkDpC"}
@@ -0,0 +1,53 @@
1
+ import { useSuspenseQuery } from '@tanstack/react-query';
2
+ import { noop } from 'lodash';
3
+ import { useCallback } from 'react';
4
+ const cacheKeyGenerator = (key) => [`StorageResource:${key}`];
5
+ /**
6
+ * Hook for using a storage adapter with React Query caching.
7
+ * Similar to useAsyncStorage but accepts a StorageAdapter instead of using AsyncStorage directly.
8
+ */
9
+ export function useStorage(storage, key, initialValue, throwOnError = false) {
10
+ const cacheKey = cacheKeyGenerator(key);
11
+ const { data: value, refetch } = useSuspenseQuery({
12
+ queryKey: cacheKey,
13
+ queryFn: () => storage
14
+ .getItem(key)
15
+ .then(storedValue => {
16
+ if (!storedValue)
17
+ return initialValue;
18
+ try {
19
+ return JSON.parse(storedValue);
20
+ }
21
+ catch {
22
+ return storedValue;
23
+ }
24
+ })
25
+ .catch(e => {
26
+ if (!throwOnError)
27
+ return initialValue;
28
+ return Promise.reject(e);
29
+ }),
30
+ });
31
+ const setValue = useCallback(itemValue => {
32
+ if (itemValue === null || itemValue === undefined) {
33
+ return storage
34
+ .removeItem(key)
35
+ .then(() => {
36
+ refetch();
37
+ })
38
+ .catch(noop);
39
+ }
40
+ return storage
41
+ .setItem(key, JSON.stringify(itemValue))
42
+ .then(() => {
43
+ refetch();
44
+ })
45
+ .catch(e => {
46
+ if (!throwOnError)
47
+ return;
48
+ return Promise.reject(e);
49
+ });
50
+ }, [throwOnError, key, refetch, storage]);
51
+ return [value || initialValue, setValue];
52
+ }
53
+ //# sourceMappingURL=use_storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_storage.js","sourceRoot":"","sources":["../../src/hooks/use_storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnC,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAA;AAIrE;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,OAAuB,EACvB,GAAW,EACX,YAAwB,EACxB,eAAwB,KAAK;IAE7B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IAEvC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAa;QAC5D,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,GAAG,EAAE,CACZ,OAAO;aACJ,OAAO,CAAC,GAAG,CAAC;aACZ,IAAI,CAAC,WAAW,CAAC,EAAE;YAClB,IAAI,CAAC,WAAW;gBAAE,OAAO,YAAY,CAAA;YAErC,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,WAAW,CAAA;YACpB,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,IAAI,CAAC,YAAY;gBAAE,OAAO,YAAY,CAAA;YAEtC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC,CAAC;KACP,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAyB,WAAW,CAChD,SAAS,CAAC,EAAE;QACV,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,OAAO,OAAO;iBACX,UAAU,CAAC,GAAG,CAAC;iBACf,IAAI,CAAC,GAAG,EAAE;gBACT,OAAO,EAAE,CAAA;YACX,CAAC,CAAC;iBACD,KAAK,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;QAED,OAAO,OAAO;aACX,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;aACvC,IAAI,CAAC,GAAG,EAAE;YACT,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE;YACT,IAAI,CAAC,YAAY;gBAAE,OAAM;YAEzB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAA;IACN,CAAC,EACD,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CACtC,CAAA;IAED,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,QAAQ,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import { useSuspenseQuery } from '@tanstack/react-query'\nimport { noop } from 'lodash'\nimport { useCallback } from 'react'\nimport { StorageAdapter } from '../utils/native_adapters'\n\nconst cacheKeyGenerator = (key: string) => [`StorageResource:${key}`]\n\ntype SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<any>\n\n/**\n * Hook for using a storage adapter with React Query caching.\n * Similar to useAsyncStorage but accepts a StorageAdapter instead of using AsyncStorage directly.\n */\nexport function useStorage<TCacheData>(\n storage: StorageAdapter,\n key: string,\n initialValue: TCacheData,\n throwOnError: boolean = false\n): [TCacheData, SetValue<TCacheData>] {\n const cacheKey = cacheKeyGenerator(key)\n\n const { data: value, refetch } = useSuspenseQuery<TCacheData>({\n queryKey: cacheKey,\n queryFn: () =>\n storage\n .getItem(key)\n .then(storedValue => {\n if (!storedValue) return initialValue\n\n try {\n return JSON.parse(storedValue)\n } catch {\n return storedValue\n }\n })\n .catch(e => {\n if (!throwOnError) return initialValue\n\n return Promise.reject(e)\n }),\n })\n\n const setValue: SetValue<TCacheData> = useCallback(\n itemValue => {\n if (itemValue === null || itemValue === undefined) {\n return storage\n .removeItem(key)\n .then(() => {\n refetch()\n })\n .catch(noop)\n }\n\n return storage\n .setItem(key, JSON.stringify(itemValue))\n .then(() => {\n refetch()\n })\n .catch(e => {\n if (!throwOnError) return\n\n return Promise.reject(e)\n })\n },\n [throwOnError, key, refetch, storage]\n )\n\n return [value || initialValue, setValue]\n}\n"]}
@@ -5,6 +5,7 @@ import { ImagePickerAdapter } from './image_picker';
5
5
  import { VideoAdapter } from './video';
6
6
  import { LinkingAdapter } from './linking';
7
7
  import { HapticAdapter } from './haptic';
8
+ import { StorageAdapter } from './storage_adapter';
8
9
  type ChatConfigurations = {
9
10
  clipboard: ClipboardAdapter;
10
11
  audio: AudioAdapter;
@@ -24,5 +25,6 @@ export declare let ImagePicker: ImagePickerAdapter;
24
25
  export declare let Log: LogAdapter;
25
26
  export declare let Linking: LinkingAdapter;
26
27
  export declare let Haptic: HapticAdapter;
28
+ export declare let Storage: StorageAdapter;
27
29
  export {};
28
30
  //# sourceMappingURL=configuration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,gBAAgB,CAAA;IAC3B,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB,CAAA;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB;CASpD;AAMD,eAAO,IAAI,SAAS,EAAE,gBAMpB,CAAA;AAEF,eAAO,IAAI,KAAK,EAAE,YAKhB,CAAA;AAEF,eAAO,IAAI,KAAK,EAAE,YAQhB,CAAA;AAEF,eAAO,IAAI,WAAW,EAAE,kBAStB,CAAA;AAEF,eAAO,IAAI,GAAG,EAAE,UAA6B,CAAA;AAE7C,eAAO,IAAI,OAAO,EAAE,cAA8C,CAAA;AAElE,eAAO,IAAI,MAAM,EAAE,aAAmC,CAAA"}
1
+ {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGlD,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,gBAAgB,CAAA;IAC3B,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,kBAAkB,CAAA;IAC/B,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB,CAAA;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB;CASpD;AAMD,eAAO,IAAI,SAAS,EAAE,gBAMpB,CAAA;AAEF,eAAO,IAAI,KAAK,EAAE,YAKhB,CAAA;AAEF,eAAO,IAAI,KAAK,EAAE,YAQhB,CAAA;AAEF,eAAO,IAAI,WAAW,EAAE,kBAStB,CAAA;AAEF,eAAO,IAAI,GAAG,EAAE,UAA6B,CAAA;AAE7C,eAAO,IAAI,OAAO,EAAE,cAA8C,CAAA;AAElE,eAAO,IAAI,MAAM,EAAE,aAAmC,CAAA;AAEtD,eAAO,IAAI,OAAO,gBAIhB,CAAA"}
@@ -6,6 +6,8 @@ import { VideoAdapter } from './video';
6
6
  import { Linking as RNLinking } from 'react-native';
7
7
  import { LinkingAdapter } from './linking';
8
8
  import { HapticAdapter } from './haptic';
9
+ import { StorageAdapter } from './storage_adapter';
10
+ import AsyncStorage from '@react-native-async-storage/async-storage';
9
11
  export class ChatAdapters {
10
12
  static configure(configurations) {
11
13
  Clipboard = configurations.clipboard;
@@ -52,4 +54,9 @@ export let ImagePicker = new ImagePickerAdapter({
52
54
  export let Log = new LogAdapter();
53
55
  export let Linking = new LinkingAdapter(RNLinking);
54
56
  export let Haptic = new HapticAdapter();
57
+ export let Storage = new StorageAdapter({
58
+ getItem: AsyncStorage.getItem,
59
+ setItem: AsyncStorage.setItem,
60
+ removeItem: AsyncStorage.removeItem,
61
+ });
55
62
  //# sourceMappingURL=configuration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAYxC,MAAM,OAAO,YAAY;IACvB,MAAM,CAAC,SAAS,CAAC,cAAkC;QACjD,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;QACpC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAA;QAC5B,KAAK,GAAG,cAAc,CAAC,KAAK,CAAA;QAC5B,WAAW,GAAG,cAAc,CAAC,WAAW,CAAA;QACxC,GAAG,GAAG,cAAc,CAAC,GAAG,IAAI,IAAI,UAAU,EAAE,CAAA;QAC5C,OAAO,GAAG,cAAc,CAAC,OAAO,IAAI,IAAI,cAAc,CAAC,SAAS,CAAC,CAAA;QACjE,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,IAAI,aAAa,EAAE,CAAA;IACvD,CAAC;CACF;AAED,MAAM,aAAa,GAAG,GAAG,EAAE;IACzB,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;AACnF,CAAC,CAAA;AAED,MAAM,CAAC,IAAI,SAAS,GAAqB,IAAI,gBAAgB,CAAC;IAC5D,cAAc,EAAE,KAAK,IAAI,EAAE;QACzB,aAAa,EAAE,CAAA;QACf,OAAO,EAAE,CAAA;IACX,CAAC;IACD,cAAc,EAAE,KAAK,EAAE,CAAS,EAAE,EAAE,CAAC,aAAa,EAAE;CACrD,CAAC,CAAA;AAEF,MAAM,CAAC,IAAI,KAAK,GAAiB,IAAI,YAAY,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE;QACtB,aAAa,EAAE,CAAA;QACf,OAAO,EAAS,CAAA;IAClB,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,IAAI,KAAK,GAAiB,IAAI,YAAY,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM,CACnB,GAAG,EAAE;QACH,aAAa,EAAE,CAAA;QACf,OAAO,IAAI,CAAA;IACb,CAAC,EACD,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE,CAC9C;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,IAAI,WAAW,GAAuB,IAAI,kBAAkB,CAAC;IAClE,eAAe,EAAE,KAAK,IAAI,EAAE;QAC1B,aAAa,EAAE,CAAA;QACf,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IACzC,CAAC;IACD,qBAAqB,EAAE,KAAK,IAAI,EAAE;QAChC,aAAa,EAAE,CAAA;QACf,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IACzC,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,IAAI,GAAG,GAAe,IAAI,UAAU,EAAE,CAAA;AAE7C,MAAM,CAAC,IAAI,OAAO,GAAmB,IAAI,cAAc,CAAC,SAAS,CAAC,CAAA;AAElE,MAAM,CAAC,IAAI,MAAM,GAAkB,IAAI,aAAa,EAAE,CAAA","sourcesContent":["import { LogAdapter } from './log'\nimport { AudioAdapter } from './audio'\nimport { ClipboardAdapter } from './clipboard'\nimport { ImagePickerAdapter } from './image_picker'\nimport { VideoAdapter } from './video'\nimport { Linking as RNLinking } from 'react-native'\nimport { LinkingAdapter } from './linking'\nimport { HapticAdapter } from './haptic'\n\ntype ChatConfigurations = {\n clipboard: ClipboardAdapter\n audio: AudioAdapter\n video: VideoAdapter\n imagePicker: ImagePickerAdapter\n log?: LogAdapter\n linking?: LinkingAdapter\n haptic?: HapticAdapter\n}\n\nexport class ChatAdapters {\n static configure(configurations: ChatConfigurations) {\n Clipboard = configurations.clipboard\n Audio = configurations.audio\n Video = configurations.video\n ImagePicker = configurations.imagePicker\n Log = configurations.log || new LogAdapter()\n Linking = configurations.linking || new LinkingAdapter(RNLinking)\n Haptic = configurations.haptic || new HapticAdapter()\n }\n}\n\nconst methodMissing = () => {\n console.warn('ChatAdapters.configure() must be called before using any adapters')\n}\n\nexport let Clipboard: ClipboardAdapter = new ClipboardAdapter({\n getStringAsync: async () => {\n methodMissing()\n return ''\n },\n setStringAsync: async (_: string) => methodMissing(),\n})\n\nexport let Audio: AudioAdapter = new AudioAdapter({\n useAudio: (_: string) => {\n methodMissing()\n return {} as any\n },\n})\n\nexport let Video: VideoAdapter = new VideoAdapter({\n Player: Object.assign(\n () => {\n methodMissing()\n return null\n },\n { $$typeof: Symbol.for('react.forward_ref') }\n ),\n})\n\nexport let ImagePicker: ImagePickerAdapter = new ImagePickerAdapter({\n openCameraAsync: async () => {\n methodMissing()\n return { canceled: true, assets: null }\n },\n openImageLibraryAsync: async () => {\n methodMissing()\n return { canceled: true, assets: null }\n },\n})\n\nexport let Log: LogAdapter = new LogAdapter()\n\nexport let Linking: LinkingAdapter = new LinkingAdapter(RNLinking)\n\nexport let Haptic: HapticAdapter = new HapticAdapter()\n"]}
1
+ {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/configuration.ts"],"names":[],"mappings":"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","sourcesContent":["import { LogAdapter } from './log'\nimport { AudioAdapter } from './audio'\nimport { ClipboardAdapter } from './clipboard'\nimport { ImagePickerAdapter } from './image_picker'\nimport { VideoAdapter } from './video'\nimport { Linking as RNLinking } from 'react-native'\nimport { LinkingAdapter } from './linking'\nimport { HapticAdapter } from './haptic'\nimport { StorageAdapter } from './storage_adapter'\nimport AsyncStorage from '@react-native-async-storage/async-storage'\n\ntype ChatConfigurations = {\n clipboard: ClipboardAdapter\n audio: AudioAdapter\n video: VideoAdapter\n imagePicker: ImagePickerAdapter\n log?: LogAdapter\n linking?: LinkingAdapter\n haptic?: HapticAdapter\n}\n\nexport class ChatAdapters {\n static configure(configurations: ChatConfigurations) {\n Clipboard = configurations.clipboard\n Audio = configurations.audio\n Video = configurations.video\n ImagePicker = configurations.imagePicker\n Log = configurations.log || new LogAdapter()\n Linking = configurations.linking || new LinkingAdapter(RNLinking)\n Haptic = configurations.haptic || new HapticAdapter()\n }\n}\n\nconst methodMissing = () => {\n console.warn('ChatAdapters.configure() must be called before using any adapters')\n}\n\nexport let Clipboard: ClipboardAdapter = new ClipboardAdapter({\n getStringAsync: async () => {\n methodMissing()\n return ''\n },\n setStringAsync: async (_: string) => methodMissing(),\n})\n\nexport let Audio: AudioAdapter = new AudioAdapter({\n useAudio: (_: string) => {\n methodMissing()\n return {} as any\n },\n})\n\nexport let Video: VideoAdapter = new VideoAdapter({\n Player: Object.assign(\n () => {\n methodMissing()\n return null\n },\n { $$typeof: Symbol.for('react.forward_ref') }\n ),\n})\n\nexport let ImagePicker: ImagePickerAdapter = new ImagePickerAdapter({\n openCameraAsync: async () => {\n methodMissing()\n return { canceled: true, assets: null }\n },\n openImageLibraryAsync: async () => {\n methodMissing()\n return { canceled: true, assets: null }\n },\n})\n\nexport let Log: LogAdapter = new LogAdapter()\n\nexport let Linking: LinkingAdapter = new LinkingAdapter(RNLinking)\n\nexport let Haptic: HapticAdapter = new HapticAdapter()\n\nexport let Storage = new StorageAdapter({\n getItem: AsyncStorage.getItem,\n setItem: AsyncStorage.setItem,\n removeItem: AsyncStorage.removeItem,\n})\n"]}
@@ -6,4 +6,5 @@ export * from './linking';
6
6
  export * from './log';
7
7
  export * from './video';
8
8
  export * from './haptic';
9
+ export * from './storage_adapter';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA"}
@@ -6,4 +6,5 @@ export * from './linking';
6
6
  export * from './log';
7
7
  export * from './video';
8
8
  export * from './haptic';
9
+ export * from './storage_adapter';
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA","sourcesContent":["export * from './audio'\nexport * from './clipboard'\nexport * from './configuration'\nexport * from './image_picker'\nexport * from './linking'\nexport * from './log'\nexport * from './video'\nexport * from './haptic'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './audio'\nexport * from './clipboard'\nexport * from './configuration'\nexport * from './image_picker'\nexport * from './linking'\nexport * from './log'\nexport * from './video'\nexport * from './haptic'\nexport * from './storage_adapter'\n"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Storage adapter interface for abstracting storage implementations.
3
+ * Allows apps to use different storage backends (AsyncStorage, expo-secure-store, etc.)
4
+ * without requiring those dependencies in the shared package.
5
+ */
6
+ export type StorageAdapterMethods = {
7
+ getItem: (key: string) => Promise<string | null>;
8
+ setItem: (key: string, value: string) => Promise<void>;
9
+ removeItem: (key: string) => Promise<void>;
10
+ };
11
+ export declare class StorageAdapter {
12
+ getItem: (key: string) => Promise<string | null>;
13
+ setItem: (key: string, value: string) => Promise<void>;
14
+ removeItem: (key: string) => Promise<void>;
15
+ constructor(methods: StorageAdapterMethods);
16
+ }
17
+ //# sourceMappingURL=storage_adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage_adapter.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/storage_adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAChD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,CAAA;AAED,qBAAa,cAAc;IACzB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAChD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;gBAE9B,OAAO,EAAE,qBAAqB;CAK3C"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Storage adapter interface for abstracting storage implementations.
3
+ * Allows apps to use different storage backends (AsyncStorage, expo-secure-store, etc.)
4
+ * without requiring those dependencies in the shared package.
5
+ */
6
+ export class StorageAdapter {
7
+ getItem;
8
+ setItem;
9
+ removeItem;
10
+ constructor(methods) {
11
+ this.getItem = methods.getItem;
12
+ this.setItem = methods.setItem;
13
+ this.removeItem = methods.removeItem;
14
+ }
15
+ }
16
+ //# sourceMappingURL=storage_adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage_adapter.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/storage_adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,OAAO,cAAc;IACzB,OAAO,CAAyC;IAChD,OAAO,CAA+C;IACtD,UAAU,CAAgC;IAE1C,YAAY,OAA8B;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA;IACtC,CAAC;CACF","sourcesContent":["/**\n * Storage adapter interface for abstracting storage implementations.\n * Allows apps to use different storage backends (AsyncStorage, expo-secure-store, etc.)\n * without requiring those dependencies in the shared package.\n */\n\nexport type StorageAdapterMethods = {\n getItem: (key: string) => Promise<string | null>\n setItem: (key: string, value: string) => Promise<void>\n removeItem: (key: string) => Promise<void>\n}\n\nexport class StorageAdapter {\n getItem: (key: string) => Promise<string | null>\n setItem: (key: string, value: string) => Promise<void>\n removeItem: (key: string) => Promise<void>\n\n constructor(methods: StorageAdapterMethods) {\n this.getItem = methods.getItem\n this.setItem = methods.setItem\n this.removeItem = methods.removeItem\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.21.2-rc.2",
3
+ "version": "3.21.2-rc.4",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -58,5 +58,5 @@
58
58
  "react-native-url-polyfill": "^2.0.0",
59
59
  "typescript": "<5.6.0"
60
60
  },
61
- "gitHead": "4c5cfa026ac37b337abd2cce32e7d28311fda421"
61
+ "gitHead": "243ecc2da2b0a74b66db045af3f30655ea57a55c"
62
62
  }
@@ -1,9 +1,5 @@
1
- import AsyncStorage from '@react-native-async-storage/async-storage'
2
- import { useSuspenseQuery } from '@tanstack/react-query'
3
- import { noop } from 'lodash'
4
- import { useCallback } from 'react'
5
-
6
- const cacheKeyGenerator = (key: string) => [`AsyncStorageResource:${key}`]
1
+ import { Storage } from '../utils/native_adapters'
2
+ import { useStorage } from './use_storage'
7
3
 
8
4
  type SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<void>
9
5
 
@@ -12,50 +8,5 @@ export function useAsyncStorage<TCacheData>(
12
8
  initialValue: TCacheData,
13
9
  throwOnError: boolean = false
14
10
  ): [TCacheData, SetValue<TCacheData>] {
15
- const cacheKey = cacheKeyGenerator(key)
16
-
17
- const { data: value, refetch } = useSuspenseQuery<TCacheData>({
18
- queryKey: cacheKey,
19
- queryFn: () =>
20
- AsyncStorage.getItem(key)
21
- .then(storedValue => {
22
- if (!storedValue) return initialValue
23
-
24
- try {
25
- return JSON.parse(storedValue)
26
- } catch {
27
- return storedValue
28
- }
29
- })
30
- .catch(e => {
31
- if (!throwOnError) return initialValue
32
-
33
- return Promise.reject(e)
34
- }),
35
- })
36
-
37
- const setValue: SetValue<TCacheData> = useCallback(
38
- itemValue => {
39
- if (itemValue === null || itemValue === undefined) {
40
- return AsyncStorage.removeItem(key)
41
- .then(() => {
42
- refetch()
43
- })
44
- .catch(noop)
45
- }
46
-
47
- return AsyncStorage.setItem(key, JSON.stringify(itemValue))
48
- .then(() => {
49
- refetch()
50
- })
51
- .catch(e => {
52
- if (!throwOnError) return
53
-
54
- return Promise.reject(e)
55
- })
56
- },
57
- [throwOnError, key, refetch]
58
- )
59
-
60
- return [value || initialValue, setValue]
11
+ return useStorage<TCacheData>(Storage, key, initialValue, throwOnError)
61
12
  }
@@ -12,7 +12,6 @@ import { useCallback, useEffect, useMemo } from 'react'
12
12
  import { useChatContext } from '../contexts/chat_context'
13
13
  import { ApiResource } from '../types'
14
14
  import { Client, Uri } from '../utils'
15
- import { useAppState } from './use_app_state'
16
15
 
17
16
  interface JoltResponse {
18
17
  type: 'JoltToken'
@@ -59,6 +58,7 @@ export const useJoltClient = (): JoltClient | undefined => {
59
58
  queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),
60
59
  staleTime: Infinity,
61
60
  gcTime: Infinity,
61
+ refetchOnWindowFocus: false,
62
62
  })
63
63
 
64
64
  const fetchAuthTokenFn: FetchAuthToken = () => {
@@ -112,6 +112,7 @@ export const useJoltClient = (): JoltClient | undefined => {
112
112
  { logToConsole: false }
113
113
  )
114
114
  },
115
+ refetchOnWindowFocus: false,
115
116
  staleTime: Infinity,
116
117
  gcTime: Infinity,
117
118
  })
@@ -124,9 +125,8 @@ export function useJoltChannel(
124
125
  enabled: boolean = true
125
126
  ): JoltSubscription | undefined | null {
126
127
  const jolt = useJoltClient()
127
- const appState = useAppState()
128
128
  const queryClient = useQueryClient()
129
- const ready = Boolean(jolt) && appState !== 'background' && enabled
129
+ const ready = Boolean(jolt) && enabled
130
130
 
131
131
  const handleSubscribe = useCallback(async () => {
132
132
  if (!jolt) return null
@@ -141,6 +141,7 @@ export function useJoltChannel(
141
141
  const { data: subscription } = useQuery<JoltSubscription | null>({
142
142
  queryKey: ['jolt-subscription', channelName],
143
143
  queryFn: handleSubscribe,
144
+ refetchOnWindowFocus: false,
144
145
  enabled: ready,
145
146
  })
146
147
 
@@ -154,12 +155,8 @@ export function useJoltChannel(
154
155
  }, [queryClient, channelName, jolt])
155
156
 
156
157
  useEffect(() => {
157
- if (appState !== 'background') return handleUnsubscribe
158
-
159
- handleUnsubscribe()
160
-
161
- return () => null
162
- }, [appState, handleUnsubscribe])
158
+ return handleUnsubscribe
159
+ }, [handleUnsubscribe])
163
160
 
164
161
  return subscription
165
162
  }
@@ -0,0 +1,69 @@
1
+ import { useSuspenseQuery } from '@tanstack/react-query'
2
+ import { noop } from 'lodash'
3
+ import { useCallback } from 'react'
4
+ import { StorageAdapter } from '../utils/native_adapters'
5
+
6
+ const cacheKeyGenerator = (key: string) => [`StorageResource:${key}`]
7
+
8
+ type SetValue<TCacheData> = (_itemValue?: TCacheData | null) => Promise<any>
9
+
10
+ /**
11
+ * Hook for using a storage adapter with React Query caching.
12
+ * Similar to useAsyncStorage but accepts a StorageAdapter instead of using AsyncStorage directly.
13
+ */
14
+ export function useStorage<TCacheData>(
15
+ storage: StorageAdapter,
16
+ key: string,
17
+ initialValue: TCacheData,
18
+ throwOnError: boolean = false
19
+ ): [TCacheData, SetValue<TCacheData>] {
20
+ const cacheKey = cacheKeyGenerator(key)
21
+
22
+ const { data: value, refetch } = useSuspenseQuery<TCacheData>({
23
+ queryKey: cacheKey,
24
+ queryFn: () =>
25
+ storage
26
+ .getItem(key)
27
+ .then(storedValue => {
28
+ if (!storedValue) return initialValue
29
+
30
+ try {
31
+ return JSON.parse(storedValue)
32
+ } catch {
33
+ return storedValue
34
+ }
35
+ })
36
+ .catch(e => {
37
+ if (!throwOnError) return initialValue
38
+
39
+ return Promise.reject(e)
40
+ }),
41
+ })
42
+
43
+ const setValue: SetValue<TCacheData> = useCallback(
44
+ itemValue => {
45
+ if (itemValue === null || itemValue === undefined) {
46
+ return storage
47
+ .removeItem(key)
48
+ .then(() => {
49
+ refetch()
50
+ })
51
+ .catch(noop)
52
+ }
53
+
54
+ return storage
55
+ .setItem(key, JSON.stringify(itemValue))
56
+ .then(() => {
57
+ refetch()
58
+ })
59
+ .catch(e => {
60
+ if (!throwOnError) return
61
+
62
+ return Promise.reject(e)
63
+ })
64
+ },
65
+ [throwOnError, key, refetch, storage]
66
+ )
67
+
68
+ return [value || initialValue, setValue]
69
+ }
@@ -6,6 +6,8 @@ import { VideoAdapter } from './video'
6
6
  import { Linking as RNLinking } from 'react-native'
7
7
  import { LinkingAdapter } from './linking'
8
8
  import { HapticAdapter } from './haptic'
9
+ import { StorageAdapter } from './storage_adapter'
10
+ import AsyncStorage from '@react-native-async-storage/async-storage'
9
11
 
10
12
  type ChatConfigurations = {
11
13
  clipboard: ClipboardAdapter
@@ -74,3 +76,9 @@ export let Log: LogAdapter = new LogAdapter()
74
76
  export let Linking: LinkingAdapter = new LinkingAdapter(RNLinking)
75
77
 
76
78
  export let Haptic: HapticAdapter = new HapticAdapter()
79
+
80
+ export let Storage = new StorageAdapter({
81
+ getItem: AsyncStorage.getItem,
82
+ setItem: AsyncStorage.setItem,
83
+ removeItem: AsyncStorage.removeItem,
84
+ })
@@ -6,3 +6,4 @@ export * from './linking'
6
6
  export * from './log'
7
7
  export * from './video'
8
8
  export * from './haptic'
9
+ export * from './storage_adapter'
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Storage adapter interface for abstracting storage implementations.
3
+ * Allows apps to use different storage backends (AsyncStorage, expo-secure-store, etc.)
4
+ * without requiring those dependencies in the shared package.
5
+ */
6
+
7
+ export type StorageAdapterMethods = {
8
+ getItem: (key: string) => Promise<string | null>
9
+ setItem: (key: string, value: string) => Promise<void>
10
+ removeItem: (key: string) => Promise<void>
11
+ }
12
+
13
+ export class StorageAdapter {
14
+ getItem: (key: string) => Promise<string | null>
15
+ setItem: (key: string, value: string) => Promise<void>
16
+ removeItem: (key: string) => Promise<void>
17
+
18
+ constructor(methods: StorageAdapterMethods) {
19
+ this.getItem = methods.getItem
20
+ this.setItem = methods.setItem
21
+ this.removeItem = methods.removeItem
22
+ }
23
+ }