@planningcenter/chat-react-native 3.21.2-rc.3 → 3.21.2-rc.5

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 (31) hide show
  1. package/build/contexts/session_context.d.ts +40 -0
  2. package/build/contexts/session_context.d.ts.map +1 -0
  3. package/build/contexts/session_context.js +131 -0
  4. package/build/contexts/session_context.js.map +1 -0
  5. package/build/hooks/use_async_storage.d.ts.map +1 -1
  6. package/build/hooks/use_async_storage.js +3 -44
  7. package/build/hooks/use_async_storage.js.map +1 -1
  8. package/build/hooks/use_storage.d.ts +9 -0
  9. package/build/hooks/use_storage.d.ts.map +1 -0
  10. package/build/hooks/use_storage.js +53 -0
  11. package/build/hooks/use_storage.js.map +1 -0
  12. package/build/utils/native_adapters/configuration.d.ts +2 -0
  13. package/build/utils/native_adapters/configuration.d.ts.map +1 -1
  14. package/build/utils/native_adapters/configuration.js +7 -0
  15. package/build/utils/native_adapters/configuration.js.map +1 -1
  16. package/build/utils/native_adapters/index.d.ts +1 -0
  17. package/build/utils/native_adapters/index.d.ts.map +1 -1
  18. package/build/utils/native_adapters/index.js +1 -0
  19. package/build/utils/native_adapters/index.js.map +1 -1
  20. package/build/utils/native_adapters/storage_adapter.d.ts +17 -0
  21. package/build/utils/native_adapters/storage_adapter.d.ts.map +1 -0
  22. package/build/utils/native_adapters/storage_adapter.js +16 -0
  23. package/build/utils/native_adapters/storage_adapter.js.map +1 -0
  24. package/package.json +2 -2
  25. package/src/__tests__/contexts/session_context.tsx +420 -0
  26. package/src/contexts/session_context.tsx +234 -0
  27. package/src/hooks/use_async_storage.ts +3 -52
  28. package/src/hooks/use_storage.ts +69 -0
  29. package/src/utils/native_adapters/configuration.ts +8 -0
  30. package/src/utils/native_adapters/index.ts +1 -0
  31. package/src/utils/native_adapters/storage_adapter.ts +23 -0
