jazz-vue 0.9.23 → 0.10.1
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +30 -0
- package/dist/auth/useDemoAuth.d.ts +5 -55
- package/dist/auth/useIsAuthenticated.d.ts +1 -0
- package/dist/auth/usePasskeyAuth.d.ts +18 -0
- package/dist/auth/usePassphraseAuth.d.ts +18 -0
- package/dist/composables.d.ts +8 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +367 -243
- package/dist/index.js.map +1 -0
- package/dist/provider-CkA-a4Og.js +86 -0
- package/dist/provider-CkA-a4Og.js.map +1 -0
- package/dist/provider.d.ts +39 -13
- package/dist/testing.d.ts +13 -3
- package/dist/testing.js +29 -17
- package/dist/testing.js.map +1 -0
- package/dist/tests/fixtures.d.ts +1 -0
- package/dist/tests/testUtils.d.ts +3 -2
- package/dist/tests/usePassphraseAuth.test.d.ts +1 -0
- package/package.json +7 -6
- package/src/auth/DemoAuthBasicUI.vue +115 -113
- package/src/auth/useDemoAuth.ts +31 -71
- package/src/auth/useIsAuthenticated.ts +18 -0
- package/src/auth/usePasskeyAuth.ts +46 -0
- package/src/auth/usePassphraseAuth.ts +56 -0
- package/src/composables.ts +36 -22
- package/src/index.ts +2 -0
- package/src/provider.ts +55 -56
- package/src/testing.ts +16 -5
- package/src/tests/fixtures.ts +2050 -0
- package/src/tests/testUtils.ts +8 -1
- package/src/tests/useCoState.test.ts +33 -4
- package/src/tests/usePassphraseAuth.test.ts +95 -0
- package/vite.config.ts +2 -0
- package/dist/provider-BZnz6FpX.js +0 -69
package/src/auth/useDemoAuth.ts
CHANGED
@@ -1,77 +1,37 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import { logoutHandler } from "../provider.js";
|
1
|
+
import { DemoAuth } from "jazz-tools";
|
2
|
+
import { computed, ref, watch } from "vue";
|
3
|
+
import { useAuthSecretStorage, useJazzContext } from "../composables.js";
|
4
|
+
import { useIsAuthenticated } from "./useIsAuthenticated.js";
|
6
5
|
|
7
|
-
export
|
8
|
-
|
9
|
-
|
10
|
-
}
|
11
|
-
| {
|
12
|
-
state: "loading";
|
13
|
-
}
|
14
|
-
| {
|
15
|
-
state: "ready";
|
16
|
-
existingUsers: string[];
|
17
|
-
signUp: (username: string) => void;
|
18
|
-
logInAs: (existingUser: string) => void;
|
19
|
-
}
|
20
|
-
| {
|
21
|
-
state: "signedIn";
|
22
|
-
logOut: () => void;
|
23
|
-
}
|
24
|
-
) & {
|
25
|
-
errors: string[];
|
26
|
-
};
|
6
|
+
export function useDemoAuth() {
|
7
|
+
const context = useJazzContext();
|
8
|
+
const authSecretStorage = useAuthSecretStorage();
|
27
9
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}: {
|
32
|
-
seedAccounts?: {
|
33
|
-
[name: string]: { accountID: ID<Account>; accountSecret: AgentSecret };
|
34
|
-
};
|
35
|
-
} = {}) {
|
36
|
-
const state = reactive<DemoAuthState>({
|
37
|
-
state: "loading",
|
38
|
-
errors: [],
|
39
|
-
});
|
10
|
+
if ("guest" in context.value) {
|
11
|
+
throw new Error("Demo auth is not supported in guest mode");
|
12
|
+
}
|
40
13
|
|
41
|
-
const authMethod =
|
42
|
-
new
|
43
|
-
{
|
44
|
-
onReady: ({ signUp, existingUsers, logInAs }) => {
|
45
|
-
state.state = "ready";
|
46
|
-
(state as DemoAuthState & { state: "ready" }).signUp = signUp;
|
47
|
-
(state as DemoAuthState & { state: "ready" }).existingUsers =
|
48
|
-
existingUsers;
|
49
|
-
(state as DemoAuthState & { state: "ready" }).logInAs = logInAs;
|
50
|
-
state.errors = [];
|
51
|
-
},
|
52
|
-
onSignedIn: ({ logOut }) => {
|
53
|
-
state.state = "signedIn";
|
54
|
-
(state as DemoAuthState & { state: "signedIn" }).logOut = () => {
|
55
|
-
logOut();
|
56
|
-
state.state = "ready";
|
57
|
-
state.errors = [];
|
58
|
-
};
|
59
|
-
state.errors = [];
|
60
|
-
logoutHandler.value = (
|
61
|
-
state as DemoAuthState & { state: "signedIn" }
|
62
|
-
).logOut;
|
63
|
-
},
|
64
|
-
onError: (error) => {
|
65
|
-
state.errors.push(error.toString());
|
66
|
-
},
|
67
|
-
},
|
68
|
-
seedAccounts,
|
69
|
-
),
|
14
|
+
const authMethod = computed(
|
15
|
+
() => new DemoAuth(context.value.authenticate, authSecretStorage),
|
70
16
|
);
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
17
|
+
|
18
|
+
const existingUsers = ref<string[]>([]);
|
19
|
+
const isAuthenticated = useIsAuthenticated();
|
20
|
+
|
21
|
+
watch(authMethod, () => {
|
22
|
+
authMethod.value.getExistingUsers().then((users) => {
|
23
|
+
existingUsers.value = users;
|
24
|
+
});
|
75
25
|
});
|
76
|
-
|
26
|
+
|
27
|
+
return computed(() => ({
|
28
|
+
state: isAuthenticated.value ? "signedIn" : "anonymous",
|
29
|
+
logIn(username: string) {
|
30
|
+
authMethod.value.logIn(username);
|
31
|
+
},
|
32
|
+
signUp(username: string) {
|
33
|
+
authMethod.value.signUp(username);
|
34
|
+
},
|
35
|
+
existingUsers: existingUsers.value,
|
36
|
+
}));
|
77
37
|
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { onMounted, onUnmounted, ref } from "vue";
|
2
|
+
import { useAuthSecretStorage } from "../composables.js";
|
3
|
+
|
4
|
+
export function useIsAuthenticated() {
|
5
|
+
const authSecretStorage = useAuthSecretStorage();
|
6
|
+
const isAuthenticated = ref(authSecretStorage.isAuthenticated);
|
7
|
+
|
8
|
+
const handleUpdate = () => {
|
9
|
+
isAuthenticated.value = authSecretStorage.isAuthenticated;
|
10
|
+
};
|
11
|
+
|
12
|
+
onMounted(() => {
|
13
|
+
const cleanup = authSecretStorage.onUpdate(handleUpdate);
|
14
|
+
onUnmounted(cleanup);
|
15
|
+
});
|
16
|
+
|
17
|
+
return isAuthenticated;
|
18
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { BrowserPasskeyAuth } from "jazz-browser";
|
2
|
+
import { computed } from "vue";
|
3
|
+
import { useAuthSecretStorage, useJazzContext } from "../composables.js";
|
4
|
+
import { useIsAuthenticated } from "./useIsAuthenticated.js";
|
5
|
+
|
6
|
+
/**
|
7
|
+
* `usePasskeyAuth` composable provides a `JazzAuth` object for passkey authentication.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* ```ts
|
11
|
+
* const auth = usePasskeyAuth({ appName, appHostname });
|
12
|
+
* ```
|
13
|
+
*
|
14
|
+
* @category Auth Providers
|
15
|
+
*/
|
16
|
+
export function usePasskeyAuth({
|
17
|
+
appName,
|
18
|
+
appHostname,
|
19
|
+
}: {
|
20
|
+
appName: string;
|
21
|
+
appHostname?: string;
|
22
|
+
}) {
|
23
|
+
const context = useJazzContext();
|
24
|
+
const authSecretStorage = useAuthSecretStorage();
|
25
|
+
const isAuthenticated = useIsAuthenticated();
|
26
|
+
|
27
|
+
if ("guest" in context.value) {
|
28
|
+
throw new Error("Passkey auth is not supported in guest mode");
|
29
|
+
}
|
30
|
+
|
31
|
+
const authMethod = computed(() => {
|
32
|
+
return new BrowserPasskeyAuth(
|
33
|
+
context.value.node.crypto,
|
34
|
+
context.value.authenticate,
|
35
|
+
authSecretStorage,
|
36
|
+
appName,
|
37
|
+
appHostname,
|
38
|
+
);
|
39
|
+
});
|
40
|
+
|
41
|
+
return computed(() => ({
|
42
|
+
state: isAuthenticated.value ? "signedIn" : "anonymous",
|
43
|
+
logIn: authMethod.value.logIn,
|
44
|
+
signUp: authMethod.value.signUp,
|
45
|
+
}));
|
46
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { PassphraseAuth } from "jazz-tools";
|
2
|
+
import { computed, ref, watchEffect } from "vue";
|
3
|
+
import { useAuthSecretStorage, useJazzContext } from "../composables.js";
|
4
|
+
import { useIsAuthenticated } from "./useIsAuthenticated.js";
|
5
|
+
|
6
|
+
/**
|
7
|
+
* `usePassphraseAuth` composable provides a `JazzAuth` object for passphrase authentication.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* ```ts
|
11
|
+
* const auth = usePassphraseAuth({ wordlist });
|
12
|
+
* ```
|
13
|
+
*
|
14
|
+
* @category Auth Providers
|
15
|
+
*/
|
16
|
+
export function usePassphraseAuth({
|
17
|
+
wordlist,
|
18
|
+
}: {
|
19
|
+
wordlist: string[];
|
20
|
+
}) {
|
21
|
+
const context = useJazzContext();
|
22
|
+
const authSecretStorage = useAuthSecretStorage();
|
23
|
+
const isAuthenticated = useIsAuthenticated();
|
24
|
+
|
25
|
+
if ("guest" in context.value) {
|
26
|
+
throw new Error("Passphrase auth is not supported in guest mode");
|
27
|
+
}
|
28
|
+
|
29
|
+
const authMethod = computed(() => {
|
30
|
+
return new PassphraseAuth(
|
31
|
+
context.value.node.crypto,
|
32
|
+
context.value.authenticate,
|
33
|
+
authSecretStorage,
|
34
|
+
wordlist,
|
35
|
+
);
|
36
|
+
});
|
37
|
+
|
38
|
+
const passphrase = ref(authMethod.value.passphrase);
|
39
|
+
|
40
|
+
watchEffect((onCleanup) => {
|
41
|
+
authMethod.value.loadCurrentAccountPassphrase();
|
42
|
+
|
43
|
+
const unsubscribe = authMethod.value.subscribe(() => {
|
44
|
+
passphrase.value = authMethod.value.passphrase;
|
45
|
+
});
|
46
|
+
|
47
|
+
onCleanup(unsubscribe);
|
48
|
+
});
|
49
|
+
|
50
|
+
return computed(() => ({
|
51
|
+
state: isAuthenticated.value ? "signedIn" : "anonymous",
|
52
|
+
logIn: authMethod.value.logIn,
|
53
|
+
signUp: authMethod.value.signUp,
|
54
|
+
passphrase: passphrase.value,
|
55
|
+
}));
|
56
|
+
}
|
package/src/composables.ts
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
import {
|
2
|
-
BrowserContext,
|
3
|
-
BrowserGuestContext,
|
4
|
-
consumeInviteLinkFromWindowLocation,
|
5
|
-
} from "jazz-browser";
|
1
|
+
import { consumeInviteLinkFromWindowLocation } from "jazz-browser";
|
6
2
|
import {
|
7
3
|
Account,
|
8
4
|
AnonymousJazzAgent,
|
5
|
+
AuthSecretStorage,
|
9
6
|
CoValue,
|
10
7
|
CoValueClass,
|
11
8
|
DeeplyLoaded,
|
12
9
|
DepthsIn,
|
13
10
|
ID,
|
11
|
+
JazzAuthContext,
|
12
|
+
JazzContextType,
|
13
|
+
JazzGuestContext,
|
14
14
|
subscribeToCoValue,
|
15
15
|
} from "jazz-tools";
|
16
16
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
@@ -29,21 +29,31 @@ import {
|
|
29
29
|
unref,
|
30
30
|
watch,
|
31
31
|
} from "vue";
|
32
|
-
import {
|
32
|
+
import {
|
33
|
+
JazzAuthContextSymbol,
|
34
|
+
JazzContextSymbol,
|
35
|
+
RegisteredAccount,
|
36
|
+
} from "./provider.js";
|
33
37
|
|
34
38
|
export const logoutHandler = ref<() => void>();
|
35
39
|
|
36
|
-
function useJazzContext() {
|
40
|
+
export function useJazzContext() {
|
37
41
|
const context =
|
38
|
-
inject<Ref<
|
39
|
-
|
40
|
-
);
|
41
|
-
if (!context) {
|
42
|
+
inject<Ref<JazzContextType<RegisteredAccount>>>(JazzContextSymbol);
|
43
|
+
if (!context?.value) {
|
42
44
|
throw new Error("useJazzContext must be used within a JazzProvider");
|
43
45
|
}
|
44
46
|
return context;
|
45
47
|
}
|
46
48
|
|
49
|
+
export function useAuthSecretStorage() {
|
50
|
+
const context = inject<AuthSecretStorage>(JazzAuthContextSymbol);
|
51
|
+
if (!context) {
|
52
|
+
throw new Error("useAuthSecretStorage must be used within a JazzProvider");
|
53
|
+
}
|
54
|
+
return context;
|
55
|
+
}
|
56
|
+
|
47
57
|
export function createUseAccountComposables<Acc extends Account>() {
|
48
58
|
function useAccount(): {
|
49
59
|
me: ComputedRef<Acc>;
|
@@ -52,13 +62,13 @@ export function createUseAccountComposables<Acc extends Account>() {
|
|
52
62
|
function useAccount<D extends DepthsIn<Acc>>(
|
53
63
|
depth: D,
|
54
64
|
): {
|
55
|
-
me: ComputedRef<DeeplyLoaded<Acc, D> | undefined>;
|
65
|
+
me: ComputedRef<DeeplyLoaded<Acc, D> | undefined | null>;
|
56
66
|
logOut: () => void;
|
57
67
|
};
|
58
68
|
function useAccount<D extends DepthsIn<Acc>>(
|
59
69
|
depth?: D,
|
60
70
|
): {
|
61
|
-
me: ComputedRef<Acc | DeeplyLoaded<Acc, D> | undefined>;
|
71
|
+
me: ComputedRef<Acc | DeeplyLoaded<Acc, D> | undefined | null>;
|
62
72
|
logOut: () => void;
|
63
73
|
} {
|
64
74
|
const context = useJazzContext();
|
@@ -85,7 +95,7 @@ export function createUseAccountComposables<Acc extends Account>() {
|
|
85
95
|
me: computed(() => {
|
86
96
|
const value =
|
87
97
|
depth === undefined
|
88
|
-
? me.value || toRaw((context.value as
|
98
|
+
? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)
|
89
99
|
: me.value;
|
90
100
|
|
91
101
|
return value ? toRaw(value) : value;
|
@@ -100,13 +110,15 @@ export function createUseAccountComposables<Acc extends Account>() {
|
|
100
110
|
function useAccountOrGuest<D extends DepthsIn<Acc>>(
|
101
111
|
depth: D,
|
102
112
|
): {
|
103
|
-
me: ComputedRef<
|
113
|
+
me: ComputedRef<
|
114
|
+
DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent
|
115
|
+
>;
|
104
116
|
};
|
105
117
|
function useAccountOrGuest<D extends DepthsIn<Acc>>(
|
106
118
|
depth?: D,
|
107
119
|
): {
|
108
120
|
me: ComputedRef<
|
109
|
-
Acc | DeeplyLoaded<Acc, D> | undefined | AnonymousJazzAgent
|
121
|
+
Acc | DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent
|
110
122
|
>;
|
111
123
|
} {
|
112
124
|
const context = useJazzContext();
|
@@ -129,13 +141,13 @@ export function createUseAccountComposables<Acc extends Account>() {
|
|
129
141
|
return {
|
130
142
|
me: computed(() =>
|
131
143
|
depth === undefined
|
132
|
-
? me.value || toRaw((context.value as
|
144
|
+
? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)
|
133
145
|
: me.value,
|
134
146
|
),
|
135
147
|
};
|
136
148
|
} else {
|
137
149
|
return {
|
138
|
-
me: computed(() => toRaw((context.value as
|
150
|
+
me: computed(() => toRaw((context.value as JazzGuestContext).guest)),
|
139
151
|
};
|
140
152
|
}
|
141
153
|
}
|
@@ -155,8 +167,8 @@ export function useCoState<V extends CoValue, D>(
|
|
155
167
|
Schema: CoValueClass<V>,
|
156
168
|
id: MaybeRef<ID<V> | undefined>,
|
157
169
|
depth: D & DepthsIn<V> = [] as D & DepthsIn<V>,
|
158
|
-
): Ref<DeeplyLoaded<V, D> | undefined> {
|
159
|
-
const state: ShallowRef<DeeplyLoaded<V, D> | undefined> =
|
170
|
+
): Ref<DeeplyLoaded<V, D> | undefined | null> {
|
171
|
+
const state: ShallowRef<DeeplyLoaded<V, D> | undefined | null> =
|
160
172
|
shallowRef(undefined);
|
161
173
|
const context = useJazzContext();
|
162
174
|
|
@@ -184,7 +196,9 @@ export function useCoState<V extends CoValue, D>(
|
|
184
196
|
(value) => {
|
185
197
|
state.value = value;
|
186
198
|
},
|
187
|
-
|
199
|
+
() => {
|
200
|
+
state.value = null;
|
201
|
+
},
|
188
202
|
true,
|
189
203
|
);
|
190
204
|
},
|
@@ -223,7 +237,7 @@ export function useAcceptInvite<V extends CoValue>({
|
|
223
237
|
|
224
238
|
const runInviteAcceptance = () => {
|
225
239
|
const result = consumeInviteLinkFromWindowLocation({
|
226
|
-
as: toRaw((context.value as
|
240
|
+
as: toRaw((context.value as JazzAuthContext<RegisteredAccount>).me),
|
227
241
|
invitedObjectSchema,
|
228
242
|
forValueHint,
|
229
243
|
});
|
package/src/index.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
export * from "./composables.js";
|
2
2
|
export { JazzProvider } from "./provider.js";
|
3
3
|
export * from "./auth/useDemoAuth.js";
|
4
|
+
export * from "./auth/usePassphraseAuth.js";
|
5
|
+
export * from "./auth/usePasskeyAuth.js";
|
4
6
|
export { default as DemoAuthBasicUI } from "./auth/DemoAuthBasicUI.vue";
|
5
7
|
export { default as ProgressiveImg } from "./ProgressiveImg.vue";
|
6
8
|
|
package/src/provider.ts
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
BrowserGuestContext,
|
4
|
-
createJazzBrowserContext,
|
5
|
-
} from "jazz-browser";
|
6
|
-
import { Account, AccountClass, AuthMethod } from "jazz-tools";
|
1
|
+
import { JazzBrowserContextManager } from "jazz-browser";
|
2
|
+
import { Account, AccountClass, JazzContextType, SyncConfig } from "jazz-tools";
|
7
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
8
4
|
import {
|
9
5
|
PropType,
|
6
|
+
computed,
|
10
7
|
defineComponent,
|
11
8
|
onMounted,
|
12
9
|
onUnmounted,
|
@@ -25,78 +22,80 @@ export type RegisteredAccount = Register extends { Account: infer Acc }
|
|
25
22
|
: Account;
|
26
23
|
|
27
24
|
export const JazzContextSymbol = Symbol("JazzContext");
|
28
|
-
|
25
|
+
export const JazzAuthContextSymbol = Symbol("JazzAuthContext");
|
29
26
|
export const JazzProvider = defineComponent({
|
30
27
|
name: "JazzProvider",
|
31
28
|
props: {
|
32
|
-
|
33
|
-
type:
|
29
|
+
guestMode: {
|
30
|
+
type: Boolean,
|
31
|
+
default: false,
|
32
|
+
},
|
33
|
+
sync: {
|
34
|
+
type: Object as PropType<SyncConfig>,
|
34
35
|
required: true,
|
35
36
|
},
|
36
37
|
AccountSchema: {
|
37
|
-
type:
|
38
|
+
type: Function as unknown as PropType<AccountClass<RegisteredAccount>>,
|
38
39
|
required: false,
|
39
40
|
},
|
40
|
-
peer: {
|
41
|
-
type: String as PropType<`wss://${string}` | `ws://${string}`>,
|
42
|
-
required: true,
|
43
|
-
},
|
44
41
|
storage: {
|
45
42
|
type: String as PropType<"indexedDB" | "singleTabOPFS">,
|
46
43
|
default: undefined,
|
47
44
|
},
|
45
|
+
defaultProfileName: {
|
46
|
+
type: String,
|
47
|
+
required: false,
|
48
|
+
},
|
49
|
+
onAnonymousAccountDiscarded: {
|
50
|
+
type: Function as PropType<
|
51
|
+
(anonymousAccount: RegisteredAccount) => Promise<void>
|
52
|
+
>,
|
53
|
+
required: false,
|
54
|
+
},
|
55
|
+
onLogOut: {
|
56
|
+
type: Function as PropType<() => void>,
|
57
|
+
required: false,
|
58
|
+
},
|
48
59
|
},
|
49
60
|
setup(props, { slots }) {
|
50
|
-
const
|
51
|
-
|
52
|
-
>(undefined);
|
53
|
-
|
54
|
-
const key = ref(0);
|
61
|
+
const contextManager = new JazzBrowserContextManager<RegisteredAccount>();
|
62
|
+
const ctx = ref<JazzContextType<RegisteredAccount>>();
|
55
63
|
|
56
64
|
provide(JazzContextSymbol, ctx);
|
57
|
-
|
58
|
-
const initializeContext = async () => {
|
59
|
-
if (ctx.value) {
|
60
|
-
ctx.value.done?.();
|
61
|
-
ctx.value = undefined;
|
62
|
-
}
|
63
|
-
|
64
|
-
try {
|
65
|
-
const context = await createJazzBrowserContext<RegisteredAccount>(
|
66
|
-
props.auth === "guest"
|
67
|
-
? { peer: props.peer, storage: props.storage }
|
68
|
-
: {
|
69
|
-
AccountSchema: props.AccountSchema,
|
70
|
-
auth: props.auth,
|
71
|
-
peer: props.peer,
|
72
|
-
storage: props.storage,
|
73
|
-
},
|
74
|
-
);
|
75
|
-
|
76
|
-
ctx.value = {
|
77
|
-
...context,
|
78
|
-
logOut: () => {
|
79
|
-
logoutHandler.value?.();
|
80
|
-
// context.logOut();
|
81
|
-
key.value += 1;
|
82
|
-
},
|
83
|
-
};
|
84
|
-
} catch (e) {
|
85
|
-
console.error("Error creating Jazz browser context:", e);
|
86
|
-
}
|
87
|
-
};
|
88
|
-
|
89
|
-
onMounted(() => {
|
90
|
-
void initializeContext();
|
91
|
-
});
|
65
|
+
provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());
|
92
66
|
|
93
67
|
watch(
|
94
|
-
() =>
|
68
|
+
() => ({
|
69
|
+
peer: props.sync.peer,
|
70
|
+
syncWhen: props.sync.when,
|
71
|
+
storage: props.storage,
|
72
|
+
guestMode: props.guestMode,
|
73
|
+
}),
|
95
74
|
async () => {
|
96
|
-
|
75
|
+
contextManager
|
76
|
+
.createContext({
|
77
|
+
sync: props.sync,
|
78
|
+
storage: props.storage,
|
79
|
+
guestMode: props.guestMode,
|
80
|
+
AccountSchema: props.AccountSchema,
|
81
|
+
defaultProfileName: props.defaultProfileName,
|
82
|
+
onAnonymousAccountDiscarded: props.onAnonymousAccountDiscarded,
|
83
|
+
onLogOut: props.onLogOut,
|
84
|
+
})
|
85
|
+
.catch((error) => {
|
86
|
+
console.error("Error creating Jazz browser context:", error);
|
87
|
+
});
|
97
88
|
},
|
89
|
+
{ immediate: true },
|
98
90
|
);
|
99
91
|
|
92
|
+
onMounted(() => {
|
93
|
+
const cleanup = contextManager.subscribe(() => {
|
94
|
+
ctx.value = contextManager.getCurrentValue();
|
95
|
+
});
|
96
|
+
onUnmounted(cleanup);
|
97
|
+
});
|
98
|
+
|
100
99
|
onUnmounted(() => {
|
101
100
|
if (ctx.value) ctx.value.done?.();
|
102
101
|
});
|
package/src/testing.ts
CHANGED
@@ -1,20 +1,31 @@
|
|
1
1
|
import { Account, AnonymousJazzAgent } from "jazz-tools";
|
2
|
-
import {
|
2
|
+
import { TestJazzContextManager } from "jazz-tools/testing";
|
3
3
|
import { provide } from "vue";
|
4
4
|
import { PropType, defineComponent, ref } from "vue";
|
5
|
-
import { JazzContextSymbol } from "./provider.js";
|
5
|
+
import { JazzAuthContextSymbol, JazzContextSymbol } from "./provider.js";
|
6
6
|
|
7
7
|
export const JazzTestProvider = defineComponent({
|
8
8
|
name: "JazzTestProvider",
|
9
9
|
props: {
|
10
10
|
account: {
|
11
11
|
type: Object as PropType<Account | { guest: AnonymousJazzAgent }>,
|
12
|
-
required:
|
12
|
+
required: false,
|
13
|
+
},
|
14
|
+
isAuthenticated: {
|
15
|
+
type: Boolean,
|
16
|
+
required: false,
|
13
17
|
},
|
14
18
|
},
|
15
19
|
setup(props, { slots }) {
|
16
|
-
const
|
17
|
-
|
20
|
+
const contextManager = TestJazzContextManager.fromAccountOrGuest(
|
21
|
+
props.account,
|
22
|
+
{
|
23
|
+
isAuthenticated: props.isAuthenticated,
|
24
|
+
},
|
25
|
+
);
|
26
|
+
|
27
|
+
provide(JazzContextSymbol, ref(contextManager.getCurrentValue()));
|
28
|
+
provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());
|
18
29
|
|
19
30
|
return () => slots.default?.();
|
20
31
|
},
|