jazz-vue 0.9.22 → 0.10.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/composables.ts","../src/auth/useIsAuthenticated.ts","../src/auth/useDemoAuth.ts","../src/auth/usePassphraseAuth.ts","../src/auth/usePasskeyAuth.ts","../src/auth/DemoAuthBasicUI.vue","../src/ProgressiveImg.vue"],"sourcesContent":["import { consumeInviteLinkFromWindowLocation } from \"jazz-browser\";\nimport {\n Account,\n AnonymousJazzAgent,\n AuthSecretStorage,\n CoValue,\n CoValueClass,\n DeeplyLoaded,\n DepthsIn,\n ID,\n JazzAuthContext,\n JazzContextType,\n JazzGuestContext,\n subscribeToCoValue,\n} from \"jazz-tools\";\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ComputedRef,\n MaybeRef,\n Ref,\n ShallowRef,\n computed,\n inject,\n onMounted,\n onUnmounted,\n ref,\n shallowRef,\n toRaw,\n unref,\n watch,\n} from \"vue\";\nimport {\n JazzAuthContextSymbol,\n JazzContextSymbol,\n RegisteredAccount,\n} from \"./provider.js\";\n\nexport const logoutHandler = ref<() => void>();\n\nexport function useJazzContext() {\n const context =\n inject<Ref<JazzContextType<RegisteredAccount>>>(JazzContextSymbol);\n if (!context?.value) {\n throw new Error(\"useJazzContext must be used within a JazzProvider\");\n }\n return context;\n}\n\nexport function useAuthSecretStorage() {\n const context = inject<AuthSecretStorage>(JazzAuthContextSymbol);\n if (!context) {\n throw new Error(\"useAuthSecretStorage must be used within a JazzProvider\");\n }\n return context;\n}\n\nexport function createUseAccountComposables<Acc extends Account>() {\n function useAccount(): {\n me: ComputedRef<Acc>;\n logOut: () => void;\n };\n function useAccount<D extends DepthsIn<Acc>>(\n depth: D,\n ): {\n me: ComputedRef<DeeplyLoaded<Acc, D> | undefined | null>;\n logOut: () => void;\n };\n function useAccount<D extends DepthsIn<Acc>>(\n depth?: D,\n ): {\n me: ComputedRef<Acc | DeeplyLoaded<Acc, D> | undefined | null>;\n logOut: () => void;\n } {\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\"useAccount must be used within a JazzProvider\");\n }\n\n if (!(\"me\" in context.value)) {\n throw new Error(\n \"useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()\",\n );\n }\n\n const contextMe = context.value.me as Acc;\n\n const me = useCoState<Acc, D>(\n contextMe.constructor as CoValueClass<Acc>,\n contextMe.id,\n depth,\n );\n\n return {\n me: computed(() => {\n const value =\n depth === undefined\n ? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)\n : me.value;\n\n return value ? toRaw(value) : value;\n }),\n logOut: context.value.logOut,\n };\n }\n\n function useAccountOrGuest(): {\n me: ComputedRef<Acc | AnonymousJazzAgent>;\n };\n function useAccountOrGuest<D extends DepthsIn<Acc>>(\n depth: D,\n ): {\n me: ComputedRef<\n DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent\n >;\n };\n function useAccountOrGuest<D extends DepthsIn<Acc>>(\n depth?: D,\n ): {\n me: ComputedRef<\n Acc | DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent\n >;\n } {\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\"useAccountOrGuest must be used within a JazzProvider\");\n }\n\n const contextMe = computed(() =>\n \"me\" in context.value ? (context.value.me as Acc) : undefined,\n );\n\n const me = useCoState<Acc, D>(\n contextMe.value?.constructor as CoValueClass<Acc>,\n contextMe.value?.id,\n depth,\n );\n\n if (\"me\" in context.value) {\n return {\n me: computed(() =>\n depth === undefined\n ? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)\n : me.value,\n ),\n };\n } else {\n return {\n me: computed(() => toRaw((context.value as JazzGuestContext).guest)),\n };\n }\n }\n\n return {\n useAccount,\n useAccountOrGuest,\n };\n}\n\nconst { useAccount, useAccountOrGuest } =\n createUseAccountComposables<RegisteredAccount>();\n\nexport { useAccount, useAccountOrGuest };\n\nexport function useCoState<V extends CoValue, D>(\n Schema: CoValueClass<V>,\n id: MaybeRef<ID<V> | undefined>,\n depth: D & DepthsIn<V> = [] as D & DepthsIn<V>,\n): Ref<DeeplyLoaded<V, D> | undefined | null> {\n const state: ShallowRef<DeeplyLoaded<V, D> | undefined | null> =\n shallowRef(undefined);\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\"useCoState must be used within a JazzProvider\");\n }\n\n let unsubscribe: (() => void) | undefined;\n\n watch(\n [() => unref(id), () => context, () => Schema, () => depth],\n () => {\n if (unsubscribe) unsubscribe();\n\n const idValue = unref(id);\n if (!idValue) return;\n\n unsubscribe = subscribeToCoValue(\n Schema,\n idValue,\n \"me\" in context.value\n ? toRaw(context.value.me)\n : toRaw(context.value.guest),\n depth,\n (value) => {\n state.value = value;\n },\n () => {\n state.value = null;\n },\n true,\n );\n },\n { deep: true, immediate: true },\n );\n\n onUnmounted(() => {\n if (unsubscribe) unsubscribe();\n });\n\n const computedState = computed(() => state.value);\n\n return computedState;\n}\n\nexport function useAcceptInvite<V extends CoValue>({\n invitedObjectSchema,\n onAccept,\n forValueHint,\n}: {\n invitedObjectSchema: CoValueClass<V>;\n onAccept: (projectID: ID<V>) => void;\n forValueHint?: string;\n}): void {\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\"useAcceptInvite must be used within a JazzProvider\");\n }\n\n if (!(\"me\" in context.value)) {\n throw new Error(\n \"useAcceptInvite can't be used in a JazzProvider with auth === 'guest'.\",\n );\n }\n\n const runInviteAcceptance = () => {\n const result = consumeInviteLinkFromWindowLocation({\n as: toRaw((context.value as JazzAuthContext<RegisteredAccount>).me),\n invitedObjectSchema,\n forValueHint,\n });\n\n result\n .then((res) => res && onAccept(res.valueID))\n .catch((e) => {\n console.error(\"Failed to accept invite\", e);\n });\n };\n\n onMounted(() => {\n runInviteAcceptance();\n });\n\n watch(\n () => onAccept,\n (newOnAccept, oldOnAccept) => {\n if (newOnAccept !== oldOnAccept) {\n runInviteAcceptance();\n }\n },\n );\n}\n","import { onMounted, onUnmounted, ref } from \"vue\";\nimport { useAuthSecretStorage } from \"../composables.js\";\n\nexport function useIsAuthenticated() {\n const authSecretStorage = useAuthSecretStorage();\n const isAuthenticated = ref(authSecretStorage.isAuthenticated);\n\n const handleUpdate = () => {\n isAuthenticated.value = authSecretStorage.isAuthenticated;\n };\n\n onMounted(() => {\n const cleanup = authSecretStorage.onUpdate(handleUpdate);\n onUnmounted(cleanup);\n });\n\n return isAuthenticated;\n}\n","import { DemoAuth } from \"jazz-tools\";\nimport { computed, ref, watch } from \"vue\";\nimport { useAuthSecretStorage, useJazzContext } from \"../composables.js\";\nimport { useIsAuthenticated } from \"./useIsAuthenticated.js\";\n\nexport function useDemoAuth() {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n\n if (\"guest\" in context.value) {\n throw new Error(\"Demo auth is not supported in guest mode\");\n }\n\n const authMethod = computed(\n () => new DemoAuth(context.value.authenticate, authSecretStorage),\n );\n\n const existingUsers = ref<string[]>([]);\n const isAuthenticated = useIsAuthenticated();\n\n watch(authMethod, () => {\n authMethod.value.getExistingUsers().then((users) => {\n existingUsers.value = users;\n });\n });\n\n return computed(() => ({\n state: isAuthenticated.value ? \"signedIn\" : \"anonymous\",\n logIn(username: string) {\n authMethod.value.logIn(username);\n },\n signUp(username: string) {\n authMethod.value.signUp(username);\n },\n existingUsers: existingUsers.value,\n }));\n}\n","import { PassphraseAuth } from \"jazz-tools\";\nimport { computed, ref, watchEffect } from \"vue\";\nimport { useAuthSecretStorage, useJazzContext } from \"../composables.js\";\nimport { useIsAuthenticated } from \"./useIsAuthenticated.js\";\n\n/**\n * `usePassphraseAuth` composable provides a `JazzAuth` object for passphrase authentication.\n *\n * @example\n * ```ts\n * const auth = usePassphraseAuth({ wordlist });\n * ```\n *\n * @category Auth Providers\n */\nexport function usePassphraseAuth({\n wordlist,\n}: {\n wordlist: string[];\n}) {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n const isAuthenticated = useIsAuthenticated();\n\n if (\"guest\" in context.value) {\n throw new Error(\"Passphrase auth is not supported in guest mode\");\n }\n\n const authMethod = computed(() => {\n return new PassphraseAuth(\n context.value.node.crypto,\n context.value.authenticate,\n authSecretStorage,\n wordlist,\n );\n });\n\n const passphrase = ref(authMethod.value.passphrase);\n\n watchEffect((onCleanup) => {\n authMethod.value.loadCurrentAccountPassphrase();\n\n const unsubscribe = authMethod.value.subscribe(() => {\n passphrase.value = authMethod.value.passphrase;\n });\n\n onCleanup(unsubscribe);\n });\n\n return computed(() => ({\n state: isAuthenticated.value ? \"signedIn\" : \"anonymous\",\n logIn: authMethod.value.logIn,\n signUp: authMethod.value.signUp,\n passphrase: passphrase.value,\n }));\n}\n","import { BrowserPasskeyAuth } from \"jazz-browser\";\nimport { computed } from \"vue\";\nimport { useAuthSecretStorage, useJazzContext } from \"../composables.js\";\nimport { useIsAuthenticated } from \"./useIsAuthenticated.js\";\n\n/**\n * `usePasskeyAuth` composable provides a `JazzAuth` object for passkey authentication.\n *\n * @example\n * ```ts\n * const auth = usePasskeyAuth({ appName, appHostname });\n * ```\n *\n * @category Auth Providers\n */\nexport function usePasskeyAuth({\n appName,\n appHostname,\n}: {\n appName: string;\n appHostname?: string;\n}) {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n const isAuthenticated = useIsAuthenticated();\n\n if (\"guest\" in context.value) {\n throw new Error(\"Passkey auth is not supported in guest mode\");\n }\n\n const authMethod = computed(() => {\n return new BrowserPasskeyAuth(\n context.value.node.crypto,\n context.value.authenticate,\n authSecretStorage,\n appName,\n appHostname,\n );\n });\n\n return computed(() => ({\n state: isAuthenticated.value ? \"signedIn\" : \"anonymous\",\n logIn: authMethod.value.logIn,\n signUp: authMethod.value.signUp,\n }));\n}\n","<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { useDemoAuth } from \"./useDemoAuth.js\";\n\ninterface Props {\n appName: string;\n}\n\ndefineProps<Props>();\ndefineSlots<{\n default?: () => any;\n}>();\n\nconst auth = useDemoAuth();\nconst username = ref(\"\");\n\nconst darkMode =\n typeof window !== \"undefined\"\n ? window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n : false;\n\nconst handleSubmit = (e: Event) => {\n e.preventDefault();\n auth.value.signUp(username.value);\n};\n</script>\n\n<template>\n <slot v-if=\"auth.state === 'signedIn'\" />\n <div\n v-else\n :style=\"{\n minHeight: '100%',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n width: '18rem',\n maxWidth: 'calc(100vw - 2rem)',\n gap: '2rem',\n margin: '0 auto'\n }\"\n >\n <h1\n :style=\"{\n color: darkMode ? '#fff' : '#000',\n textAlign: 'center',\n fontSize: '1.5rem',\n fontWeight: 'bold'\n }\"\n >\n {{ appName }}\n </h1>\n\n <form\n :style=\"{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem'\n }\"\n @submit=\"handleSubmit\"\n >\n <input\n v-model=\"username\"\n placeholder=\"Display name\"\n autocomplete=\"webauthn\"\n :style=\"{\n border: darkMode ? '1px solid #444' : '1px solid #ddd',\n padding: '11px 8px',\n borderRadius: '6px',\n background: darkMode ? '#000' : '#fff',\n color: darkMode ? '#fff' : '#000'\n }\"\n >\n <input\n type=\"submit\"\n value=\"Sign up\"\n :style=\"{\n padding: '13px 5px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n background: darkMode ? '#444' : '#ddd',\n color: darkMode ? '#fff' : '#000'\n }\"\n >\n </form>\n\n <div\n v-if=\"auth.existingUsers.length > 0\"\n :style=\"{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem'\n }\"\n >\n <p\n :style=\"{\n color: darkMode ? '#e2e2e2' : '#000',\n textAlign: 'center',\n paddingTop: '0.5rem',\n borderTop: '1px solid',\n borderColor: darkMode ? '#111' : '#e2e2e2'\n }\"\n >\n Log in as\n </p>\n <button\n v-for=\"user in auth.existingUsers\"\n :key=\"user\"\n @click=\"auth.logIn(user)\"\n type=\"button\"\n :aria-label=\"`Log in as ${user}`\"\n :style=\"{\n background: darkMode ? '#0d0d0d' : '#eee',\n color: darkMode ? '#fff' : '#000',\n padding: '0.5rem',\n border: 'none',\n borderRadius: '6px'\n }\"\n >\n {{ user }}\n </button>\n </div>\n </div>\n</template>","<script setup lang=\"ts\">\nimport type { ImageDefinition } from \"jazz-tools\";\nimport { type Ref, onUnmounted, ref, toRef, watch } from \"vue\";\n\ninterface ImageState {\n src?: string;\n res?: `${number}x${number}` | \"placeholder\";\n originalSize?: readonly [number, number];\n}\n\nfunction useProgressiveImg(\n image: Ref<ImageDefinition | null | undefined>,\n maxWidth?: number,\n) {\n const current = ref<ImageState>({});\n\n let cleanup: (() => void) | undefined;\n const unsubscribe = watch(\n () => [image.value?.id, maxWidth],\n () => {\n let lastHighestRes: string | undefined;\n\n if (!image.value) return;\n\n const unsub = image.value.subscribe({}, (update) => {\n const highestRes = update?.highestResAvailable({ maxWidth });\n\n if (highestRes) {\n if (highestRes.res !== lastHighestRes) {\n lastHighestRes = highestRes.res;\n const blob = highestRes.stream.toBlob();\n\n if (blob) {\n const blobURI = URL.createObjectURL(blob);\n current.value = {\n src: blobURI,\n res: highestRes.res,\n originalSize: image.value?.originalSize,\n };\n\n if (cleanup) cleanup();\n cleanup = () => {\n setTimeout(() => URL.revokeObjectURL(blobURI), 200);\n };\n }\n }\n } else {\n current.value = {\n src: update?.placeholderDataURL,\n res: \"placeholder\",\n originalSize: image.value?.originalSize,\n };\n }\n });\n\n return unsub;\n },\n );\n\n onUnmounted(() => {\n unsubscribe();\n if (cleanup) cleanup();\n });\n\n return current;\n}\n\nconst props = defineProps<{\n image: ImageDefinition | null | undefined;\n maxWidth?: number;\n}>();\n\nconst current = useProgressiveImg(toRef(props, \"image\"), props.maxWidth);\n</script>\n\n<template>\n <slot\n :src=\"current.src\"\n :res=\"current.res\"\n :original-size=\"current.originalSize\"\n />\n</template>"],"names":["useAccount","useAccountOrGuest","current"],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { JazzBrowserContextManager } from "jazz-browser";
2
+ import { ref, defineComponent, provide, watch, onMounted, onUnmounted } from "vue";
3
+ ref();
4
+ const JazzContextSymbol = Symbol("JazzContext");
5
+ const JazzAuthContextSymbol = Symbol("JazzAuthContext");
6
+ const JazzProvider = defineComponent({
7
+ name: "JazzProvider",
8
+ props: {
9
+ guestMode: {
10
+ type: Boolean,
11
+ default: false
12
+ },
13
+ sync: {
14
+ type: Object,
15
+ required: true
16
+ },
17
+ AccountSchema: {
18
+ type: Function,
19
+ required: false
20
+ },
21
+ storage: {
22
+ type: String,
23
+ default: void 0
24
+ },
25
+ defaultProfileName: {
26
+ type: String,
27
+ required: false
28
+ },
29
+ onAnonymousAccountDiscarded: {
30
+ type: Function,
31
+ required: false
32
+ },
33
+ onLogOut: {
34
+ type: Function,
35
+ required: false
36
+ }
37
+ },
38
+ setup(props, { slots }) {
39
+ const contextManager = new JazzBrowserContextManager();
40
+ const ctx = ref();
41
+ provide(JazzContextSymbol, ctx);
42
+ provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());
43
+ watch(
44
+ () => ({
45
+ peer: props.sync.peer,
46
+ syncWhen: props.sync.when,
47
+ storage: props.storage,
48
+ guestMode: props.guestMode
49
+ }),
50
+ async () => {
51
+ contextManager.createContext({
52
+ sync: props.sync,
53
+ storage: props.storage,
54
+ guestMode: props.guestMode,
55
+ AccountSchema: props.AccountSchema,
56
+ defaultProfileName: props.defaultProfileName,
57
+ onAnonymousAccountDiscarded: props.onAnonymousAccountDiscarded,
58
+ onLogOut: props.onLogOut
59
+ }).catch((error) => {
60
+ console.error("Error creating Jazz browser context:", error);
61
+ });
62
+ },
63
+ { immediate: true }
64
+ );
65
+ onMounted(() => {
66
+ const cleanup = contextManager.subscribe(() => {
67
+ ctx.value = contextManager.getCurrentValue();
68
+ });
69
+ onUnmounted(cleanup);
70
+ });
71
+ onUnmounted(() => {
72
+ var _a, _b;
73
+ if (ctx.value) (_b = (_a = ctx.value).done) == null ? void 0 : _b.call(_a);
74
+ });
75
+ return () => {
76
+ var _a;
77
+ return ctx.value ? (_a = slots.default) == null ? void 0 : _a.call(slots) : null;
78
+ };
79
+ }
80
+ });
81
+ export {
82
+ JazzContextSymbol as J,
83
+ JazzAuthContextSymbol as a,
84
+ JazzProvider as b
85
+ };
86
+ //# sourceMappingURL=provider-CkA-a4Og.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-CkA-a4Og.js","sources":["../src/provider.ts"],"sourcesContent":["import { JazzBrowserContextManager } from \"jazz-browser\";\nimport { Account, AccountClass, JazzContextType, SyncConfig } from \"jazz-tools\";\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n PropType,\n computed,\n defineComponent,\n onMounted,\n onUnmounted,\n provide,\n ref,\n watch,\n} from \"vue\";\n\nexport const logoutHandler = ref<() => void>();\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface Register {}\n\nexport type RegisteredAccount = Register extends { Account: infer Acc }\n ? Acc\n : Account;\n\nexport const JazzContextSymbol = Symbol(\"JazzContext\");\nexport const JazzAuthContextSymbol = Symbol(\"JazzAuthContext\");\nexport const JazzProvider = defineComponent({\n name: \"JazzProvider\",\n props: {\n guestMode: {\n type: Boolean,\n default: false,\n },\n sync: {\n type: Object as PropType<SyncConfig>,\n required: true,\n },\n AccountSchema: {\n type: Function as unknown as PropType<AccountClass<RegisteredAccount>>,\n required: false,\n },\n storage: {\n type: String as PropType<\"indexedDB\" | \"singleTabOPFS\">,\n default: undefined,\n },\n defaultProfileName: {\n type: String,\n required: false,\n },\n onAnonymousAccountDiscarded: {\n type: Function as PropType<\n (anonymousAccount: RegisteredAccount) => Promise<void>\n >,\n required: false,\n },\n onLogOut: {\n type: Function as PropType<() => void>,\n required: false,\n },\n },\n setup(props, { slots }) {\n const contextManager = new JazzBrowserContextManager<RegisteredAccount>();\n const ctx = ref<JazzContextType<RegisteredAccount>>();\n\n provide(JazzContextSymbol, ctx);\n provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());\n\n watch(\n () => ({\n peer: props.sync.peer,\n syncWhen: props.sync.when,\n storage: props.storage,\n guestMode: props.guestMode,\n }),\n async () => {\n contextManager\n .createContext({\n sync: props.sync,\n storage: props.storage,\n guestMode: props.guestMode,\n AccountSchema: props.AccountSchema,\n defaultProfileName: props.defaultProfileName,\n onAnonymousAccountDiscarded: props.onAnonymousAccountDiscarded,\n onLogOut: props.onLogOut,\n })\n .catch((error) => {\n console.error(\"Error creating Jazz browser context:\", error);\n });\n },\n { immediate: true },\n );\n\n onMounted(() => {\n const cleanup = contextManager.subscribe(() => {\n ctx.value = contextManager.getCurrentValue();\n });\n onUnmounted(cleanup);\n });\n\n onUnmounted(() => {\n if (ctx.value) ctx.value.done?.();\n });\n\n return () => (ctx.value ? slots.default?.() : null);\n },\n});\n"],"names":[],"mappings":";;AAc6B,IAAgB;AAShC,MAAA,oBAAoB,OAAO,aAAa;AACxC,MAAA,wBAAwB,OAAO,iBAAiB;AACtD,MAAM,eAAe,gBAAgB;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,IACL,WAAW;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,eAAe;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,6BAA6B;AAAA,MAC3B,MAAM;AAAA,MAGN,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,EAEd;AAAA,EACA,MAAM,OAAO,EAAE,SAAS;AAChB,UAAA,iBAAiB,IAAI,0BAA6C;AACxE,UAAM,MAAM,IAAwC;AAEpD,YAAQ,mBAAmB,GAAG;AACtB,YAAA,uBAAuB,eAAe,sBAAsB;AAEpE;AAAA,MACE,OAAO;AAAA,QACL,MAAM,MAAM,KAAK;AAAA,QACjB,UAAU,MAAM,KAAK;AAAA,QACrB,SAAS,MAAM;AAAA,QACf,WAAW,MAAM;AAAA,MAAA;AAAA,MAEnB,YAAY;AACV,uBACG,cAAc;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,SAAS,MAAM;AAAA,UACf,WAAW,MAAM;AAAA,UACjB,eAAe,MAAM;AAAA,UACrB,oBAAoB,MAAM;AAAA,UAC1B,6BAA6B,MAAM;AAAA,UACnC,UAAU,MAAM;AAAA,QAAA,CACjB,EACA,MAAM,CAAC,UAAU;AACR,kBAAA,MAAM,wCAAwC,KAAK;AAAA,QAAA,CAC5D;AAAA,MACL;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AAEA,cAAU,MAAM;AACR,YAAA,UAAU,eAAe,UAAU,MAAM;AACzC,YAAA,QAAQ,eAAe,gBAAgB;AAAA,MAAA,CAC5C;AACD,kBAAY,OAAO;AAAA,IAAA,CACpB;AAED,gBAAY,MAAM;;AAChB,UAAI,IAAI,MAAW,iBAAA,OAAM,SAAN;AAAA,IAAa,CACjC;AAED,WAAO,MAAO;;AAAA,iBAAI,SAAQ,WAAM,YAAN,iCAAoB;AAAA;AAAA,EAAA;AAElD,CAAC;"}
@@ -1,4 +1,4 @@
1
- import { Account, AccountClass, AuthMethod } from 'jazz-tools';
1
+ import { Account, AccountClass, SyncConfig } from 'jazz-tools';
2
2
  import { PropType } from 'vue';