@@ -0,0 +1,40 @@
1
+ import { Session, ENV } from '../utils';
2
+ import { FailedResponse, OAuthToken } from '../types';
3
+ import { QueryClient } from '@tanstack/react-query';
4
+ import React, { PropsWithChildren } from 'react';
5
+ import { StorageAdapter } from '../utils/native_adapters/storage_adapter';
6
+ export type SessionContextValue = {
7
+ env: ENV;
8
+ setEnv: (_env: ENV) => void;
9
+ session: Session;
10
+ token: OAuthToken | undefined;
11
+ handleUnauthorizedResponse: (_response: FailedResponse) => void;
12
+ logout: () => void;
13
+ setToken: (_token: OAuthToken) => void;
14
+ };
15
+ export declare const SessionContext: React.Context<SessionContextValue>;
16
+ export type SessionContextConfig = {
17
+ storage: StorageAdapter;
18
+ secureStorage: StorageAdapter;
19
+ refreshTokenFn: (params: {
20
+ refresh_token: string;
21
+ env: ENV;
22
+ }) => Promise<OAuthToken>;
23
+ onLogout: () => void | Promise<void>;
24
+ storageKeys?: {
25
+ env?: string;
26
+ sessions?: string;
27
+ };
28
+ alertConfig?: {
29
+ title?: string;
30
+ message?: string;
31
+ retryText?: string;
32
+ logoutText?: string;
33
+ };
34
+ defaultEnv?: ENV;
35
+ };
36
+ export declare function SessionContextProvider({ children, queryClient, config, }: PropsWithChildren<{
37
+ queryClient: QueryClient;
38
+ config: SessionContextConfig;
39
+ }>): React.JSX.Element;
40
+ //# sourceMappingURL=session_context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_context.d.ts","sourceRoot":"","sources":["../../src/contexts/session_context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErD,OAAO,EAAE,WAAW,EAAe,MAAM,uBAAuB,CAAA;AAChE,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAKlB,MAAM,OAAO,CAAA;AAGd,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAA;AAEzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,GAAG,CAAA;IACR,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;IAC7B,0BAA0B,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;IAC/D,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,cAAc,oCAQzB,CAAA;AAaF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,OAAO,EAAE,cAAc,CAAA;IACvB,aAAa,EAAE,cAAc,CAAA;IAG7B,cAAc,EAAE,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACpF,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAGpC,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,UAAU,CAAC,EAAE,GAAG,CAAA;CACjB,CAAA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,EACX,MAAM,GACP,EAAE,iBAAiB,CAAC;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC,qBA+J/E"}
@@ -0,0 +1,131 @@
1
+ import { Session } from '../utils';
2
+ import { chatQueryClient } from './api_provider';
3
+ import { useMutation } from '@tanstack/react-query';
4
+ import React, { createContext, useCallback, useEffect, useMemo, useState, } from 'react';
5
+ import { Alert } from 'react-native';
6
+ import { useStorage } from '../hooks/use_storage';
7
+ export const SessionContext = createContext({
8
+ env: 'production',
9
+ setEnv: () => null,
10
+ session: new Session(),
11
+ token: undefined,
12
+ handleUnauthorizedResponse: () => null,
13
+ logout: () => null,
14
+ setToken: () => null,
15
+ });
16
+ const environments = ['production', 'staging', 'development'];
17
+ const initialSessions = environments.reduce((acc, env) => {
18
+ const sessionProps = { env, token: undefined };
19
+ acc[env] = new Session(sessionProps).toString();
20
+ return acc;
21
+ }, {});
22
+ export function SessionContextProvider({ children, queryClient, config, }) {
23
+ const { storage, secureStorage, refreshTokenFn, onLogout, storageKeys = {}, alertConfig = {}, defaultEnv = 'production', } = config;
24
+ const envKey = storageKeys.env || 'env';
25
+ const sessionsKey = storageKeys.sessions || 'sessions-storage';
26
+ const [env, setEnv] = useStorage(storage, envKey, defaultEnv);
27
+ const [sessions, setSessions] = useStorage(secureStorage, sessionsKey, initialSessions);
28
+ const [alertShown, setAlertShown] = useState(false);
29
+ const session = useMemo(() => Session.hydrate(sessions[env]), [sessions, env]);
30
+ const { token } = session;
31
+ const { mutate: refreshToken, isPending: isRefreshingToken, isError: isRefreshError, } = useMutation({
32
+ mutationKey: ['refresh-token', token?.refresh_token],
33
+ mutationFn: () => {
34
+ if (!token?.refresh_token) {
35
+ return Promise.reject(new Error('Refresh token is required'));
36
+ }
37
+ return refreshTokenFn({ refresh_token: token.refresh_token, env: session.env }).then(handleTokenUpdate);
38
+ },
39
+ onError: (t) => {
40
+ handleRefreshFailed(t);
41
+ },
42
+ });
43
+ const handleClearQueryClient = useCallback(() => {
44
+ chatQueryClient.clear();
45
+ queryClient.clear();
46
+ }, [queryClient]);
47
+ const handleSetEnv = useCallback((_env) => {
48
+ setEnv(_env);
49
+ handleClearQueryClient();
50
+ }, [handleClearQueryClient, setEnv]);
51
+ const handleLogout = useCallback(async () => {
52
+ handleClearQueryClient();
53
+ return setSessions({
54
+ ...sessions,
55
+ [env]: new Session({ env }).toString(),
56
+ }).then(() => onLogout());
57
+ }, [env, sessions, setSessions, handleClearQueryClient, onLogout]);
58
+ const handleTokenUpdate = useCallback((t) => {
59
+ if (!t || !session)
60
+ return t;
61
+ session.token = t;
62
+ return setSessions({
63
+ ...sessions,
64
+ [env]: session?.toString(),
65
+ }).then(() => t);
66
+ }, [env, session, sessions, setSessions]);
67
+ const handleRefreshFailed = useCallback((t) => {
68
+ if (t.status !== 401)
69
+ return;
70
+ // If we didn't fail because of an unauthorized response ( 401 ),
71
+ // it could be because we were unable to store the token.
72
+ // Do not log out.
73
+ const { errors = [] } = t;
74
+ // The code for a forced logout is "capuchin"
75
+ const isForcedLogout = errors.some((e) => /capuchin/i.test(e.detail || ''));
76
+ if (isForcedLogout) {
77
+ handleLogout();
78
+ }
79
+ }, [handleLogout]);
80
+ const handleUnauthorizedResponse = useCallback(async (response) => {
81
+ const { errors = [] } = response;
82
+ const isUnauthorized = errors.some((e) => /TRASH_PANDA/i.test(e.detail || ''));
83
+ if (isUnauthorized)
84
+ return;
85
+ const isForcedLogout = errors.some((e) => /capuchin/i.test(e.detail || ''));
86
+ const isExpiredToken = errors.some((e) => /baboon/i.test(e.detail || ''));
87
+ if (!isRefreshingToken || isExpiredToken || isForcedLogout) {
88
+ refreshToken();
89
+ }
90
+ }, [refreshToken, isRefreshingToken]);
91
+ const sessionContextValue = {
92
+ env: session.env,
93
+ token: session.token,
94
+ session,
95
+ logout: handleLogout,
96
+ setToken: handleTokenUpdate,
97
+ handleUnauthorizedResponse,
98
+ setEnv: handleSetEnv,
99
+ };
100
+ const alertTitle = alertConfig.title || 'Oops';
101
+ const alertMessage = alertConfig.message || 'Something went wrong with your login!';
102
+ const retryText = alertConfig.retryText || 'Keep trying';
103
+ const logoutText = alertConfig.logoutText || 'Logout';
104
+ useEffect(() => {
105
+ if (isRefreshError && !alertShown && token?.refresh_token) {
106
+ setAlertShown(true);
107
+ Alert.alert(alertTitle, alertMessage, [
108
+ {
109
+ text: retryText,
110
+ onPress: () => {
111
+ refreshToken();
112
+ setAlertShown(false);
113
+ },
114
+ },
115
+ { text: logoutText, onPress: () => handleLogout() },
116
+ ]);
117
+ }
118
+ }, [
119
+ isRefreshError,
120
+ handleLogout,
121
+ alertShown,
122
+ refreshToken,
123
+ token?.refresh_token,
124
+ alertTitle,
125
+ alertMessage,
126
+ retryText,
127
+ logoutText,
128
+ ]);
129
+ return <SessionContext.Provider value={sessionContextValue}>{children}</SessionContext.Provider>;
130
+ }
131
+ //# sourceMappingURL=session_context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_context.js","sourceRoot":"","sources":["../../src/contexts/session_context.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Session, ENV } from '../utils'\nimport { FailedResponse, OAuthToken } from '../types'\nimport { chatQueryClient } from './api_provider'\nimport { QueryClient, useMutation } from '@tanstack/react-query'\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { Alert } from 'react-native'\nimport { useStorage } from '../hooks/use_storage'\nimport { StorageAdapter } from '../utils/native_adapters/storage_adapter'\n\nexport type SessionContextValue = {\n env: ENV\n setEnv: (_env: ENV) => void\n session: Session\n token: OAuthToken | undefined\n handleUnauthorizedResponse: (_response: FailedResponse) => void\n logout: () => void\n setToken: (_token: OAuthToken) => void\n}\n\nexport const SessionContext = createContext<SessionContextValue>({\n env: 'production',\n setEnv: () => null,\n session: new Session(),\n token: undefined,\n handleUnauthorizedResponse: () => null,\n logout: () => null,\n setToken: () => null,\n})\n\ntype Sessions = Record<ENV, string>\nconst environments: ENV[] = ['production', 'staging', 'development']\n\nconst initialSessions = environments.reduce((acc, env) => {\n const sessionProps = { env, token: undefined }\n\n acc[env] = new Session(sessionProps).toString()\n\n return acc\n}, {} as Sessions)\n\nexport type SessionContextConfig = {\n // Storage adapters\n storage: StorageAdapter // For non-sensitive data (env preference)\n secureStorage: StorageAdapter // For sensitive data (tokens/sessions)\n\n // Functional callbacks\n refreshTokenFn: (params: { refresh_token: string; env: ENV }) => Promise<OAuthToken>\n onLogout: () => void | Promise<void>\n\n // Optional configuration\n storageKeys?: {\n env?: string\n sessions?: string\n }\n alertConfig?: {\n title?: string\n message?: string\n retryText?: string\n logoutText?: string\n }\n defaultEnv?: ENV\n}\n\nexport function SessionContextProvider({\n children,\n queryClient,\n config,\n}: PropsWithChildren<{ queryClient: QueryClient; config: SessionContextConfig }>) {\n const {\n storage,\n secureStorage,\n refreshTokenFn,\n onLogout,\n storageKeys = {},\n alertConfig = {},\n defaultEnv = 'production',\n } = config\n\n const envKey = storageKeys.env || 'env'\n const sessionsKey = storageKeys.sessions || 'sessions-storage'\n\n const [env, setEnv] = useStorage<ENV>(storage, envKey, defaultEnv)\n const [sessions, setSessions] = useStorage<Sessions>(secureStorage, sessionsKey, initialSessions)\n const [alertShown, setAlertShown] = useState(false)\n const session = useMemo(() => Session.hydrate<OAuthToken>(sessions[env]), [sessions, env])\n const { token } = session\n\n const {\n mutate: refreshToken,\n isPending: isRefreshingToken,\n isError: isRefreshError,\n } = useMutation({\n mutationKey: ['refresh-token', token?.refresh_token],\n mutationFn: () => {\n if (!token?.refresh_token) {\n return Promise.reject(new Error('Refresh token is required'))\n }\n return refreshTokenFn({ refresh_token: token.refresh_token, env: session.env }).then(\n handleTokenUpdate\n )\n },\n onError: (t: Partial<FailedResponse>) => {\n handleRefreshFailed(t)\n },\n })\n\n const handleClearQueryClient = useCallback(() => {\n chatQueryClient.clear()\n queryClient.clear()\n }, [queryClient])\n\n const handleSetEnv = useCallback(\n (_env: ENV) => {\n setEnv(_env)\n handleClearQueryClient()\n },\n [handleClearQueryClient, setEnv]\n )\n\n const handleLogout = useCallback(async () => {\n handleClearQueryClient()\n\n return setSessions({\n ...sessions,\n [env]: new Session({ env }).toString(),\n }).then(() => onLogout())\n }, [env, sessions, setSessions, handleClearQueryClient, onLogout])\n\n const handleTokenUpdate = useCallback(\n (t: OAuthToken) => {\n if (!t || !session) return t\n\n session.token = t\n\n return setSessions({\n ...sessions,\n [env]: session?.toString(),\n }).then(() => t)\n },\n [env, session, sessions, setSessions]\n )\n\n const handleRefreshFailed = useCallback(\n (t: Partial<FailedResponse>) => {\n if (t.status !== 401) return\n // If we didn't fail because of an unauthorized response ( 401 ),\n // it could be because we were unable to store the token.\n // Do not log out.\n\n const { errors = [] } = t\n // The code for a forced logout is \"capuchin\"\n const isForcedLogout = errors.some((e: { detail?: string }) =>\n /capuchin/i.test(e.detail || '')\n )\n\n if (isForcedLogout) {\n handleLogout()\n }\n },\n [handleLogout]\n )\n\n const handleUnauthorizedResponse = useCallback(\n async (response: FailedResponse) => {\n const { errors = [] } = response\n\n const isUnauthorized = errors.some((e: { detail?: string }) =>\n /TRASH_PANDA/i.test(e.detail || '')\n )\n\n if (isUnauthorized) return\n\n const isForcedLogout = errors.some((e: { detail?: string }) =>\n /capuchin/i.test(e.detail || '')\n )\n const isExpiredToken = errors.some((e: { detail?: string }) => /baboon/i.test(e.detail || ''))\n\n if (!isRefreshingToken || isExpiredToken || isForcedLogout) {\n refreshToken()\n }\n },\n [refreshToken, isRefreshingToken]\n )\n\n const sessionContextValue: SessionContextValue = {\n env: session.env,\n token: session.token,\n session,\n logout: handleLogout,\n setToken: handleTokenUpdate,\n handleUnauthorizedResponse,\n setEnv: handleSetEnv,\n }\n\n const alertTitle = alertConfig.title || 'Oops'\n const alertMessage = alertConfig.message || 'Something went wrong with your login!'\n const retryText = alertConfig.retryText || 'Keep trying'\n const logoutText = alertConfig.logoutText || 'Logout'\n\n useEffect(() => {\n if (isRefreshError && !alertShown && token?.refresh_token) {\n setAlertShown(true)\n Alert.alert(alertTitle, alertMessage, [\n {\n text: retryText,\n onPress: () => {\n refreshToken()\n setAlertShown(false)\n },\n },\n { text: logoutText, onPress: () => handleLogout() },\n ])\n }\n }, [\n isRefreshError,\n handleLogout,\n alertShown,\n refreshToken,\n token?.refresh_token,\n alertTitle,\n alertMessage,\n retryText,\n logoutText,\n ])\n\n return <SessionContext.Provider value={sessionContextValue}>{children}</SessionContext.Provider>\n}\n"]}
@@ -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"]}
@@ -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":"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;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,YAAY,MAAM,2CAA2C,CAAA;AAYpE,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;AAEtD,MAAM,CAAC,IAAI,OAAO,GAAG,IAAI,cAAc,CAAC;IACtC,OAAO,EAAE,YAAY,CAAC,OAAO;IAC7B,OAAO,EAAE,YAAY,CAAC,OAAO;IAC7B,UAAU,EAAE,YAAY,CAAC,UAAU;CACpC,CAAC,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'\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.3",
3
+ "version": "3.21.2-rc.5",
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": "a963dc243ab9a2d6c12b29312e84550a787858a9"
61
+ "gitHead": "c1a1960f32f77300be55537e4b34860322c12ff7"
62
62
  }