jazz-tools 0.19.22 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.svelte-kit/__package__/react.d.ts.map +1 -1
- package/.svelte-kit/__package__/react.tsx +5 -2
- package/.turbo/turbo-build.log +71 -83
- package/CHANGELOG.md +69 -0
- package/dist/better-auth/auth/react.d.ts.map +1 -1
- package/dist/better-auth/auth/react.js +5 -2
- package/dist/better-auth/auth/react.js.map +1 -1
- package/dist/browser/createBrowserContext.d.ts +1 -2
- package/dist/browser/createBrowserContext.d.ts.map +1 -1
- package/dist/browser/index.js +1 -8
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/provideBrowserLockSession/SessionIDStorage.d.ts +1 -1
- package/dist/{chunk-QCTQH5RS.js → chunk-3CAPPS2F.js} +234 -101
- package/dist/chunk-3CAPPS2F.js.map +1 -0
- package/dist/{chunk-M2HGBOXS.js → chunk-K4D7IMFM.js} +3 -3
- package/dist/chunk-K4D7IMFM.js.map +1 -0
- package/dist/expo/auth/clerk/index.d.ts.map +1 -1
- package/dist/expo/index.js +5 -2
- package/dist/expo/index.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/inspector/{chunk-YQNK5Y7B.js → chunk-MCTB5ZJC.js} +1 -1
- package/dist/inspector/chunk-MCTB5ZJC.js.map +1 -0
- package/dist/inspector/contexts/node.d.ts.map +1 -1
- package/dist/inspector/{custom-element-KYV64IOC.js → custom-element-5YWVZBWA.js} +1 -1
- package/dist/inspector/{custom-element-KYV64IOC.js.map → custom-element-5YWVZBWA.js.map} +1 -1
- package/dist/inspector/index.js +3 -3
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/standalone.js +1 -1
- package/dist/react/auth/Clerk.d.ts.map +1 -1
- package/dist/react/hooks.d.ts +1 -1
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/index.js +61 -47
- package/dist/react/index.js.map +1 -1
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/ssr.js +2 -2
- package/dist/react/ssr.js.map +1 -1
- package/dist/react-core/chunk-UOYH6JFJ.js +10 -0
- package/dist/react-core/chunk-UOYH6JFJ.js.map +1 -0
- package/dist/react-core/hooks.d.ts +3 -3
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +27 -25
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/provider.d.ts +2 -3
- package/dist/react-core/provider.d.ts.map +1 -1
- package/dist/react-core/testing.d.ts.map +1 -1
- package/dist/react-core/testing.js +4 -10
- package/dist/react-core/testing.js.map +1 -1
- package/dist/react-native/index.js +61 -53
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native-core/ReactNativeContextManager.d.ts +0 -1
- package/dist/react-native-core/ReactNativeContextManager.d.ts.map +1 -1
- package/dist/react-native-core/hooks.d.ts +1 -1
- package/dist/react-native-core/hooks.d.ts.map +1 -1
- package/dist/react-native-core/index.js +58 -50
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/platform.d.ts +0 -4
- package/dist/react-native-core/platform.d.ts.map +1 -1
- package/dist/react-native-core/provider.d.ts +2 -1
- package/dist/react-native-core/provider.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +2 -8
- package/dist/svelte/tests/AccountCoState.svelte.test.d.ts +2 -0
- package/dist/svelte/tests/AccountCoState.svelte.test.d.ts.map +1 -0
- package/dist/svelte/tests/AccountCoState.svelte.test.js +59 -0
- package/dist/svelte/tests/CoState.svelte.test.js +23 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts +11 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts.map +1 -0
- package/dist/testing.js +6 -6
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/coList.d.ts +2 -2
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +2 -2
- package/dist/tools/coValues/deepLoading.d.ts +2 -2
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +32 -0
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
- package/dist/tools/implementation/createContext.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +3 -3
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +5 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/ssr.js +1 -1
- package/dist/tools/subscribe/JazzError.d.ts +3 -3
- package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/types.d.ts +5 -1
- package/dist/tools/subscribe/types.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +3 -3
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/deleteCoValues.test.d.ts +2 -0
- package/dist/tools/tests/deleteCoValues.test.d.ts.map +1 -0
- package/dist/tools/tests/deletedState.test.d.ts +2 -0
- package/dist/tools/tests/deletedState.test.d.ts.map +1 -0
- package/dist/worker/edge-wasm.js +2 -1
- package/dist/worker/edge-wasm.js.map +1 -1
- package/dist/worker/wasm.d.ts +2 -0
- package/dist/worker/wasm.d.ts.map +1 -0
- package/package.json +9 -28
- package/src/better-auth/auth/react.tsx +5 -2
- package/src/browser/createBrowserContext.ts +2 -5
- package/src/expo/auth/clerk/index.tsx +5 -2
- package/src/inspector/contexts/node.tsx +1 -2
- package/src/inspector/index.tsx +2 -2
- package/src/react/auth/Clerk.tsx +5 -2
- package/src/react/auth/PasskeyAuth.tsx +2 -2
- package/src/react/hooks.tsx +3 -2
- package/src/react/provider.tsx +45 -41
- package/src/react-core/auth/DemoAuth.tsx +2 -2
- package/src/react-core/auth/PassphraseAuth.tsx +2 -2
- package/src/react-core/hooks.ts +26 -27
- package/src/react-core/provider.tsx +1 -5
- package/src/react-core/testing.tsx +3 -11
- package/src/react-core/tests/useAccount.selector.test.ts +2 -3
- package/src/react-core/tests/useAccount.test.ts +57 -7
- package/src/react-core/tests/useCoState.test.ts +37 -0
- package/src/react-core/tests/useInboxSender.test.ts +2 -5
- package/src/react-core/tests/useSuspenseAccount.test.tsx +68 -0
- package/src/react-core/tests/useSuspenseCoState.test.tsx +44 -0
- package/src/react-native-core/ReactNativeContextManager.ts +0 -3
- package/src/react-native-core/auth/usePasskeyAuth.tsx +2 -2
- package/src/react-native-core/hooks.tsx +3 -3
- package/src/react-native-core/platform.ts +2 -6
- package/src/react-native-core/provider.tsx +47 -43
- package/src/svelte/jazz.class.svelte.ts +2 -8
- package/src/svelte/tests/AccountCoState.svelte.test.ts +79 -0
- package/src/svelte/tests/CoState.svelte.test.ts +36 -0
- package/src/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
- package/src/tools/coValues/deepLoading.ts +2 -0
- package/src/tools/coValues/interfaces.ts +170 -32
- package/src/tools/exports.ts +1 -0
- package/src/tools/implementation/ContextManager.ts +2 -2
- package/src/tools/implementation/createContext.ts +4 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +30 -6
- package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +55 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +33 -14
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +35 -6
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +35 -14
- package/src/tools/ssr/ssr.ts +2 -2
- package/src/tools/subscribe/CoValueCoreSubscription.ts +1 -0
- package/src/tools/subscribe/JazzError.ts +4 -1
- package/src/tools/subscribe/SubscriptionScope.ts +23 -0
- package/src/tools/subscribe/types.ts +5 -0
- package/src/tools/testing.ts +5 -5
- package/src/tools/tests/PassphraseAuth.test.ts +5 -5
- package/src/tools/tests/deleteCoValues.test.ts +231 -0
- package/src/tools/tests/deletedState.test.ts +110 -0
- package/src/tools/tests/request.test.ts +15 -2
- package/src/worker/edge-wasm.ts +2 -1
- package/src/worker/wasm.ts +1 -0
- package/tsup.config.ts +0 -4
- package/dist/browser/storageOptions.d.ts +0 -8
- package/dist/browser/storageOptions.d.ts.map +0 -1
- package/dist/browser/tests/storageOptions.test.d.ts +0 -2
- package/dist/browser/tests/storageOptions.test.d.ts.map +0 -1
- package/dist/chunk-M2HGBOXS.js.map +0 -1
- package/dist/chunk-QCTQH5RS.js.map +0 -1
- package/dist/expo/crypto.d.ts +0 -2
- package/dist/expo/crypto.d.ts.map +0 -1
- package/dist/expo/crypto.js +0 -6
- package/dist/expo/crypto.js.map +0 -1
- package/dist/inspector/chunk-YQNK5Y7B.js.map +0 -1
- package/dist/react-core/chunk-7DYMJ74I.js +0 -12
- package/dist/react-core/chunk-7DYMJ74I.js.map +0 -1
- package/dist/react-native/chunk-DGUM43GV.js +0 -11
- package/dist/react-native/chunk-DGUM43GV.js.map +0 -1
- package/dist/react-native/crypto.d.ts +0 -2
- package/dist/react-native/crypto.d.ts.map +0 -1
- package/dist/react-native/crypto.js +0 -8
- package/dist/react-native/crypto.js.map +0 -1
- package/dist/react-native-core/chunk-DGUM43GV.js +0 -11
- package/dist/react-native-core/chunk-DGUM43GV.js.map +0 -1
- package/dist/react-native-core/crypto/RNCrypto.d.ts +0 -2
- package/dist/react-native-core/crypto/RNCrypto.d.ts.map +0 -1
- package/dist/react-native-core/crypto/RNCrypto.js +0 -3
- package/dist/react-native-core/crypto/RNCrypto.js.map +0 -1
- package/dist/react-native-core/crypto/RNQuickCrypto.d.ts +0 -17
- package/dist/react-native-core/crypto/RNQuickCrypto.d.ts.map +0 -1
- package/dist/react-native-core/crypto/index.d.ts +0 -2
- package/dist/react-native-core/crypto/index.d.ts.map +0 -1
- package/dist/react-native-core/crypto.js +0 -89
- package/dist/react-native-core/crypto.js.map +0 -1
- package/src/browser/storageOptions.ts +0 -17
- package/src/browser/tests/storageOptions.test.ts +0 -33
- package/src/expo/crypto.ts +0 -1
- package/src/react-native/crypto.ts +0 -1
- package/src/react-native-core/crypto/RNCrypto.ts +0 -1
- package/src/react-native-core/crypto/RNQuickCrypto.ts +0 -122
- package/src/react-native-core/crypto/index.ts +0 -1
|
@@ -218,6 +218,50 @@ describe("useSuspenseCoState", () => {
|
|
|
218
218
|
);
|
|
219
219
|
});
|
|
220
220
|
|
|
221
|
+
it("should throw error when CoValue is deleted", async () => {
|
|
222
|
+
const TestMap = co.map({
|
|
223
|
+
value: z.string(),
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const owner = await createJazzTestAccount({
|
|
227
|
+
isCurrentActiveAccount: true,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const map = TestMap.create(
|
|
231
|
+
{
|
|
232
|
+
value: "123",
|
|
233
|
+
},
|
|
234
|
+
Group.create(owner).makePublic("reader"),
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
map.$jazz.raw.core.deleteCoValue();
|
|
238
|
+
|
|
239
|
+
const TestComponent = () => {
|
|
240
|
+
const value = useSuspenseCoState(TestMap, map.$jazz.id);
|
|
241
|
+
return <div>{value.value}</div>;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const { container } = await act(async () => {
|
|
245
|
+
return render(
|
|
246
|
+
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
|
247
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
248
|
+
<TestComponent />
|
|
249
|
+
</Suspense>
|
|
250
|
+
</ErrorBoundary>,
|
|
251
|
+
{
|
|
252
|
+
account: owner,
|
|
253
|
+
},
|
|
254
|
+
);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
await waitFor(
|
|
258
|
+
() => {
|
|
259
|
+
expect(container.textContent).toContain("Error: deleted");
|
|
260
|
+
},
|
|
261
|
+
{ timeout: 10_000 },
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
|
|
221
265
|
it("should throw error when CoValue is unavailable due disabled network", async () => {
|
|
222
266
|
disableJazzTestSync();
|
|
223
267
|
|
|
@@ -33,7 +33,6 @@ export type JazzContextManagerProps<
|
|
|
33
33
|
onAnonymousAccountDiscarded?: (
|
|
34
34
|
anonymousAccount: InstanceOfSchema<S>,
|
|
35
35
|
) => Promise<void>;
|
|
36
|
-
CryptoProvider?: BaseReactNativeContextOptions["CryptoProvider"];
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
export class ReactNativeContextManager<
|
|
@@ -50,7 +49,6 @@ export class ReactNativeContextManager<
|
|
|
50
49
|
sync: props.sync,
|
|
51
50
|
storage: props.storage,
|
|
52
51
|
authSecretStorage: this.authSecretStorage,
|
|
53
|
-
CryptoProvider: props.CryptoProvider,
|
|
54
52
|
});
|
|
55
53
|
} else {
|
|
56
54
|
return createJazzReactNativeContext<S>({
|
|
@@ -61,7 +59,6 @@ export class ReactNativeContextManager<
|
|
|
61
59
|
newAccountProps: authProps?.newAccountProps,
|
|
62
60
|
defaultProfileName: props.defaultProfileName,
|
|
63
61
|
authSecretStorage: this.authSecretStorage,
|
|
64
|
-
CryptoProvider: props.CryptoProvider,
|
|
65
62
|
});
|
|
66
63
|
}
|
|
67
64
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useAuthSecretStorage,
|
|
3
3
|
useIsAuthenticated,
|
|
4
|
-
|
|
4
|
+
useJazzContextValue,
|
|
5
5
|
} from "jazz-tools/react-core";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import { ReactNativePasskeyAuth } from "./PasskeyAuth.js";
|
|
@@ -52,7 +52,7 @@ export function usePasskeyAuth({
|
|
|
52
52
|
appName: string;
|
|
53
53
|
rpId: string;
|
|
54
54
|
}) {
|
|
55
|
-
const context =
|
|
55
|
+
const context = useJazzContextValue();
|
|
56
56
|
const authSecretStorage = useAuthSecretStorage();
|
|
57
57
|
|
|
58
58
|
if ("guest" in context) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
import { CoValueClassOrSchema, parseInviteLink } from "jazz-tools";
|
|
4
|
-
import {
|
|
4
|
+
import { useJazzContextValue } from "jazz-tools/react-core";
|
|
5
5
|
import { Linking } from "react-native";
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -10,7 +10,7 @@ export {
|
|
|
10
10
|
experimental_useInboxSender,
|
|
11
11
|
useDemoAuth,
|
|
12
12
|
usePassphraseAuth,
|
|
13
|
-
|
|
13
|
+
useJazzContextValue,
|
|
14
14
|
useAuthSecretStorage,
|
|
15
15
|
useIsAuthenticated,
|
|
16
16
|
useAccount,
|
|
@@ -34,7 +34,7 @@ export function useAcceptInviteNative<S extends CoValueClassOrSchema>({
|
|
|
34
34
|
onAccept: (projectID: string) => void;
|
|
35
35
|
forValueHint?: string;
|
|
36
36
|
}): void {
|
|
37
|
-
const context =
|
|
37
|
+
const context = useJazzContextValue();
|
|
38
38
|
|
|
39
39
|
if (!("me" in context)) {
|
|
40
40
|
throw new Error(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import NetInfo from "@react-native-community/netinfo";
|
|
2
2
|
import { LocalNode, Peer, getSqliteStorageAsync } from "cojson";
|
|
3
|
-
import { PureJSCrypto } from "cojson/dist/crypto/PureJSCrypto"; // Importing from dist to not rely on the exports field
|
|
4
3
|
import {
|
|
5
4
|
Account,
|
|
6
5
|
AccountClass,
|
|
@@ -20,14 +19,12 @@ import { ReactNativeSessionProvider } from "./ReactNativeSessionProvider.js";
|
|
|
20
19
|
|
|
21
20
|
import { SQLiteDatabaseDriverAsync } from "cojson";
|
|
22
21
|
import { WebSocketPeerWithReconnection } from "cojson-transport-ws";
|
|
23
|
-
import
|
|
24
|
-
import type { RNCrypto } from "cojson/crypto/RNCrypto";
|
|
22
|
+
import { RNCrypto } from "cojson/crypto/RNCrypto";
|
|
25
23
|
|
|
26
24
|
export type BaseReactNativeContextOptions = {
|
|
27
25
|
sync: SyncConfig;
|
|
28
26
|
reconnectionTimeout?: number;
|
|
29
27
|
storage?: SQLiteDatabaseDriverAsync | "disabled";
|
|
30
|
-
CryptoProvider?: typeof PureJSCrypto | typeof RNQuickCrypto | typeof RNCrypto;
|
|
31
28
|
authSecretStorage: AuthSecretStorage;
|
|
32
29
|
};
|
|
33
30
|
|
|
@@ -40,8 +37,7 @@ class ReactNativeWebSocketPeerWithReconnection extends WebSocketPeerWithReconnec
|
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
async function setupPeers(options: BaseReactNativeContextOptions) {
|
|
43
|
-
const
|
|
44
|
-
const crypto = await CryptoProvider.create();
|
|
40
|
+
const crypto = await RNCrypto.create();
|
|
45
41
|
let node: LocalNode | undefined = undefined;
|
|
46
42
|
|
|
47
43
|
const peers: Peer[] = [];
|
|
@@ -3,12 +3,17 @@ import {
|
|
|
3
3
|
AccountClass,
|
|
4
4
|
AnyAccountSchema,
|
|
5
5
|
CoValueFromRaw,
|
|
6
|
-
InstanceOfSchema,
|
|
7
|
-
JazzContextType,
|
|
8
6
|
KvStore,
|
|
9
7
|
} from "jazz-tools";
|
|
10
|
-
import { JazzContext
|
|
11
|
-
import React, {
|
|
8
|
+
import { JazzContext } from "jazz-tools/react-core";
|
|
9
|
+
import React, {
|
|
10
|
+
useCallback,
|
|
11
|
+
useContext,
|
|
12
|
+
useEffect,
|
|
13
|
+
useMemo,
|
|
14
|
+
useRef,
|
|
15
|
+
useSyncExternalStore,
|
|
16
|
+
} from "react";
|
|
12
17
|
import type { JazzContextManagerProps } from "./ReactNativeContextManager.js";
|
|
13
18
|
import { ReactNativeContextManager } from "./ReactNativeContextManager.js";
|
|
14
19
|
import { setupKvStore } from "./platform.js";
|
|
@@ -20,6 +25,7 @@ export type JazzProviderProps<
|
|
|
20
25
|
> = {
|
|
21
26
|
children: React.ReactNode;
|
|
22
27
|
kvStore?: KvStore;
|
|
28
|
+
fallback?: React.ReactNode | null;
|
|
23
29
|
authSecretStorageKey?: string;
|
|
24
30
|
} & JazzContextManagerProps<S>;
|
|
25
31
|
|
|
@@ -39,9 +45,15 @@ export function JazzProviderCore<
|
|
|
39
45
|
logOutReplacement,
|
|
40
46
|
onAnonymousAccountDiscarded,
|
|
41
47
|
kvStore,
|
|
42
|
-
CryptoProvider,
|
|
43
48
|
authSecretStorageKey,
|
|
49
|
+
fallback = null,
|
|
44
50
|
}: JazzProviderProps<S>) {
|
|
51
|
+
if (useContext(JazzContext)) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
"You can't nest a JazzProvider inside another JazzProvider.",
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
setupKvStore(kvStore);
|
|
46
58
|
|
|
47
59
|
const [contextManager] = React.useState(
|
|
@@ -53,46 +65,40 @@ export function JazzProviderCore<
|
|
|
53
65
|
const onAnonymousAccountDiscardedRefCallback = useRefCallback(
|
|
54
66
|
onAnonymousAccountDiscarded,
|
|
55
67
|
);
|
|
56
|
-
const logoutReplacementActiveRef = useRef(false);
|
|
57
|
-
logoutReplacementActiveRef.current = Boolean(logOutReplacement);
|
|
58
|
-
const onAnonymousAccountDiscardedEnabled = Boolean(
|
|
59
|
-
onAnonymousAccountDiscarded,
|
|
60
|
-
);
|
|
61
68
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
? onAnonymousAccountDiscardedRefCallback
|
|
79
|
-
: undefined,
|
|
80
|
-
CryptoProvider,
|
|
81
|
-
} satisfies JazzContextManagerProps<S>;
|
|
69
|
+
const props = useMemo(() => {
|
|
70
|
+
return {
|
|
71
|
+
AccountSchema,
|
|
72
|
+
guestMode,
|
|
73
|
+
sync,
|
|
74
|
+
storage,
|
|
75
|
+
defaultProfileName,
|
|
76
|
+
onLogOut: onLogOutRefCallback,
|
|
77
|
+
logOutReplacement: logOutReplacement
|
|
78
|
+
? logOutReplacementRefCallback
|
|
79
|
+
: undefined,
|
|
80
|
+
onAnonymousAccountDiscarded: onAnonymousAccountDiscarded
|
|
81
|
+
? onAnonymousAccountDiscardedRefCallback
|
|
82
|
+
: undefined,
|
|
83
|
+
} satisfies JazzContextManagerProps<S>;
|
|
84
|
+
}, [guestMode, sync.peer, sync.when, storage]);
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if (contextManager.propsChanged(props)) {
|
|
87
|
+
contextManager.createContext(props).catch((error) => {
|
|
88
|
+
console.log(error.stack);
|
|
89
|
+
console.error("Error creating Jazz React Native context:", error);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
89
92
|
|
|
93
|
+
const isReady = useSyncExternalStore(
|
|
94
|
+
useCallback(
|
|
95
|
+
(callback) => {
|
|
90
96
|
return contextManager.subscribe(callback);
|
|
91
97
|
},
|
|
92
|
-
[
|
|
98
|
+
[contextManager],
|
|
93
99
|
),
|
|
94
|
-
() => contextManager.getCurrentValue(),
|
|
95
|
-
() => contextManager.getCurrentValue(),
|
|
100
|
+
() => Boolean(contextManager.getCurrentValue()),
|
|
101
|
+
() => Boolean(contextManager.getCurrentValue()),
|
|
96
102
|
);
|
|
97
103
|
|
|
98
104
|
useEffect(() => {
|
|
@@ -106,10 +112,8 @@ export function JazzProviderCore<
|
|
|
106
112
|
}, []);
|
|
107
113
|
|
|
108
114
|
return (
|
|
109
|
-
<JazzContext.Provider value={
|
|
110
|
-
|
|
111
|
-
{value && children}
|
|
112
|
-
</JazzContextManagerContext.Provider>
|
|
115
|
+
<JazzContext.Provider value={contextManager}>
|
|
116
|
+
{isReady ? children : fallback}
|
|
113
117
|
</JazzContext.Provider>
|
|
114
118
|
);
|
|
115
119
|
}
|
|
@@ -99,10 +99,7 @@ export class CoState<
|
|
|
99
99
|
// @ts-expect-error The resolve query type isn't compatible with the coValueClassFromCoValueClassOrSchema conversion
|
|
100
100
|
resolve,
|
|
101
101
|
loadAs: agent,
|
|
102
|
-
|
|
103
|
-
this.update(value);
|
|
104
|
-
},
|
|
105
|
-
onUnauthorized: (value) => {
|
|
102
|
+
onError: (value) => {
|
|
106
103
|
this.update(value);
|
|
107
104
|
},
|
|
108
105
|
syncResolution: true,
|
|
@@ -181,10 +178,7 @@ export class AccountCoState<
|
|
|
181
178
|
{
|
|
182
179
|
resolve,
|
|
183
180
|
loadAs: me,
|
|
184
|
-
|
|
185
|
-
this.update(value);
|
|
186
|
-
},
|
|
187
|
-
onUnauthorized: (value) => {
|
|
181
|
+
onError: (value) => {
|
|
188
182
|
this.update(value);
|
|
189
183
|
},
|
|
190
184
|
syncResolution: true,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
import { CoValueLoadingState, co, z } from "jazz-tools";
|
|
4
|
+
import { assertLoaded } from "jazz-tools/testing";
|
|
5
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
6
|
+
import { createJazzTestAccount, setupJazzTestSync } from "../testing";
|
|
7
|
+
import { render, screen, waitFor } from "./testUtils";
|
|
8
|
+
import TestAccountCoStateWrapper from "./TestAccountCoStateWrapper.svelte";
|
|
9
|
+
|
|
10
|
+
describe("AccountCoState", () => {
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
await setupJazzTestSync();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should return a 'deleted' value when a required resolved child is deleted", async () => {
|
|
16
|
+
const AccountRoot = co.map({
|
|
17
|
+
value: z.string(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const AccountSchema = co
|
|
21
|
+
.account({
|
|
22
|
+
profile: co.profile(),
|
|
23
|
+
root: AccountRoot,
|
|
24
|
+
})
|
|
25
|
+
.withMigration((account) => {
|
|
26
|
+
if (!account.$jazz.refs.root) {
|
|
27
|
+
account.$jazz.set("root", { value: "123" });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const account = await createJazzTestAccount({
|
|
32
|
+
AccountSchema,
|
|
33
|
+
isCurrentActiveAccount: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
render(
|
|
37
|
+
TestAccountCoStateWrapper,
|
|
38
|
+
{
|
|
39
|
+
Schema: AccountSchema,
|
|
40
|
+
options: {
|
|
41
|
+
resolve: {
|
|
42
|
+
root: true,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
account,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Ensure the account (and root) is loaded first.
|
|
52
|
+
const loaded = await account.$jazz.ensureLoaded({
|
|
53
|
+
resolve: {
|
|
54
|
+
root: true,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
assertLoaded(loaded.root);
|
|
58
|
+
|
|
59
|
+
await waitFor(() => {
|
|
60
|
+
expect(screen.getByTestId("loading-state").textContent).toBe(
|
|
61
|
+
CoValueLoadingState.LOADED,
|
|
62
|
+
);
|
|
63
|
+
expect(screen.getByTestId("is-loaded").textContent).toBe("true");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Delete the required child (root) -> AccountCoState should bubble the error.
|
|
67
|
+
loaded.root.$jazz.raw.core.deleteCoValue();
|
|
68
|
+
await loaded.root.$jazz.raw.core.waitForSync();
|
|
69
|
+
|
|
70
|
+
await waitFor(() => {
|
|
71
|
+
expect(screen.getByTestId("loading-state").textContent).toBe(
|
|
72
|
+
CoValueLoadingState.DELETED,
|
|
73
|
+
);
|
|
74
|
+
expect(screen.getByTestId("is-loaded").textContent).toBe("false");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
|
|
@@ -54,4 +54,40 @@ describe("CoState", () => {
|
|
|
54
54
|
);
|
|
55
55
|
expect(stateValue.name).toBe("John Doe");
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
it("should return a 'deleted' value when the coValue is deleted", async () => {
|
|
59
|
+
const Person = co.map({
|
|
60
|
+
name: co.plainText(),
|
|
61
|
+
});
|
|
62
|
+
const PersonWithName = Person.resolved({ name: true });
|
|
63
|
+
const person = Person.create({ name: "John Doe" }, publicGroup);
|
|
64
|
+
|
|
65
|
+
render(
|
|
66
|
+
TestCoStateWrapper,
|
|
67
|
+
{
|
|
68
|
+
Schema: PersonWithName,
|
|
69
|
+
id: person.$jazz.id,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
account: clientAccount,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
await waitFor(() => {
|
|
77
|
+
expect(screen.getByTestId("loading-state").textContent).toBe(
|
|
78
|
+
CoValueLoadingState.LOADED,
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Delete on the server (owner/admin) and ensure it propagates.
|
|
83
|
+
person.$jazz.raw.core.deleteCoValue();
|
|
84
|
+
await person.$jazz.raw.core.waitForSync();
|
|
85
|
+
|
|
86
|
+
await waitFor(() => {
|
|
87
|
+
expect(screen.getByTestId("loading-state").textContent).toBe(
|
|
88
|
+
CoValueLoadingState.DELETED,
|
|
89
|
+
);
|
|
90
|
+
expect(screen.getByTestId("is-loaded").textContent).toBe("false");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
57
93
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AnyAccountSchema, ResolveQuery } from "jazz-tools";
|
|
3
|
+
import { AccountCoState } from "../jazz.class.svelte";
|
|
4
|
+
|
|
5
|
+
type Props<A extends AnyAccountSchema, R extends ResolveQuery<A>> = {
|
|
6
|
+
Schema: A;
|
|
7
|
+
options?: { resolve?: R };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { Schema, options }: Props<any, any> = $props();
|
|
11
|
+
|
|
12
|
+
const state = new AccountCoState(Schema, options);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div data-testid="account-costate-wrapper">
|
|
16
|
+
<div data-testid="loading-state">{state.current.$jazz.loadingState}</div>
|
|
17
|
+
<div data-testid="is-loaded">{state.current.$isLoaded ? "true" : "false"}</div>
|
|
18
|
+
{#if state.current.$isLoaded}
|
|
19
|
+
<div data-testid="account-id">{state.current.$jazz.id}</div>
|
|
20
|
+
<div data-testid="state-json">{JSON.stringify(state.current.toJSON())}</div>
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
|
|
@@ -46,6 +46,7 @@ export type NotLoaded<T> = {
|
|
|
46
46
|
id: ID<T>;
|
|
47
47
|
loadingState:
|
|
48
48
|
| typeof CoValueLoadingState.LOADING
|
|
49
|
+
| typeof CoValueLoadingState.DELETED
|
|
49
50
|
| typeof CoValueLoadingState.UNAVAILABLE
|
|
50
51
|
| typeof CoValueLoadingState.UNAUTHORIZED;
|
|
51
52
|
};
|
|
@@ -70,6 +71,7 @@ export type Inaccessible<T> = {
|
|
|
70
71
|
$jazz: {
|
|
71
72
|
id: ID<T>;
|
|
72
73
|
loadingState:
|
|
74
|
+
| typeof CoValueLoadingState.DELETED
|
|
73
75
|
| typeof CoValueLoadingState.UNAVAILABLE
|
|
74
76
|
| typeof CoValueLoadingState.UNAUTHORIZED;
|
|
75
77
|
};
|