3
3
  export declare const logoutHandler: import('vue').Ref<(() => void) | undefined, (() => void) | undefined>;
4
4
  export interface Register {
@@ -7,42 +7,68 @@ export type RegisteredAccount = Register extends {
7
7
  Account: infer Acc;
8
8
  } ? Acc : Account;
9
9
  export declare const JazzContextSymbol: unique symbol;
10
+ export declare const JazzAuthContextSymbol: unique symbol;
10
11
  export declare const JazzProvider: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
11
- auth: {
12
- type: PropType<AuthMethod | "guest">;
12
+ guestMode: {
13
+ type: BooleanConstructor;
14
+ default: boolean;
15
+ };
16
+ sync: {
17
+ type: PropType<SyncConfig>;
13
18
  required: true;
14
19
  };
15
20
  AccountSchema: {
16
21
  type: PropType<AccountClass<RegisteredAccount>>;
17
22
  required: false;
18
23
  };
19
- peer: {
20
- type: PropType<`wss://${string}` | `ws://${string}`>;
21
- required: true;
22
- };
23
24
  storage: {
24
25
  type: PropType<"indexedDB" | "singleTabOPFS">;
25
26
  default: undefined;
26
27
  };
28
+ defaultProfileName: {
29
+ type: StringConstructor;
30
+ required: false;
31
+ };
32
+ onAnonymousAccountDiscarded: {
33
+ type: PropType<(anonymousAccount: RegisteredAccount) => Promise<void>>;
34
+ required: false;
35
+ };
36
+ onLogOut: {
37
+ type: PropType<() => void>;
38
+ required: false;
39
+ };
27
40
  }>, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
28
41
  [key: string]: any;
29
42
  }>[] | null | undefined, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
