jazz-vue 0.11.8 → 0.12.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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { consumeInviteLinkFromWindowLocation, BrowserPasskeyAuth } from "jazz-browser";
2
2
  import { createInviteLink, parseInviteLink } from "jazz-browser";
3
3
  import { subscribeToCoValue, DemoAuth, PassphraseAuth } from "jazz-tools";
4
- import { ref, inject, shallowRef, watch, unref, toRaw, onUnmounted, computed, onMounted, watchEffect, defineComponent, renderSlot, openBlock, createElementBlock, createElementVNode, normalizeStyle, toDisplayString, withDirectives, vModelText, Fragment, renderList, createCommentVNode, toRef } from "vue";
4
+ import { ref, inject, computed, toRaw, shallowRef, watch, unref, onUnmounted, onMounted, watchEffect, defineComponent, renderSlot, openBlock, createElementBlock, createElementVNode, normalizeStyle, toDisplayString, withDirectives, vModelText, Fragment, renderList, createCommentVNode, toRef } from "vue";
5
5
  import { J as JazzContextSymbol, a as JazzAuthContextSymbol } from "./provider-CkA-a4Og.js";
6
6
  import { b } from "./provider-CkA-a4Og.js";
7
7
  const logoutHandler = ref();
@@ -19,64 +19,57 @@ function useAuthSecretStorage() {
19
19
  }
20
20
  return context;
21
21
  }