30
- auth: {
31
- type: PropType<AuthMethod | "guest">;
43
+ guestMode: {
44
+ type: BooleanConstructor;
45
+ default: boolean;
46
+ };
47
+ sync: {
48
+ type: PropType<SyncConfig>;
32
49
  required: true;
33
50
  };
34
51
  AccountSchema: {
35
52
  type: PropType<AccountClass<RegisteredAccount>>;
36
53
  required: false;
37
54
  };
38
- peer: {
39
- type: PropType<`wss://${string}` | `ws://${string}`>;
40
- required: true;
41
- };
42
55
  storage: {
43
56
  type: PropType<"indexedDB" | "singleTabOPFS">;
44
57
  default: undefined;
45
58
  };
59
+ defaultProfileName: {
60
+ type: StringConstructor;
61
+ required: false;
62
+ };
63
+ onAnonymousAccountDiscarded: {
64
+ type: PropType<(anonymousAccount: RegisteredAccount) => Promise<void>>;
65
+ required: false;
66
+ };
67
+ onLogOut: {
68
+ type: PropType<() => void>;
69
+ required: false;
70
+ };
46
71
  }>> & Readonly<{}>, {
47
72
  storage: "indexedDB" | "singleTabOPFS";
73
+ guestMode: boolean;
48
74
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
package/dist/testing.d.ts CHANGED
@@ -5,7 +5,11 @@ export declare const JazzTestProvider: import('vue').DefineComponent<import('vue
5
5
  type: PropType<Account | {
6
6
  guest: AnonymousJazzAgent;
7
7
  }>;
8
- required: true;
8
+ required: false;
9
+ };
10
+ isAuthenticated: {
11
+ type: BooleanConstructor;
12
+ required: false;
9
13
  };
10
14
  }>, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
11
15
  [key: string]: any;
@@ -14,7 +18,13 @@ export declare const JazzTestProvider: import('vue').DefineComponent<import('vue
14
18
  type: PropType<Account | {
15
19
  guest: AnonymousJazzAgent;
16
20
  }>;
17
- required: true;
21
+ required: false;
22
+ };
23
+ isAuthenticated: {
24
+ type: BooleanConstructor;
25
+ required: false;
18
26
  };
19
- }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
27
+ }>> & Readonly<{}>, {
28
+ isAuthenticated: boolean;
29
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
20
30
  export { createJazzTestAccount, createJazzTestGuest, linkAccounts, setActiveAccount, setupJazzTestSync, } from 'jazz-tools/testing';
package/dist/testing.js CHANGED
@@ -1,28 +1,40 @@
1
- import { getJazzContextShape as c } from "jazz-tools/testing";
2
- import { createJazzTestAccount as s, createJazzTestGuest as x, linkAccounts as T, setActiveAccount as v, setupJazzTestSync as A } from "jazz-tools/testing";
3
- import { defineComponent as n, ref as a, provide as z } from "vue";
4
- import { J as p } from "./provider-BZnz6FpX.js";
5
- const J = n({
1
+ import { TestJazzContextManager } from "jazz-tools/testing";
2
+ import { createJazzTestAccount, createJazzTestGuest, linkAccounts, setActiveAccount, setupJazzTestSync } from "jazz-tools/testing";
3
+ import { defineComponent, provide, ref } from "vue";
4
+ import { J as JazzContextSymbol, a as JazzAuthContextSymbol } from "./provider-CkA-a4Og.js";
5
+ const JazzTestProvider = defineComponent({
6
6
  name: "JazzTestProvider",
7
7
  props: {
8
8
  account: {
9
9
  type: Object,
10
- required: !0
10
+ required: false
11
+ },
12
+ isAuthenticated: {
13
+ type: Boolean,
14
+ required: false
11
15
  }
12
16
  },
13
- setup(r, { slots: e }) {
14
- const o = a(c(r.account));
15
- return z(p, o), () => {
16
- var t;
17
- return (t = e.default) == null ? void 0 : t.call(e);
17
+ setup(props, { slots }) {
18
+ const contextManager = TestJazzContextManager.fromAccountOrGuest(
19
+ props.account,
20
+ {
21
+ isAuthenticated: props.isAuthenticated
22
+ }
23
+ );
24
+ provide(JazzContextSymbol, ref(contextManager.getCurrentValue()));
25
+ provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());
26
+ return () => {
27
+ var _a;
28
+ return (_a = slots.default) == null ? void 0 : _a.call(slots);
18
29
  };
19
30
  }
20
31
  });
21
32
  export {
22
- J as JazzTestProvider,
23
- s as createJazzTestAccount,
24
- x as createJazzTestGuest,
25
- T as linkAccounts,
26
- v as setActiveAccount,
27
- A as setupJazzTestSync
33
+ JazzTestProvider,
34
+ createJazzTestAccount,
35
+ createJazzTestGuest,
36
+ linkAccounts,
37
+ setActiveAccount,
38
+ setupJazzTestSync
28
39
  };
40
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sources":["../src/testing.ts"],"sourcesContent":["import { Account, AnonymousJazzAgent } from \"jazz-tools\";\nimport { TestJazzContextManager } from \"jazz-tools/testing\";\nimport { provide } from \"vue\";\nimport { PropType, defineComponent, ref } from \"vue\";\nimport { JazzAuthContextSymbol, JazzContextSymbol } from \"./provider.js\";\n\nexport const JazzTestProvider = defineComponent({\n name: \"JazzTestProvider\",\n props: {\n account: {\n type: Object as PropType<Account | { guest: AnonymousJazzAgent }>,\n required: false,\n },\n isAuthenticated: {\n type: Boolean,\n required: false,\n },\n },\n setup(props, { slots }) {\n const contextManager = TestJazzContextManager.fromAccountOrGuest(\n props.account,\n {\n isAuthenticated: props.isAuthenticated,\n },\n );\n\n provide(JazzContextSymbol, ref(contextManager.getCurrentValue()));\n provide(JazzAuthContextSymbol, contextManager.getAuthSecretStorage());\n\n return () => slots.default?.();\n },\n});\n\nexport {\n createJazzTestAccount,\n createJazzTestGuest,\n linkAccounts,\n setActiveAccount,\n setupJazzTestSync,\n} from \"jazz-tools/testing\";\n"],"names":[],"mappings":";;;;AAMO,MAAM,mBAAmB,gBAAgB;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,IACL,SAAS;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,EAEd;AAAA,EACA,MAAM,OAAO,EAAE,SAAS;AACtB,UAAM,iBAAiB,uBAAuB;AAAA,MAC5C,MAAM;AAAA,MACN;AAAA,QACE,iBAAiB,MAAM;AAAA,MAAA;AAAA,IAE3B;AAEA,YAAQ,mBAAmB,IAAI,eAAe,gBAAiB,CAAA,CAAC;AACxD,YAAA,uBAAuB,eAAe,sBAAsB;AAE7D,WAAA,MAAA;;AAAM,yBAAM,YAAN;AAAA;AAAA,EAAgB;AAEjC,CAAC;"}
@@ -0,0 +1 @@
1
+ export declare const testWordlist: string[];
@@ -1,8 +1,9 @@
1
1
  import { Account, AnonymousJazzAgent } from 'jazz-tools';
2
2
  import { createApp } from 'vue';
3
- export declare const withJazzTestSetup: <C extends (...args: any[]) => any>(composable: C, { account }: {
4
- account: Account | {
3
+ export declare const withJazzTestSetup: <C extends (...args: any[]) => any>(composable: C, { account, isAuthenticated, }?: {
4
+ account?: Account | {
5
5
  guest: AnonymousJazzAgent;
6
6
  };
7
+ isAuthenticated?: boolean;
7
8
  }) => [ReturnType<C>, ReturnType<typeof createApp>];
8
9
  export declare function waitFor(callback: () => boolean | void): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jazz-vue",
3
- "version": "0.9.22",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -16,15 +16,16 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "cojson": "0.9.19",
20
- "jazz-tools": "0.9.21",
21
- "jazz-browser": "0.9.22"
19
+ "cojson": "0.10.0",
20
+ "jazz-tools": "0.10.0",
21
+ "jazz-browser": "0.10.0"
22
22
  },
23
23
  "devDependencies": {
24
+ "@scure/bip39": "^1.3.0",
24
25
  "@vitejs/plugin-vue": "^5.1.4",
25
26
  "rollup-plugin-node-externals": "^8.0.0",
26
27
  "typescript": "~5.6.2",
27
- "vite": "^5.4.10",
28
+ "vite": "^6.0.11",
28
29
  "vite-plugin-dts": "^4.2.4",
29
30
  "vue": "^3.5.11",
30
31
  "vue-tsc": "^2.1.6"
@@ -33,7 +34,7 @@
33
34
  "vue": "^3.5.11"
34
35
  },
35
36
  "scripts": {
36
- "dev": "vite",
37
+ "dev": "vite build --watch",
37
38
  "format-and-lint": "biome check .",
38
39
  "format-and-lint:fix": "biome check . --write",
39
40
  "build": "rm -rf ./dist && vite build"
@@ -1,123 +1,125 @@
1
- <template>
2
- <div
3
- :style="containerStyle"
4
- >
5
- <div v-if="state.state === 'loading'">Loading...</div>
6
- <template v-else-if="state.state === 'ready'">
7
- <h1 :style="{ color: darkMode ? '#fff' : '#000', textAlign: 'center' }">
8
- {{ appName }}
9
- </h1>
10
- <div v-for="error in state.errors" :key="error" style="color: red">
11
- {{ error }}
12
- </div>
13
- <form
14
- @submit.prevent="signUp"
15
- style="display: flex; flex-direction: column; gap: 0.5rem;"
16
- >
17
- <input
18
- v-model="username"
19
- placeholder="Display name"
20
- autoComplete="webauthn"
21
- :style="inputStyle"
22
- />
23
- <input
24
- type="submit"
25
- value="Sign up"
26
- :style="buttonStyle"
27
- />
28
- </form>
29
- <div
30
- v-if="state.existingUsers.length > 0"
31
- style="display: flex; flex-direction: column; gap: 0.5rem;"
32
- >
33
- <p
34
- :style="{
35
- color: darkMode ? '#e2e2e2' : '#000',
36
- textAlign: 'center',
37
- paddingTop: '0.5rem',
38
- borderTop: '1px solid',
39
- borderColor: darkMode ? '#111' : '#e2e2e2',
40
- }"
41
- >
42
- Log in as
43
- </p>
44
- <button
45
- v-for="user in state.existingUsers"
46
- :key="user"
47
- @click="logInAs(user)"
48
- type="button"
49
- :aria-label="`Log in as ${user}`"
50
- :style="loginButtonStyle"
51
- >
52
- {{ user }}
53
- </button>
54
- </div>
55
- </template>
56
- </div>
57
- </template>
58
-
59
- <script setup lang="ts">
60
- import { computed, ref } from "vue";
61
- import { DemoAuthState } from "./useDemoAuth.js";
1
+ <script setup lang="ts">
2
+ import { ref } from "vue";
3
+ import { useDemoAuth } from "./useDemoAuth.js";
62
4
 
63
- const props = defineProps<{
5
+ interface Props {
64
6
  appName: string;
65
- state: DemoAuthState;
7
+ }
8
+
9
+ defineProps<Props>();
10
+ defineSlots<{
11
+ default?: () => any;
66
12
  }>();
67
13
 
14
+ const auth = useDemoAuth();
68
15
  const username = ref("");
69
- const darkMode = computed(
70
- () =>
71
- window.matchMedia &&
72
- window.matchMedia("(prefers-color-scheme: dark)").matches,
73
- );
74
16
 
75
- const containerStyle = computed(() => ({
76
- minHeight: "100vh",
77
- display: "flex",
78
- flexDirection: "column" as const,
79
- justifyContent: "center",
80
- alignItems: "center",
81
- width: "100%",
82
- padding: "1rem",
83
- maxWidth: "100vw",
84
- gap: "2rem",
85
- margin: "0",
86
- ...(darkMode.value ? { background: "#000" } : {}),
87
- }));
17
+ const darkMode =
18
+ typeof window !== "undefined"
19
+ ? window.matchMedia("(prefers-color-scheme: dark)").matches
20
+ : false;
88
21
 
89
- const inputStyle = computed(() => ({
90
- border: darkMode.value ? "2px solid #444" : "2px solid #ddd",
91
- padding: "11px 8px",
92
- borderRadius: "6px",
93
- background: darkMode.value ? "#000" : "#fff",
94
- color: darkMode.value ? "#fff" : "#000",
95
- }));
96
-
97
- const buttonStyle = computed(() => ({
98
- padding: "13px 5px",
99
- border: "none",
100
- borderRadius: "6px",
101
- cursor: "pointer",
102
- background: darkMode.value ? "#444" : "#ddd",
103
- color: darkMode.value ? "#fff" : "#000",
104
- }));
22
+ const handleSubmit = (e: Event) => {
23
+ e.preventDefault();
24
+ auth.value.signUp(username.value);
25
+ };
26
+ </script>
105
27
 
106
- const loginButtonStyle = computed(() => ({
107
- background: darkMode.value ? "#0d0d0d" : "#eee",
108
- color: darkMode.value ? "#fff" : "#000",
109
- padding: "0.5rem",
110
- border: "none",
111
- borderRadius: "6px",
112
- }));
28
+ <template>
29
+ <slot v-if="auth.state === 'signedIn'" />
30
+ <div
31
+ v-else
32
+ :style="{
33
+ minHeight: '100%',
34
+ display: 'flex',
35
+ flexDirection: 'column',
36
+ justifyContent: 'center',
37
+ width: '18rem',
38
+ maxWidth: 'calc(100vw - 2rem)',
39
+ gap: '2rem',
40
+ margin: '0 auto'
41
+ }"
42
+ >
43
+ <h1
44
+ :style="{
45
+ color: darkMode ? '#fff' : '#000',
46
+ textAlign: 'center',
47
+ fontSize: '1.5rem',
48
+ fontWeight: 'bold'
49
+ }"
50
+ >
51
+ {{ appName }}
52
+ </h1>
113
53
 
114
- const signUp = () => {
115
- (props.state as DemoAuthState & { state: "ready" }).signUp(username.value);
116
- username.value = "";
117
- };
54
+ <form
55
+ :style="{
56
+ display: 'flex',
57
+ flexDirection: 'column',
58
+ gap: '0.5rem'
59
+ }"
60
+ @submit="handleSubmit"
61
+ >
62
+ <input
63
+ v-model="username"
64
+ placeholder="Display name"
65
+ autocomplete="webauthn"
66
+ :style="{
67
+ border: darkMode ? '1px solid #444' : '1px solid #ddd',
68
+ padding: '11px 8px',
69
+ borderRadius: '6px',
70
+ background: darkMode ? '#000' : '#fff',
71
+ color: darkMode ? '#fff' : '#000'
72
+ }"
73
+ >
74
+ <input
75
+ type="submit"
76
+ value="Sign up"
77
+ :style="{
78
+ padding: '13px 5px',
79
+ border: 'none',
80
+ borderRadius: '6px',
81
+ cursor: 'pointer',
82
+ background: darkMode ? '#444' : '#ddd',
83
+ color: darkMode ? '#fff' : '#000'
84
+ }"
85
+ >
86
+ </form>
118
87
 