22
- function createUseAccountComposables() {
23
- function useAccount2(depth) {
24
- const context = useJazzContext();
25
- if (!context.value) {
26
- throw new Error("useAccount must be used within a JazzProvider");
27
- }
28
- if (!("me" in context.value)) {
29
- throw new Error(
30
- "useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()"
31
- );
32
- }
33
- const contextMe = context.value.me;
34
- const me = useCoState(
35
- contextMe.constructor,
36
- contextMe.id,
37
- depth
38
- );
39
- return {
40
- me: computed(() => {
41
- const value = depth === void 0 ? me.value || toRaw(context.value.me) : me.value;
42
- return value ? toRaw(value) : value;
43
- }),
44
- logOut: context.value.logOut
45
- };
22
+ function useAccount(options) {
23
+ const context = useJazzContext();
24
+ if (!context.value) {
25
+ throw new Error("useAccount must be used within a JazzProvider");
46
26
  }
47
- function useAccountOrGuest2(depth) {
48
- var _a, _b;
49
- const context = useJazzContext();
50
- if (!context.value) {
51
- throw new Error("useAccountOrGuest must be used within a JazzProvider");
52
- }
53
- const contextMe = computed(
54
- () => "me" in context.value ? context.value.me : void 0
55
- );
56
- const me = useCoState(
57
- (_a = contextMe.value) == null ? void 0 : _a.constructor,
58
- (_b = contextMe.value) == null ? void 0 : _b.id,
59
- depth
27
+ if (!("me" in context.value)) {
28
+ throw new Error(
29
+ "useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()"
60
30
  );
61
- if ("me" in context.value) {
62
- return {
63
- me: computed(
64
- () => depth === void 0 ? me.value || toRaw(context.value.me) : me.value
65
- )
66
- };
67
- } else {
68
- return {
69
- me: computed(() => toRaw(context.value.guest))
70
- };
71
- }
72
31
  }
32
+ const contextMe = context.value.me;
33
+ const me = useCoState(
34
+ contextMe.constructor,
35
+ contextMe.id,
36
+ options
37
+ );
73
38
  return {
74
- useAccount: useAccount2,
75
- useAccountOrGuest: useAccountOrGuest2
39
+ me: computed(() => {
40
+ const value = (options == null ? void 0 : options.resolve) === void 0 ? me.value || toRaw(context.value.me) : me.value;
41
+ return value ? toRaw(value) : value;
42
+ }),
43
+ logOut: context.value.logOut
76
44
  };
77
45
  }
78
- const { useAccount, useAccountOrGuest } = createUseAccountComposables();
79
- function useCoState(Schema, id, depth = []) {
46
+ function useAccountOrGuest(options) {
47
+ var _a, _b;
48
+ const context = useJazzContext();
49
+ if (!context.value) {
50
+ throw new Error("useAccountOrGuest must be used within a JazzProvider");
51
+ }
52
+ const contextMe = computed(
53
+ () => "me" in context.value ? context.value.me : void 0
54
+ );
55
+ const me = useCoState(
56
+ (_a = contextMe.value) == null ? void 0 : _a.constructor,
57
+ (_b = contextMe.value) == null ? void 0 : _b.id,
58
+ options
59
+ );
60
+ if ("me" in context.value) {
61
+ return {
62
+ me: computed(
63
+ () => (options == null ? void 0 : options.resolve) === void 0 ? me.value || toRaw(context.value.me) : me.value
64
+ )
65
+ };
66
+ } else {
67
+ return {
68
+ me: computed(() => toRaw(context.value.guest))
69
+ };
70
+ }
71
+ }
72
+ function useCoState(Schema, id, options) {
80
73
  const state = shallowRef(void 0);
81
74
  const context = useJazzContext();
82
75
  if (!context.value) {
@@ -84,7 +77,7 @@ function useCoState(Schema, id, depth = []) {
84
77
  }
85
78
  let unsubscribe;
86
79
  watch(
87
- [() => unref(id), () => context, () => Schema, () => depth],
80
+ [() => unref(id), () => context, () => Schema, () => options],
88
81
  () => {
89
82
  if (unsubscribe) unsubscribe();
90
83
  const idValue = unref(id);
@@ -92,15 +85,20 @@ function useCoState(Schema, id, depth = []) {
92
85
  unsubscribe = subscribeToCoValue(
93
86
  Schema,
94
87
  idValue,
95
- "me" in context.value ? toRaw(context.value.me) : toRaw(context.value.guest),
96
- depth,
88
+ {
89
+ resolve: options == null ? void 0 : options.resolve,
90
+ loadAs: "me" in context.value ? toRaw(context.value.me) : toRaw(context.value.guest),
91
+ onUnavailable: () => {
92
+ state.value = null;
93
+ },
94
+ onUnauthorized: () => {
95
+ state.value = null;
96
+ },
97
+ syncResolution: true
98
+ },
97
99
  (value) => {
98
100
  state.value = value;
99
- },
100
- () => {
101
- state.value = null;
102
- },
103
- true
101
+ }
104
102
  );
105
103
  },
106
104
  { deep: true, immediate: true }
@@ -430,7 +428,6 @@ export {
430
428
  b as JazzProvider,
431
429
  _sfc_main as ProgressiveImg,
432
430
  createInviteLink,
433
- createUseAccountComposables,
434
431
  logoutHandler,
435
432
  parseInviteLink,
436
433
  useAcceptInvite,
package/dist/index.js.map CHANGED
@@ -1 +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<CoValue> | 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 context.value.register,\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 registerNewAccount: authMethod.value.registerNewAccount,\n generateRandomPassphrase: authMethod.value.generateRandomPassphrase,\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 targetWidth?: 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({\n maxWidth,\n targetWidth,\n });\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":";;;;;;AAqCO,MAAM,gBAAgB,IAAgB;AAEtC,SAAS,iBAAiB;AACzB,QAAA,UACJ,OAAgD,iBAAiB;AAC/D,MAAA,EAAC,mCAAS,QAAO;AACb,UAAA,IAAI,MAAM,mDAAmD;AAAA,EAAA;AAE9D,SAAA;AACT;AAEO,SAAS,uBAAuB;AAC/B,QAAA,UAAU,OAA0B,qBAAqB;AAC/D,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,yDAAyD;AAAA,EAAA;AAEpE,SAAA;AACT;AAEO,SAAS,8BAAmD;AAWjE,WAASA,YACP,OAIA;AACA,UAAM,UAAU,eAAe;AAE3B,QAAA,CAAC,QAAQ,OAAO;AACZ,YAAA,IAAI,MAAM,+CAA+C;AAAA,IAAA;AAG7D,QAAA,EAAE,QAAQ,QAAQ,QAAQ;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IAAA;AAGI,UAAA,YAAY,QAAQ,MAAM;AAEhC,UAAM,KAAK;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,MACV;AAAA,IACF;AAEO,WAAA;AAAA,MACL,IAAI,SAAS,MAAM;AACX,cAAA,QACJ,UAAU,SACN,GAAG,SAAS,MAAO,QAAQ,MAA+B,EAAE,IAC5D,GAAG;AAEF,eAAA,QAAQ,MAAM,KAAK,IAAI;AAAA,MAAA,CAC/B;AAAA,MACD,QAAQ,QAAQ,MAAM;AAAA,IACxB;AAAA,EAAA;AAaF,WAASC,mBACP,OAKA;;AACA,UAAM,UAAU,eAAe;AAE3B,QAAA,CAAC,QAAQ,OAAO;AACZ,YAAA,IAAI,MAAM,sDAAsD;AAAA,IAAA;AAGxE,UAAM,YAAY;AAAA,MAAS,MACzB,QAAQ,QAAQ,QAAS,QAAQ,MAAM,KAAa;AAAA,IACtD;AAEA,UAAM,KAAK;AAAA,OACT,eAAU,UAAV,mBAAiB;AAAA,OACjB,eAAU,UAAV,mBAAiB;AAAA,MACjB;AAAA,IACF;AAEI,QAAA,QAAQ,QAAQ,OAAO;AAClB,aAAA;AAAA,QACL,IAAI;AAAA,UAAS,MACX,UAAU,SACN,GAAG,SAAS,MAAO,QAAQ,MAA+B,EAAE,IAC5D,GAAG;AAAA,QAAA;AAAA,MAEX;AAAA,IAAA,OACK;AACE,aAAA;AAAA,QACL,IAAI,SAAS,MAAM,MAAO,QAAQ,MAA2B,KAAK,CAAC;AAAA,MACrE;AAAA,IAAA;AAAA,EACF;AAGK,SAAA;AAAA,IACL,YAAAD;AAAAA,IACA,mBAAAC;AAAAA,EACF;AACF;AAEA,MAAM,EAAE,YAAY,kBAAkB,IACpC,4BAA+C;AAI1C,SAAS,WACd,QACA,IACA,QAAyB,CAAA,GACmB;AACtC,QAAA,QACJ,WAAW,MAAS;AACtB,QAAM,UAAU,eAAe;AAE3B,MAAA,CAAC,QAAQ,OAAO;AACZ,UAAA,IAAI,MAAM,+CAA+C;AAAA,EAAA;AAG7D,MAAA;AAEJ;AAAA,IACE,CAAC,MAAM,MAAM,EAAE,GAAG,MAAM,SAAS,MAAM,QAAQ,MAAM,KAAK;AAAA,IAC1D,MAAM;AACJ,UAAI,YAAyB,aAAA;AAEvB,YAAA,UAAU,MAAM,EAAE;AACxB,UAAI,CAAC,QAAS;AAEA,oBAAA;AAAA,QACZ;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,QACZ,MAAM,QAAQ,MAAM,EAAE,IACtB,MAAM,QAAQ,MAAM,KAAK;AAAA,QAC7B;AAAA,QACA,CAAC,UAAU;AACT,gBAAM,QAAQ;AAAA,QAChB;AAAA,QACA,MAAM;AACJ,gBAAM,QAAQ;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,MAAM,MAAM,WAAW,KAAK;AAAA,EAChC;AAEA,cAAY,MAAM;AAChB,QAAI,YAAyB,aAAA;AAAA,EAAA,CAC9B;AAED,QAAM,gBAAgB,SAAS,MAAM,MAAM,KAAK;AAEzC,SAAA;AACT;AAEO,SAAS,gBAAmC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AACF,GAIS;AACP,QAAM,UAAU,eAAe;AAE3B,MAAA,CAAC,QAAQ,OAAO;AACZ,UAAA,IAAI,MAAM,oDAAoD;AAAA,EAAA;AAGlE,MAAA,EAAE,QAAQ,QAAQ,QAAQ;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EAAA;AAGF,QAAM,sBAAsB,MAAM;AAChC,UAAM,SAAS,oCAAoC;AAAA,MACjD,IAAI,MAAO,QAAQ,MAA6C,EAAE;AAAA,MAClE;AAAA,MACA;AAAA,IAAA,CACD;AAGE,WAAA,KAAK,CAAC,QAAQ,OAAO,SAAS,IAAI,OAAO,CAAC,EAC1C,MAAM,CAAC,MAAM;AACJ,cAAA,MAAM,2BAA2B,CAAC;AAAA,IAAA,CAC3C;AAAA,EACL;AAEA,YAAU,MAAM;AACM,wBAAA;AAAA,EAAA,CACrB;AAED;AAAA,IACE,MAAM;AAAA,IACN,CAAC,aAAa,gBAAgB;AAC5B,UAAI,gBAAgB,aAAa;AACX,4BAAA;AAAA,MAAA;AAAA,IACtB;AAAA,EAEJ;AACF;ACpQO,SAAS,qBAAqB;AACnC,QAAM,oBAAoB,qBAAqB;AACzC,QAAA,kBAAkB,IAAI,kBAAkB,eAAe;AAE7D,QAAM,eAAe,MAAM;AACzB,oBAAgB,QAAQ,kBAAkB;AAAA,EAC5C;AAEA,YAAU,MAAM;AACR,UAAA,UAAU,kBAAkB,SAAS,YAAY;AACvD,gBAAY,OAAO;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;ACZO,SAAS,cAAc;AAC5B,QAAM,UAAU,eAAe;AAC/B,QAAM,oBAAoB,qBAAqB;AAE3C,MAAA,WAAW,QAAQ,OAAO;AACtB,UAAA,IAAI,MAAM,0CAA0C;AAAA,EAAA;AAG5D,QAAM,aAAa;AAAA,IACjB,MAAM,IAAI,SAAS,QAAQ,MAAM,cAAc,iBAAiB;AAAA,EAClE;AAEM,QAAA,gBAAgB,IAAc,EAAE;AACtC,QAAM,kBAAkB,mBAAmB;AAE3C,QAAM,YAAY,MAAM;AACtB,eAAW,MAAM,iBAAmB,EAAA,KAAK,CAAC,UAAU;AAClD,oBAAc,QAAQ;AAAA,IAAA,CACvB;AAAA,EAAA,CACF;AAED,SAAO,SAAS,OAAO;AAAA,IACrB,OAAO,gBAAgB,QAAQ,aAAa;AAAA,IAC5C,MAAM,UAAkB;AACX,iBAAA,MAAM,MAAM,QAAQ;AAAA,IACjC;AAAA,IACA,OAAO,UAAkB;AACZ,iBAAA,MAAM,OAAO,QAAQ;AAAA,IAClC;AAAA,IACA,eAAe,cAAc;AAAA,EAAA,EAC7B;AACJ;ACrBO,SAAS,kBAAkB;AAAA,EAChC;AACF,GAEG;AACD,QAAM,UAAU,eAAe;AAC/B,QAAM,oBAAoB,qBAAqB;AAC/C,QAAM,kBAAkB,mBAAmB;AAEvC,MAAA,WAAW,QAAQ,OAAO;AACtB,UAAA,IAAI,MAAM,gDAAgD;AAAA,EAAA;AAG5D,QAAA,aAAa,SAAS,MAAM;AAChC,WAAO,IAAI;AAAA,MACT,QAAQ,MAAM,KAAK;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd,QAAQ,MAAM;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EAAA,CACD;AAED,QAAM,aAAa,IAAI,WAAW,MAAM,UAAU;AAElD,cAAY,CAAC,cAAc;AACzB,eAAW,MAAM,6BAA6B;AAE9C,UAAM,cAAc,WAAW,MAAM,UAAU,MAAM;AACxC,iBAAA,QAAQ,WAAW,MAAM;AAAA,IAAA,CACrC;AAED,cAAU,WAAW;AAAA,EAAA,CACtB;AAED,SAAO,SAAS,OAAO;AAAA,IACrB,OAAO,gBAAgB,QAAQ,aAAa;AAAA,IAC5C,OAAO,WAAW,MAAM;AAAA,IACxB,QAAQ,WAAW,MAAM;AAAA,IACzB,oBAAoB,WAAW,MAAM;AAAA,IACrC,0BAA0B,WAAW,MAAM;AAAA,IAC3C,YAAY,WAAW;AAAA,EAAA,EACvB;AACJ;AC3CO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAGG;AACD,QAAM,UAAU,eAAe;AAC/B,QAAM,oBAAoB,qBAAqB;AAC/C,QAAM,kBAAkB,mBAAmB;AAEvC,MAAA,WAAW,QAAQ,OAAO;AACtB,UAAA,IAAI,MAAM,6CAA6C;AAAA,EAAA;AAGzD,QAAA,aAAa,SAAS,MAAM;AAChC,WAAO,IAAI;AAAA,MACT,QAAQ,MAAM,KAAK;AAAA,MACnB,QAAQ,MAAM;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EAAA,CACD;AAED,SAAO,SAAS,OAAO;AAAA,IACrB,OAAO,gBAAgB,QAAQ,aAAa;AAAA,IAC5C,OAAO,WAAW,MAAM;AAAA,IACxB,QAAQ,WAAW,MAAM;AAAA,EAAA,EACzB;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChCA,UAAM,OAAO,YAAY;AACnB,UAAA,WAAW,IAAI,EAAE;AAEjB,UAAA,WACJ,OAAO,WAAW,cACd,OAAO,WAAW,8BAA8B,EAAE,UAClD;AAEA,UAAA,eAAe,CAAC,MAAa;AACjC,QAAE,eAAe;AACZ,WAAA,MAAM,OAAO,SAAS,KAAK;AAAA,IAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACdS,aAAA,kBACP,OACA,UACA,aACA;AACMC,YAAAA,WAAU,IAAgB,EAAE;AAE9B,UAAA;AACJ,YAAM,cAAc;AAAA,QAClB,MAAA;;AAAM,mBAAC,WAAM,UAAN,mBAAa,IAAI,QAAQ;AAAA;AAAA,QAChC,MAAM;AACA,cAAA;AAEA,cAAA,CAAC,MAAM,MAAO;AAElB,gBAAM,QAAQ,MAAM,MAAM,UAAU,CAAA,GAAI,CAAC,WAAW;;AAC5C,kBAAA,aAAa,iCAAQ,oBAAoB;AAAA,cAC7C;AAAA,cACA;AAAA,YAAA;AAGF,gBAAI,YAAY;AACV,kBAAA,WAAW,QAAQ,gBAAgB;AACrC,iCAAiB,WAAW;AACtB,sBAAA,OAAO,WAAW,OAAO,OAAO;AAEtC,oBAAI,MAAM;AACF,wBAAA,UAAU,IAAI,gBAAgB,IAAI;AACxCA,2BAAQ,QAAQ;AAAA,oBACd,KAAK;AAAA,oBACL,KAAK,WAAW;AAAA,oBAChB,eAAc,WAAM,UAAN,mBAAa;AAAA,kBAC7B;AAEA,sBAAI,QAAiB,SAAA;AACrB,4BAAU,MAAM;AACd,+BAAW,MAAM,IAAI,gBAAgB,OAAO,GAAG,GAAG;AAAA,kBACpD;AAAA,gBAAA;AAAA,cACF;AAAA,YACF,OACK;AACLA,uBAAQ,QAAQ;AAAA,gBACd,KAAK,iCAAQ;AAAA,gBACb,KAAK;AAAA,gBACL,eAAc,WAAM,UAAN,mBAAa;AAAA,cAC7B;AAAA,YAAA;AAAA,UACF,CACD;AAEM,iBAAA;AAAA,QAAA;AAAA,MAEX;AAEA,kBAAY,MAAM;AACJ,oBAAA;AACZ,YAAI,QAAiB,SAAA;AAAA,MAAA,CACtB;AAEMA,aAAAA;AAAAA,IAAA;AAGT,UAAM,QAAQ;AAKd,UAAM,UAAU,kBAAkB,MAAM,OAAO,OAAO,GAAG,MAAM,QAAQ;;;;;;;;;;"}
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 ID,\n JazzAuthContext,\n JazzContextType,\n JazzGuestContext,\n RefsToResolve,\n RefsToResolveStrict,\n Resolved,\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(): Ref<\n JazzContextType<RegisteredAccount>,\n JazzContextType<RegisteredAccount>\n> {\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 useAccount(): {\n me: ComputedRef<RegisteredAccount>;\n logOut: () => void;\n};\nexport function useAccount<\n const R extends RefsToResolve<RegisteredAccount>,\n>(options?: {\n resolve?: RefsToResolveStrict<RegisteredAccount, R>;\n}): {\n me: ComputedRef<Resolved<RegisteredAccount, R> | undefined | null>;\n logOut: () => void;\n};\nexport function useAccount<\n const R extends RefsToResolve<RegisteredAccount>,\n>(options?: {\n resolve?: RefsToResolveStrict<RegisteredAccount, R>;\n}): {\n me: ComputedRef<\n RegisteredAccount | Resolved<RegisteredAccount, R> | undefined | null\n >;\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 RegisteredAccount;\n\n const me = useCoState<RegisteredAccount, R>(\n contextMe.constructor as CoValueClass<RegisteredAccount>,\n contextMe.id,\n options,\n );\n\n return {\n me: computed(() => {\n const value =\n options?.resolve === undefined\n ? me.value ||\n toRaw((context.value as JazzAuthContext<RegisteredAccount>).me)\n : me.value;\n\n return value ? toRaw(value) : value;\n }),\n logOut: context.value.logOut,\n };\n}\n\nexport function useAccountOrGuest(): {\n me: ComputedRef<RegisteredAccount | AnonymousJazzAgent>;\n};\nexport function useAccountOrGuest<\n const R extends RefsToResolve<RegisteredAccount>,\n>(options?: {\n resolve?: RefsToResolveStrict<RegisteredAccount, R>;\n}): {\n me: ComputedRef<\n Resolved<RegisteredAccount, R> | undefined | null | AnonymousJazzAgent\n >;\n};\nexport function useAccountOrGuest<\n const R extends RefsToResolve<RegisteredAccount>,\n>(options?: {\n resolve?: RefsToResolveStrict<RegisteredAccount, R>;\n}): {\n me: ComputedRef<\n | RegisteredAccount\n | Resolved<RegisteredAccount, R>\n | undefined\n | null\n | 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 RegisteredAccount) : undefined,\n );\n\n const me = useCoState<RegisteredAccount, R>(\n contextMe.value?.constructor as CoValueClass<RegisteredAccount>,\n contextMe.value?.id,\n options,\n );\n\n if (\"me\" in context.value) {\n return {\n me: computed(() =>\n options?.resolve === undefined\n ? me.value ||\n toRaw((context.value as JazzAuthContext<RegisteredAccount>).me)\n : me.value,\n ),\n };\n } else {\n return {\n me: computed(() => toRaw((context.value as JazzGuestContext).guest)),\n };\n }\n}\n\nexport function useCoState<V extends CoValue, const R extends RefsToResolve<V>>(\n Schema: CoValueClass<V>,\n id: MaybeRef<ID<CoValue> | undefined>,\n options?: { resolve?: RefsToResolveStrict<V, R> },\n): Ref<Resolved<V, R> | undefined | null> {\n const state: ShallowRef<Resolved<V, R> | 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, () => options],\n () => {\n if (unsubscribe) unsubscribe();\n\n const idValue = unref(id);\n if (!idValue) return;\n\n unsubscribe = subscribeToCoValue(\n Schema,\n idValue,\n {\n resolve: options?.resolve,\n loadAs:\n \"me\" in context.value\n ? toRaw(context.value.me)\n : toRaw(context.value.guest),\n onUnavailable: () => {\n state.value = null;\n },\n onUnauthorized: () => {\n state.value = null;\n },\n syncResolution: true,\n },\n (value) => {\n state.value = value;\n },\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 context.value.register,\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 registerNewAccount: authMethod.value.registerNewAccount,\n generateRandomPassphrase: authMethod.value.generateRandomPassphrase,\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 targetWidth?: 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({\n maxWidth,\n targetWidth,\n });\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":["current"],"mappings":"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"}
@@ -1 +1,14 @@
1
+ import { Account, CoMap, co } from 'jazz-tools';
2
+ declare class AccountRoot extends CoMap {
3
+ value: co<string>;
4
+ }
5
+ declare class AccountSchema extends Account {
6
+ root: co<AccountRoot | null>;
7
+ migrate(): void;
8
+ }
9
+ declare module "../provider" {
10
+ interface Register {
11
+ Account: AccountSchema;
12
+ }
13
+ }
1
14
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jazz-vue",
3
- "version": "0.11.8",
3
+ "version": "0.12.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -16,9 +16,9 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "jazz-browser": "0.11.8",
20
- "jazz-tools": "0.11.8",
21
- "cojson": "0.11.8"
19
+ "cojson": "0.12.1",
20
+ "jazz-browser": "0.12.1",
21
+ "jazz-tools": "0.12.1"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@scure/bip39": "^1.3.0",
@@ -5,12 +5,13 @@ import {
5
5
  AuthSecretStorage,
6
6
  CoValue,
7
7
  CoValueClass,
8
- DeeplyLoaded,
9
- DepthsIn,
10
8
  ID,
11
9
  JazzAuthContext,
12
10
  JazzContextType,
13
11
  JazzGuestContext,
12
+ RefsToResolve,
13
+ RefsToResolveStrict,
14
+ Resolved,
14
15
  subscribeToCoValue,
15
16
  } from "jazz-tools";
16
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -37,7 +38,10 @@ import {
37
38
 
38
39
  export const logoutHandler = ref<() => void>();
39
40
 
40
- export function useJazzContext() {
41
+ export function useJazzContext(): Ref<
42
+ JazzContextType<RegisteredAccount>,
43
+ JazzContextType<RegisteredAccount>
44
+ > {
41
45
  const context =
42
46
  inject<Ref<JazzContextType<RegisteredAccount>>>(JazzContextSymbol);
43
47
  if (!context?.value) {
@@ -54,121 +58,125 @@ export function useAuthSecretStorage() {
54
58
  return context;
55
59
  }
56
60
 
57
- export function createUseAccountComposables<Acc extends Account>() {
58
- function useAccount(): {
59
- me: ComputedRef<Acc>;
60
- logOut: () => void;
61
- };
62
- function useAccount<D extends DepthsIn<Acc>>(
63
- depth: D,
64
- ): {
65
- me: ComputedRef<DeeplyLoaded<Acc, D> | undefined | null>;
66
- logOut: () => void;
67
- };
68
- function useAccount<D extends DepthsIn<Acc>>(
69
- depth?: D,
70
- ): {
71
- me: ComputedRef<Acc | DeeplyLoaded<Acc, D> | undefined | null>;
72
- logOut: () => void;
73
- } {
74
- const context = useJazzContext();
75
-
76
- if (!context.value) {
77
- throw new Error("useAccount must be used within a JazzProvider");
78
- }
79
-
80
- if (!("me" in context.value)) {
81
- throw new Error(
82
- "useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()",
83
- );
84
- }
61
+ export function useAccount(): {
62
+ me: ComputedRef<RegisteredAccount>;
63
+ logOut: () => void;
64
+ };
65
+ export function useAccount<
66
+ const R extends RefsToResolve<RegisteredAccount>,
67
+ >(options?: {
68
+ resolve?: RefsToResolveStrict<RegisteredAccount, R>;
69
+ }): {
70
+ me: ComputedRef<Resolved<RegisteredAccount, R> | undefined | null>;
71
+ logOut: () => void;
72
+ };
73
+ export function useAccount<
74
+ const R extends RefsToResolve<RegisteredAccount>,
75
+ >(options?: {
76
+ resolve?: RefsToResolveStrict<RegisteredAccount, R>;
77
+ }): {
78
+ me: ComputedRef<
79
+ RegisteredAccount | Resolved<RegisteredAccount, R> | undefined | null
80
+ >;
81
+ logOut: () => void;
82
+ } {
83
+ const context = useJazzContext();
85
84
 
86
- const contextMe = context.value.me as Acc;
85
+ if (!context.value) {
86
+ throw new Error("useAccount must be used within a JazzProvider");
87
+ }
87
88
 
88
- const me = useCoState<Acc, D>(
89
- contextMe.constructor as CoValueClass<Acc>,
90
- contextMe.id,
91
- depth,
89
+ if (!("me" in context.value)) {
90
+ throw new Error(
91
+ "useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()",
92
92
  );
93
-
94
- return {
95
- me: computed(() => {
96
- const value =
97
- depth === undefined
98
- ? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)
99
- : me.value;
100
-
101
- return value ? toRaw(value) : value;
102
- }),
103
- logOut: context.value.logOut,
104
- };
105
93
  }
106
94
 
107
- function useAccountOrGuest(): {
108
- me: ComputedRef<Acc | AnonymousJazzAgent>;
109
- };
110
- function useAccountOrGuest<D extends DepthsIn<Acc>>(
111
- depth: D,
112
- ): {
113
- me: ComputedRef<
114
- DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent
115
- >;
116
- };
117
- function useAccountOrGuest<D extends DepthsIn<Acc>>(
118
- depth?: D,
119
- ): {
120
- me: ComputedRef<
121
- Acc | DeeplyLoaded<Acc, D> | undefined | null | AnonymousJazzAgent
122
- >;
123
- } {
124
- const context = useJazzContext();
95
+ const contextMe = context.value.me as RegisteredAccount;
125
96
 
126
- if (!context.value) {
127
- throw new Error("useAccountOrGuest must be used within a JazzProvider");
128
- }
97
+ const me = useCoState<RegisteredAccount, R>(
98
+ contextMe.constructor as CoValueClass<RegisteredAccount>,
99
+ contextMe.id,
100
+ options,
101
+ );
129
102
 
130
- const contextMe = computed(() =>
131
- "me" in context.value ? (context.value.me as Acc) : undefined,
132
- );
103
+ return {
104
+ me: computed(() => {
105
+ const value =
106
+ options?.resolve === undefined
107
+ ? me.value ||
108
+ toRaw((context.value as JazzAuthContext<RegisteredAccount>).me)
109
+ : me.value;
110
+
111
+ return value ? toRaw(value) : value;
112
+ }),
113
+ logOut: context.value.logOut,
114
+ };
115
+ }
133
116
 
134
- const me = useCoState<Acc, D>(
135
- contextMe.value?.constructor as CoValueClass<Acc>,
136
- contextMe.value?.id,
137
- depth,
138
- );
117
+ export function useAccountOrGuest(): {
118
+ me: ComputedRef<RegisteredAccount | AnonymousJazzAgent>;
119
+ };
120
+ export function useAccountOrGuest<
121
+ const R extends RefsToResolve<RegisteredAccount>,
122
+ >(options?: {
123
+ resolve?: RefsToResolveStrict<RegisteredAccount, R>;
124
+ }): {
125
+ me: ComputedRef<
126
+ Resolved<RegisteredAccount, R> | undefined | null | AnonymousJazzAgent
127
+ >;
128
+ };
129
+ export function useAccountOrGuest<
130
+ const R extends RefsToResolve<RegisteredAccount>,
131
+ >(options?: {
132
+ resolve?: RefsToResolveStrict<RegisteredAccount, R>;
133
+ }): {
134
+ me: ComputedRef<
135
+ | RegisteredAccount
136
+ | Resolved<RegisteredAccount, R>
137
+ | undefined
138
+ | null
139
+ | AnonymousJazzAgent
140
+ >;
141
+ } {
142
+ const context = useJazzContext();
139
143
 
140
- if ("me" in context.value) {
141
- return {
142
- me: computed(() =>
143
- depth === undefined
144
- ? me.value || toRaw((context.value as JazzAuthContext<Acc>).me)
145
- : me.value,
146
- ),
147
- };
148
- } else {
149
- return {
150
- me: computed(() => toRaw((context.value as JazzGuestContext).guest)),
151
- };
152
- }
144
+ if (!context.value) {
145
+ throw new Error("useAccountOrGuest must be used within a JazzProvider");
153
146
  }
154
147
 
155
- return {
156
- useAccount,
157
- useAccountOrGuest,
158
- };
159
- }
148
+ const contextMe = computed(() =>
149
+ "me" in context.value ? (context.value.me as RegisteredAccount) : undefined,
150
+ );
160
151
 
161
- const { useAccount, useAccountOrGuest } =
162
- createUseAccountComposables<RegisteredAccount>();
152
+ const me = useCoState<RegisteredAccount, R>(
153
+ contextMe.value?.constructor as CoValueClass<RegisteredAccount>,
154
+ contextMe.value?.id,
155
+ options,
156
+ );
163
157
 
164
- export { useAccount, useAccountOrGuest };
158
+ if ("me" in context.value) {
159
+ return {
160
+ me: computed(() =>
161
+ options?.resolve === undefined
162
+ ? me.value ||
163
+ toRaw((context.value as JazzAuthContext<RegisteredAccount>).me)
164
+ : me.value,
165
+ ),
166
+ };
167
+ } else {
168
+ return {
169
+ me: computed(() => toRaw((context.value as JazzGuestContext).guest)),
170
+ };
171
+ }
172
+ }
165
173
 
166
- export function useCoState<V extends CoValue, D>(
174
+ export function useCoState<V extends CoValue, const R extends RefsToResolve<V>>(
167
175
  Schema: CoValueClass<V>,
168
176
  id: MaybeRef<ID<CoValue> | undefined>,
169
- depth: D & DepthsIn<V> = [] as D & DepthsIn<V>,
170
- ): Ref<DeeplyLoaded<V, D> | undefined | null> {
171
- const state: ShallowRef<DeeplyLoaded<V, D> | undefined | null> =
177
+ options?: { resolve?: RefsToResolveStrict<V, R> },
178
+ ): Ref<Resolved<V, R> | undefined | null> {
179
+ const state: ShallowRef<Resolved<V, R> | undefined | null> =
172
180
  shallowRef(undefined);
173
181
  const context = useJazzContext();
174
182
 
@@ -179,7 +187,7 @@ export function useCoState<V extends CoValue, D>(
179
187
  let unsubscribe: (() => void) | undefined;
180
188
 
181
189
  watch(
182
- [() => unref(id), () => context, () => Schema, () => depth],
190
+ [() => unref(id), () => context, () => Schema, () => options],
183
191
  () => {
184
192
  if (unsubscribe) unsubscribe();
185
193
 
@@ -189,17 +197,23 @@ export function useCoState<V extends CoValue, D>(
189
197
  unsubscribe = subscribeToCoValue(
190
198
  Schema,
191
199
  idValue,
192
- "me" in context.value
193
- ? toRaw(context.value.me)
194
- : toRaw(context.value.guest),
195
- depth,
200
+ {
201
+ resolve: options?.resolve,
202
+ loadAs:
203
+ "me" in context.value
204
+ ? toRaw(context.value.me)
205
+ : toRaw(context.value.guest),
206
+ onUnavailable: () => {
207
+ state.value = null;
208
+ },
209
+ onUnauthorized: () => {
210
+ state.value = null;
211
+ },
212
+ syncResolution: true,
213
+ },
196
214
  (value) => {
197
215
  state.value = value;
198
216
  },
199
- () => {
200
- state.value = null;
201
- },
202
- true,
203
217
  );
204
218
  },
205
219
  { deep: true, immediate: true },
@@ -15,7 +15,7 @@ describe("useAcceptInvite", () => {
15
15
  const account = await createJazzTestAccount();
16
16
  const inviteSender = await createJazzTestAccount();
17
17
 
18
- linkAccounts(account, inviteSender);
18
+ await linkAccounts(account, inviteSender);
19
19
 
20
20
  let acceptedId: ID<TestMap> | undefined;
21
21
 
@@ -46,7 +46,9 @@ describe("useAcceptInvite", () => {
46
46
  expect(acceptedId).toBeDefined();
47
47
  });
48
48
 
49
- const accepted = await TestMap.load(acceptedId!, account, {});
49
+ const accepted = await TestMap.load(acceptedId!, {
50
+ loadAs: account,
51
+ });
50
52
 
51
53
  expect(accepted?.value).toEqual("hello");
52
54
  });