119
- const logInAs = (user: string) => {
120
- (props.state as DemoAuthState & { state: "ready" }).logInAs(user);
121
- };
122
- </script>
123
-
88
+ <div
89
+ v-if="auth.existingUsers.length > 0"
90
+ :style="{
91
+ display: 'flex',
92
+ flexDirection: 'column',
93
+ gap: '0.5rem'
94
+ }"
95
+ >
96
+ <p
97
+ :style="{
98
+ color: darkMode ? '#e2e2e2' : '#000',
99
+ textAlign: 'center',
100
+ paddingTop: '0.5rem',
101
+ borderTop: '1px solid',
102
+ borderColor: darkMode ? '#111' : '#e2e2e2'
103
+ }"
104
+ >
105
+ Log in as
106
+ </p>
107
+ <button
108
+ v-for="user in auth.existingUsers"
109
+ :key="user"
110
+ @click="auth.logIn(user)"
111
+ type="button"
112
+ :aria-label="`Log in as ${user}`"
113
+ :style="{
114
+ background: darkMode ? '#0d0d0d' : '#eee',
115
+ color: darkMode ? '#fff' : '#000',
116
+ padding: '0.5rem',
117
+ border: 'none',
118
+ borderRadius: '6px'
119
+ }"
120
+ >
121
+ {{ user }}
122
+ </button>
123
+ </div>
124
+ </div>
125
+ </template>