community-jazz-vue 0.17.13 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +40 -0
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Image.vue +3 -2
- package/src/composables.ts +5 -1
- package/src/tests/proxyBehavior.test.ts +34 -27
- package/src/tests/useAccount.test.ts +3 -6
- package/src/tests/useCoState.test.ts +21 -12
- package/src/tests/useInboxSender.test.ts +5 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> community-jazz-vue@0.
|
|
2
|
+
> community-jazz-vue@0.18.0 build /home/runner/_work/jazz/jazz/packages/community-jazz-vue
|
|
3
3
|
> pnpm typecheck && rm -rf ./dist && vite build
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> community-jazz-vue@0.
|
|
6
|
+
> community-jazz-vue@0.18.0 typecheck /home/runner/_work/jazz/jazz/packages/community-jazz-vue
|
|
7
7
|
> vue-tsc --noEmit
|
|
8
8
|
|
|
9
9
|
[36mvite v6.3.5 [32mbuilding for production...[36m[39m
|
|
@@ -15,7 +15,7 @@ rendering chunks...
|
|
|
15
15
|
computing gzip size...
|
|
16
16
|
[2mdist/[22m[36mtesting.js [39m[1m[2m 1.28 kB[22m[1m[22m[2m │ gzip: 0.54 kB[22m[2m │ map: 1.84 kB[22m
|
|
17
17
|
[2mdist/[22m[36mprovider-CCZVJj45.js [39m[1m[2m 4.15 kB[22m[1m[22m[2m │ gzip: 1.25 kB[22m[2m │ map: 7.94 kB[22m
|
|
18
|
-
[2mdist/[22m[36mindex.js [39m[1m[2m19.
|
|
19
|
-
[vite:dts] Declaration files built in
|
|
18
|
+
[2mdist/[22m[36mindex.js [39m[1m[2m19.88 kB[22m[1m[22m[2m │ gzip: 4.96 kB[22m[2m │ map: 35.13 kB[22m
|
|
19
|
+
[vite:dts] Declaration files built in 2292ms.
|
|
20
20
|
|
|
21
|
-
[32m✓ built in 2.
|
|
21
|
+
[32m✓ built in 2.42s[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# jazz-react
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f263856: Add `$jazz` field to CoValues:
|
|
8
|
+
- This field contains Jazz methods that cluttered CoValues' API, as well as Jazz internal properties. This field is not enumerable, to allow CoValues to behave similarly to JSON objects.
|
|
9
|
+
- Added a `$jazz.set` method to update a CoValue's fields. When updating collaborative fields, you can pass in JSON objects instead of CoValues and Jazz will create
|
|
10
|
+
the CoValues automatically (similarly to CoValue `create` methods).
|
|
11
|
+
- All CoMap methods have been moved into `$jazz`, to allow defining any arbitrary key in the CoMap (except for `$jazz`) without conflicts.
|
|
12
|
+
- For CoMaps created with `co.map`, fields are now `readonly` to prevent setting properties directly. Use the `$jazz.set` method instead.
|
|
13
|
+
- CoMaps created with class schemas don't get type errors on direct property assignments, but they get a runtime errors prompting indicating to use `$jazz.set`.
|
|
14
|
+
- the `delete` operator can no longer be used to delete CoRecord properties. Use `$jazz.delete` instead.
|
|
15
|
+
- CoList's array-mutation methods have been moved into `$jazz`, in order to prevent using methods
|
|
16
|
+
- CoLists are now readonly arrays. Trying to use any mutation method yields a type error.
|
|
17
|
+
- `$jazz.set` can be used in place of direct element assignments.
|
|
18
|
+
- Added two new utility methods: `$jazz.remove` and `$jazz.retain`. They allow editing a CoList in-place with a simpler API than `$jazz.splice`.
|
|
19
|
+
- `sort`, `reverse`, `fill` and `copyWithin` have been deprecated, given that they could behave inconsistently with CoLists. `$jazz` replacements may be introduced
|
|
20
|
+
in future releases.
|
|
21
|
+
- `.$jazz.owner` now always returns a Group (instead of a Group or an Account). We'll be migrating away of having Accounts as CoValue owners in future releases.
|
|
22
|
+
- Removed `castAs`, since it's an inherently unsafe operation that bypassed typechecking and enabled using CoValues in unsupported ways.
|
|
23
|
+
- Removed the `id` and `_type` fields from `toJSON()`'s output in Account, CoMap, CoFeed & FileStream, to make CoValues behave more similarly to JSON objects.
|
|
24
|
+
- Removed the `root` and `profile` fields from Group.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [b709494]
|
|
29
|
+
- Updated dependencies [f263856]
|
|
30
|
+
- cojson@0.18.0
|
|
31
|
+
- jazz-tools@0.18.0
|
|
32
|
+
|
|
33
|
+
## 0.17.14
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- Updated dependencies [1094b7c]
|
|
38
|
+
- Updated dependencies [6378ad5]
|
|
39
|
+
- Updated dependencies [cc2f774]
|
|
40
|
+
- cojson@0.17.14
|
|
41
|
+
- jazz-tools@0.17.14
|
|
42
|
+
|
|
3
43
|
## 0.17.13
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,11 @@ function useAccount(AccountSchema = Account, options) {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
const contextMe = context.value.me;
|
|
57
|
-
const me = useCoState(
|
|
57
|
+
const me = useCoState(
|
|
58
|
+
AccountSchema,
|
|
59
|
+
toRaw(contextMe).$jazz.id,
|
|
60
|
+
options
|
|
61
|
+
);
|
|
58
62
|
return {
|
|
59
63
|
me: computed(() => {
|
|
60
64
|
const value = (options == null ? void 0 : options.resolve) === void 0 ? me.value || contextMe : me.value;
|
|
@@ -600,12 +604,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
600
604
|
dimensions.value.height || dimensions.value.width || 9999
|
|
601
605
|
);
|
|
602
606
|
if (!bestImage) return image.value.placeholderDataURL;
|
|
603
|
-
if ((lastBestImage == null ? void 0 : lastBestImage[0]) === bestImage.image.id)
|
|
607
|
+
if ((lastBestImage == null ? void 0 : lastBestImage[0]) === bestImage.image.$jazz.id)
|
|
608
|
+
return lastBestImage == null ? void 0 : lastBestImage[1];
|
|
604
609
|
const blob = bestImage.image.toBlob();
|
|
605
610
|
if (blob) {
|
|
606
611
|
const url = URL.createObjectURL(blob);
|
|
607
612
|
revokeObjectURL(lastBestImage == null ? void 0 : lastBestImage[1]);
|
|
608
|
-
lastBestImage = [bestImage.image.id, url];
|
|
613
|
+
lastBestImage = [bestImage.image.$jazz.id, url];
|
|
609
614
|
return url;
|
|
610
615
|
}
|
|
611
616
|
return image.value.placeholderDataURL;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/composables.ts","../src/auth/useIsAuthenticated.ts","../src/auth/usePassphraseAuth.ts","../src/auth/usePasskeyAuth.ts","../src/auth/useClerkAuth.ts","../src/auth/JazzVueProviderWithClerk.ts","../src/auth/PasskeyAuthBasicUI.vue","../src/Image.vue"],"sourcesContent":["import {\n Account,\n AccountClass,\n AnonymousJazzAgent,\n AnyAccountSchema,\n type AuthSecretStorage,\n type CoValue,\n CoValueClassOrSchema,\n InboxSender,\n InstanceOfSchema,\n type JazzAuthContext,\n JazzContextManager,\n type JazzContextType,\n type Loaded,\n type RefsToResolve,\n ResolveQuery,\n ResolveQueryStrict,\n coValueClassFromCoValueClassOrSchema,\n subscribeToCoValue,\n} from \"jazz-tools\";\nimport { consumeInviteLinkFromWindowLocation } from \"jazz-tools/browser\";\nimport {\n type ComputedRef,\n type Ref,\n type ShallowRef,\n computed,\n inject,\n markRaw,\n nextTick,\n onMounted,\n onUnmounted,\n ref,\n shallowRef,\n toRaw,\n watch,\n} from \"vue\";\n\nimport {\n JazzAuthContextSymbol,\n JazzContextManagerSymbol,\n JazzContextSymbol,\n} from \"./provider.js\";\n\nexport const logoutHandler = ref<() => void>();\n\nfunction getCurrentAccountFromContextManager<Acc extends Account>(\n contextManager: JazzContextManager<Acc, any>,\n) {\n const context = contextManager.getCurrentValue();\n\n if (!context) {\n throw new Error(\"No context found\");\n }\n\n return \"me\" in context ? context.me : context.guest;\n}\n\nexport function useJazzContext<Acc extends Account>(): Ref<\n JazzContextType<Acc>,\n JazzContextType<Acc>\n> {\n const context = inject<Ref<JazzContextType<Acc>>>(JazzContextSymbol);\n if (!context) {\n throw new Error(\"useJazzContext must be used within a JazzProvider\");\n }\n return context;\n}\n\nexport function useJazzContextManager<Acc extends Account>() {\n const context = inject<Ref<JazzContextManager<Acc, {}>>>(\n JazzContextManagerSymbol,\n );\n\n if (!context?.value) {\n throw new Error(\n \"You need to set up a JazzProvider on top of your app to use this hook.\",\n );\n }\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 A extends AccountClass<Account> | AnyAccountSchema = typeof Account,\n R extends ResolveQuery<A> = true,\n>(\n AccountSchema: A = Account as unknown as A,\n options?: {\n resolve?: ResolveQueryStrict<A, R>;\n },\n): {\n me: ComputedRef<Loaded<A, R> | undefined | null>;\n agent: AnonymousJazzAgent | Loaded<A, true>;\n logOut: () => void;\n} {\n const context = useJazzContext();\n const contextManager = useJazzContextManager<InstanceOfSchema<A>>();\n\n if (!context.value) {\n throw new Error(\"useAccount must be used within a JazzProvider\");\n }\n\n const agent = getCurrentAccountFromContextManager(contextManager.value);\n\n // Handle guest mode - return null for me and the guest agent\n if (!(\"me\" in context.value)) {\n return {\n me: computed(() => null) as any,\n agent: agent,\n logOut: context.value.logOut,\n };\n }\n\n const contextMe = context.value.me as InstanceOfSchema<A>;\n\n const me = useCoState(AccountSchema as any, contextMe.id, options as any);\n\n return {\n me: computed(() => {\n const value =\n options?.resolve === undefined ? me.value || contextMe : me.value;\n return value ? markRaw(value) : value;\n }) as any,\n agent: agent,\n logOut: context.value.logOut,\n };\n}\n\nexport function useCoState<\n S extends CoValueClassOrSchema,\n const R extends RefsToResolve<S> = true,\n>(\n Schema: S,\n id: string | undefined,\n options?: { resolve?: ResolveQueryStrict<S, R> },\n): Ref<Loaded<S, R> | undefined | null> {\n const state: ShallowRef<Loaded<S, 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 [() => id, context],\n ([currentId, currentContext]) => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = undefined;\n }\n\n if (!currentId || !currentContext) {\n state.value = undefined;\n return;\n }\n\n const loadAsAgent =\n \"me\" in currentContext ? currentContext.me : currentContext.guest;\n if (!loadAsAgent) {\n state.value = undefined;\n return;\n }\n\n const safeLoadAsAgent = toRaw(loadAsAgent);\n\n try {\n unsubscribe = subscribeToCoValue(\n coValueClassFromCoValueClassOrSchema(Schema),\n currentId as any,\n {\n resolve: options?.resolve as any,\n loadAs: safeLoadAsAgent,\n onUnavailable: () => {\n state.value = null;\n },\n onUnauthorized: () => {\n state.value = null;\n },\n syncResolution: true,\n },\n (value: any) => {\n // Use markRaw to prevent Vue from making Jazz objects reactive\n // but still allow property access and mutations\n state.value = value ? markRaw(value) : value;\n },\n );\n } catch (error) {\n console.error(\"Error in useCoState subscription:\", error);\n state.value = null;\n }\n },\n { immediate: true },\n );\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = undefined;\n }\n });\n\n return state;\n}\n\nexport function useAcceptInvite<S extends CoValueClassOrSchema>({\n invitedObjectSchema,\n onAccept,\n forValueHint,\n}: {\n invitedObjectSchema: S;\n onAccept: (projectID: string) => 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 handleInvite = () => {\n const result = consumeInviteLinkFromWindowLocation({\n as: toRaw((context.value as JazzAuthContext<Account>).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 handleInvite();\n window.addEventListener(\"hashchange\", handleInvite);\n });\n\n onUnmounted(() => {\n window.removeEventListener(\"hashchange\", handleInvite);\n });\n\n watch(\n () => onAccept,\n (newOnAccept, oldOnAccept) => {\n if (newOnAccept !== oldOnAccept) {\n handleInvite();\n }\n },\n );\n}\n\nexport function experimental_useInboxSender<\n I extends CoValue,\n O extends CoValue | undefined,\n>(inboxOwnerID: string | undefined) {\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\n \"experimental_useInboxSender must be used within a JazzProvider\",\n );\n }\n\n if (!(\"me\" in context.value)) {\n throw new Error(\n \"experimental_useInboxSender can't be used in a JazzProvider with auth === 'guest'.\",\n );\n }\n\n const me = computed(() => (context.value as JazzAuthContext<Account>).me);\n const inboxRef = ref<Promise<InboxSender<I, O>> | undefined>(undefined);\n\n const sendMessage = async (message: I) => {\n if (!inboxOwnerID) throw new Error(\"Inbox owner ID is required\");\n\n if (!inboxRef.value) {\n const inbox = InboxSender.load<I, O>(inboxOwnerID, toRaw(me.value));\n inboxRef.value = inbox;\n }\n\n let inbox = await inboxRef.value;\n\n if (inbox.owner.id !== inboxOwnerID) {\n const req = InboxSender.load<I, O>(inboxOwnerID, toRaw(me.value));\n inboxRef.value = req;\n inbox = await req;\n }\n\n return inbox.sendMessage(message);\n };\n\n watch(\n () => inboxOwnerID,\n () => {\n inboxRef.value = undefined;\n },\n );\n\n return sendMessage;\n}\n\n// useAccountOrGuest has been removed in v0.15.4 to match React library.\n// It has been merged into useAccount which now handles both authenticated and guest scenarios.\n// This change maintains 1:1 API compatibility with the React Jazz library.\n// If you were using useAccountOrGuest, please migrate to useAccount.\n","import { 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 = (newIsAuthenticated: boolean) => {\n isAuthenticated.value = newIsAuthenticated;\n };\n\n // Set up the listener immediately, not waiting for onMounted\n // This ensures we catch auth state changes that happen before mounting\n const cleanup = authSecretStorage.onUpdate(handleUpdate);\n\n onUnmounted(() => {\n cleanup();\n });\n\n return isAuthenticated;\n}\n","import { PassphraseAuth } from \"jazz-tools\";\nimport { computed, markRaw, 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({ wordlist }: { wordlist: string[] }) {\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 markRaw(\n new PassphraseAuth(\n context.value.node.crypto,\n context.value.authenticate,\n context.value.register,\n authSecretStorage,\n wordlist,\n ),\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-tools/browser\";\nimport { computed, markRaw } 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 markRaw(\n new BrowserPasskeyAuth(\n context.value.node.crypto,\n context.value.authenticate,\n authSecretStorage,\n appName,\n appHostname,\n ),\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","import { JazzClerkAuth, type MinimalClerkClient } from \"jazz-tools\";\nimport { computed, markRaw, onMounted, onUnmounted } from \"vue\";\nimport { useAuthSecretStorage, useJazzContext } from \"../composables.js\";\n\nexport function useClerkAuth(clerk: MinimalClerkClient) {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n\n if (\"guest\" in context.value) {\n throw new Error(\"Clerk auth is not supported in guest mode\");\n }\n\n // Create auth method similar to React's useMemo pattern\n const authMethod = computed(() => {\n return markRaw(\n new JazzClerkAuth(\n context.value.authenticate,\n context.value.logOut,\n authSecretStorage,\n ),\n );\n });\n\n onMounted(() => {\n const cleanup = authMethod.value.registerListener(clerk) as\n | (() => void)\n | void;\n\n onUnmounted(() => {\n // Clerk's addListener returns a cleanup function, but the type says void\n // Handle both cases for type safety\n if (typeof cleanup === \"function\") {\n cleanup();\n }\n });\n });\n\n return authMethod.value;\n}\n","import type {\n Account,\n AccountClass,\n AnyAccountSchema,\n CoValueFromRaw,\n SyncConfig,\n} from \"jazz-tools\";\nimport {\n InMemoryKVStore,\n JazzClerkAuth,\n KvStoreContext,\n type MinimalClerkClient,\n} from \"jazz-tools\";\nimport { LocalStorageKVStore } from \"jazz-tools/browser\";\nimport { type PropType, defineComponent, h, onMounted, ref } from \"vue\";\nimport { JazzVueProvider } from \"../provider.js\";\nimport { useClerkAuth } from \"./useClerkAuth.js\";\n\nfunction setupKvStore() {\n KvStoreContext.getInstance().initialize(\n typeof window === \"undefined\"\n ? new InMemoryKVStore()\n : new LocalStorageKVStore(),\n );\n}\n\nconst RegisterClerkAuth = defineComponent({\n name: \"RegisterClerkAuth\",\n props: {\n clerk: {\n type: Object as PropType<MinimalClerkClient>,\n required: true,\n },\n },\n setup(props, { slots }) {\n useClerkAuth(props.clerk);\n return () => slots.default?.();\n },\n});\n\nexport const JazzVueProviderWithClerk = defineComponent({\n name: \"JazzVueProviderWithClerk\",\n props: {\n clerk: {\n type: Object as PropType<MinimalClerkClient>,\n required: true,\n },\n AccountSchema: {\n type: Function as unknown as PropType<\n (AccountClass<Account> & CoValueFromRaw<Account>) | AnyAccountSchema\n >,\n required: false,\n },\n guestMode: {\n type: Boolean,\n default: false,\n },\n sync: {\n type: Object as PropType<SyncConfig>,\n required: true,\n },\n storage: {\n type: String as PropType<\"indexedDB\">,\n default: undefined,\n },\n defaultProfileName: {\n type: String,\n required: false,\n },\n onLogOut: {\n type: Function as PropType<() => void>,\n required: false,\n },\n onAnonymousAccountDiscarded: {\n type: Function as PropType<(anonymousAccount: any) => Promise<void>>,\n required: false,\n },\n enableSSR: {\n type: Boolean,\n default: false,\n },\n },\n setup(props, { slots }) {\n const isLoaded = ref(false);\n\n onMounted(async () => {\n try {\n setupKvStore();\n await JazzClerkAuth.initializeAuth(props.clerk);\n isLoaded.value = true;\n } catch (error) {\n console.error(\"Jazz + Clerk initialization error:\", error);\n // Still render even if auth init fails\n isLoaded.value = true;\n }\n });\n\n return () => {\n if (!isLoaded.value) {\n return null;\n }\n\n // Destructure props to exclude 'clerk' which JazzVueProvider doesn't accept\n const { clerk, ...jazzProviderProps } = props;\n\n return h(\n JazzVueProvider,\n {\n ...jazzProviderProps,\n logOutReplacement: clerk.signOut,\n },\n {\n default: () =>\n h(\n RegisterClerkAuth,\n { clerk },\n { default: () => slots.default?.() },\n ),\n },\n );\n };\n },\n});\n","<template>\n <div v-if=\"auth.state === 'signedIn'\">\n <slot />\n </div>\n <div v-else :style=\"containerStyle\">\n <div :style=\"cardStyle\">\n <h1 :style=\"headingStyle\">{{ appName }}</h1>\n \n <div v-if=\"error\" :style=\"errorStyle\">\n {{ error }}\n </div>\n\n <form @submit.prevent=\"handleSignUp\" :style=\"formStyle\">\n <input\n v-model=\"username\"\n type=\"text\"\n placeholder=\"Display name\"\n autocomplete=\"name\"\n :style=\"inputStyle\"\n />\n <button type=\"submit\" :style=\"primaryButtonStyle\">\n Sign up\n </button>\n </form>\n\n <button @click=\"handleLogIn\" :style=\"secondaryButtonStyle\">\n Log in with existing account\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { usePasskeyAuth } from \"./usePasskeyAuth.js\";\n\ninterface Props {\n appName: string;\n appHostname?: string;\n}\n\nconst props = defineProps<Props>();\n\nconst username = ref(\"\");\nconst error = ref<string | null>(null);\n\nconst auth = usePasskeyAuth({\n appName: props.appName,\n appHostname: props.appHostname,\n});\n\nfunction handleError(err: Error) {\n if (err.cause instanceof Error) {\n error.value = err.cause.message;\n } else {\n error.value = err.message;\n }\n}\n\nconst handleSignUp = async () => {\n if (!username.value.trim()) {\n error.value = \"Name is required\";\n return;\n }\n\n error.value = null;\n try {\n await auth.value.signUp(username.value.trim());\n } catch (err) {\n handleError(err as Error);\n }\n};\n\nconst handleLogIn = async () => {\n error.value = null;\n try {\n await auth.value.logIn();\n } catch (err) {\n handleError(err as Error);\n }\n};\n\n// Styles (matching React version)\nconst containerStyle = {\n width: \"100vw\",\n height: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f3f4f6\",\n padding: \"1rem\",\n};\n\nconst cardStyle = {\n backgroundColor: \"white\",\n padding: \"2rem\",\n borderRadius: \"0.5rem\",\n boxShadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1)\",\n width: \"100%\",\n maxWidth: \"18rem\",\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: \"2rem\",\n};\n\nconst headingStyle = {\n fontSize: \"1.5rem\",\n fontWeight: \"bold\",\n textAlign: \"center\" as const,\n margin: \"0\",\n};\n\nconst errorStyle = {\n color: \"red\",\n fontSize: \"0.875rem\",\n textAlign: \"center\" as const,\n};\n\nconst formStyle = {\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: \"0.5rem\",\n};\n\nconst inputStyle = {\n padding: \"0.75rem\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"0.375rem\",\n fontSize: \"1rem\",\n};\n\nconst primaryButtonStyle = {\n backgroundColor: \"#3b82f6\",\n color: \"white\",\n padding: \"0.75rem 1rem\",\n border: \"none\",\n borderRadius: \"0.375rem\",\n cursor: \"pointer\",\n fontSize: \"1rem\",\n fontWeight: \"500\",\n};\n\nconst secondaryButtonStyle = {\n backgroundColor: \"#e5e7eb\",\n color: \"#374151\",\n padding: \"0.75rem 1rem\",\n border: \"none\",\n borderRadius: \"0.375rem\",\n cursor: \"pointer\",\n fontSize: \"1rem\",\n fontWeight: \"500\",\n};\n</script>\n","<script setup lang=\"ts\">\nimport { ImageDefinition } from \"jazz-tools\";\nimport { highestResAvailable } from \"jazz-tools/media\";\nimport { onUnmounted, ref, watch, computed } from \"vue\";\nimport { useCoState } from \"./composables.js\";\n\nexport interface ImageProps {\n /** The ID of the ImageDefinition to display */\n imageId: string;\n /**\n * The desired width of the image. Can be a number in pixels or \"original\" to use the image's original width.\n * When set to a number, the component will select the best available resolution and maintain aspect ratio.\n */\n width?: number | \"original\";\n /**\n * The desired height of the image. Can be a number in pixels or \"original\" to use the image's original height.\n * When set to a number, the component will select the best available resolution and maintain aspect ratio.\n */\n height?: number | \"original\";\n /** Alt text for the image */\n alt?: string;\n /** CSS classes to apply to the image */\n classNames?: string;\n /** CSS styles to apply to the image */\n style?: string | Record<string, string>;\n /** Loading strategy for the image */\n loading?: \"lazy\" | \"eager\";\n}\n\nconst props = withDefaults(defineProps<ImageProps>(), {\n loading: \"eager\",\n});\n\nconst image = useCoState(ImageDefinition, props.imageId, {});\nlet lastBestImage: [string, string] | null = null;\n\n/**\n * For lazy loading, we use the browser's strategy for images with loading=\"lazy\".\n * We use an empty image, and when the browser triggers the load event, we load the best available image.\n */\nconst waitingLazyLoading = ref(props.loading === \"lazy\");\nconst lazyPlaceholder = computed(() =>\n waitingLazyLoading.value ? URL.createObjectURL(emptyPixelBlob) : undefined,\n);\n\nconst dimensions = computed(() => {\n const originalWidth = image.value?.originalSize?.[0];\n const originalHeight = image.value?.originalSize?.[1];\n\n // Both width and height are \"original\"\n if (props.width === \"original\" && props.height === \"original\") {\n return { width: originalWidth, height: originalHeight };\n }\n\n // Width is \"original\", height is a number\n if (props.width === \"original\" && typeof props.height === \"number\") {\n if (originalWidth && originalHeight) {\n return {\n width: Math.round((props.height * originalWidth) / originalHeight),\n height: props.height,\n };\n }\n return { width: undefined, height: props.height };\n }\n\n // Height is \"original\", width is a number\n if (props.height === \"original\" && typeof props.width === \"number\") {\n if (originalWidth && originalHeight) {\n return {\n width: props.width,\n height: Math.round((props.width * originalHeight) / originalWidth),\n };\n }\n return { width: props.width, height: undefined };\n }\n\n // In all other cases, use the property value:\n return {\n width: props.width === \"original\" ? originalWidth : props.width,\n height: props.height === \"original\" ? originalHeight : props.height,\n };\n});\n\nconst src = computed(() => {\n if (waitingLazyLoading.value) {\n return lazyPlaceholder.value;\n }\n\n if (!image.value) return undefined;\n\n const bestImage = highestResAvailable(\n image.value,\n dimensions.value.width || dimensions.value.height || 9999,\n dimensions.value.height || dimensions.value.width || 9999,\n );\n\n if (!bestImage) return image.value.placeholderDataURL;\n if (lastBestImage?.[0] === bestImage.image.id) return lastBestImage?.[1];\n\n const blob = bestImage.image.toBlob();\n\n if (blob) {\n const url = URL.createObjectURL(blob);\n revokeObjectURL(lastBestImage?.[1]);\n lastBestImage = [bestImage.image.id, url];\n return url;\n }\n\n return image.value.placeholderDataURL;\n});\n\nconst onThresholdReached = () => {\n waitingLazyLoading.value = false;\n};\n\n// Cleanup object URL on component destroy\nonUnmounted(() => {\n revokeObjectURL(lastBestImage?.[1]);\n});\n\nfunction revokeObjectURL(url: string | undefined) {\n if (url && url.startsWith(\"blob:\")) {\n URL.revokeObjectURL(url);\n }\n}\n\nconst emptyPixelBlob = new Blob(\n [\n Uint8Array.from(\n atob(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==\",\n ),\n (c) => c.charCodeAt(0),\n ),\n ],\n { type: \"image/png\" },\n);\n</script>\n\n<template>\n <img\n :src=\"src\"\n :width=\"dimensions.width\"\n :height=\"dimensions.height\"\n :alt=\"alt\"\n :class=\"classNames\"\n :style=\"style\"\n :loading=\"loading\"\n @load=\"waitingLazyLoading ? onThresholdReached() : undefined\"\n />\n</template>\n"],"names":["inbox"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/composables.ts","../src/auth/useIsAuthenticated.ts","../src/auth/usePassphraseAuth.ts","../src/auth/usePasskeyAuth.ts","../src/auth/useClerkAuth.ts","../src/auth/JazzVueProviderWithClerk.ts","../src/auth/PasskeyAuthBasicUI.vue","../src/Image.vue"],"sourcesContent":["import {\n Account,\n AccountClass,\n AnonymousJazzAgent,\n AnyAccountSchema,\n type AuthSecretStorage,\n type CoValue,\n CoValueClassOrSchema,\n InboxSender,\n InstanceOfSchema,\n type JazzAuthContext,\n JazzContextManager,\n type JazzContextType,\n type Loaded,\n type RefsToResolve,\n ResolveQuery,\n ResolveQueryStrict,\n coValueClassFromCoValueClassOrSchema,\n subscribeToCoValue,\n} from \"jazz-tools\";\nimport { consumeInviteLinkFromWindowLocation } from \"jazz-tools/browser\";\nimport {\n type ComputedRef,\n type Ref,\n type ShallowRef,\n computed,\n inject,\n markRaw,\n nextTick,\n onMounted,\n onUnmounted,\n ref,\n shallowRef,\n toRaw,\n watch,\n} from \"vue\";\n\nimport {\n JazzAuthContextSymbol,\n JazzContextManagerSymbol,\n JazzContextSymbol,\n} from \"./provider.js\";\n\nexport const logoutHandler = ref<() => void>();\n\nfunction getCurrentAccountFromContextManager<Acc extends Account>(\n contextManager: JazzContextManager<Acc, any>,\n) {\n const context = contextManager.getCurrentValue();\n\n if (!context) {\n throw new Error(\"No context found\");\n }\n\n return \"me\" in context ? context.me : context.guest;\n}\n\nexport function useJazzContext<Acc extends Account>(): Ref<\n JazzContextType<Acc>,\n JazzContextType<Acc>\n> {\n const context = inject<Ref<JazzContextType<Acc>>>(JazzContextSymbol);\n if (!context) {\n throw new Error(\"useJazzContext must be used within a JazzProvider\");\n }\n return context;\n}\n\nexport function useJazzContextManager<Acc extends Account>() {\n const context = inject<Ref<JazzContextManager<Acc, {}>>>(\n JazzContextManagerSymbol,\n );\n\n if (!context?.value) {\n throw new Error(\n \"You need to set up a JazzProvider on top of your app to use this hook.\",\n );\n }\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 A extends AccountClass<Account> | AnyAccountSchema = typeof Account,\n R extends ResolveQuery<A> = true,\n>(\n AccountSchema: A = Account as unknown as A,\n options?: {\n resolve?: ResolveQueryStrict<A, R>;\n },\n): {\n me: ComputedRef<Loaded<A, R> | undefined | null>;\n agent: AnonymousJazzAgent | Loaded<A, true>;\n logOut: () => void;\n} {\n const context = useJazzContext();\n const contextManager = useJazzContextManager<InstanceOfSchema<A>>();\n\n if (!context.value) {\n throw new Error(\"useAccount must be used within a JazzProvider\");\n }\n\n const agent = getCurrentAccountFromContextManager(contextManager.value);\n\n // Handle guest mode - return null for me and the guest agent\n if (!(\"me\" in context.value)) {\n return {\n me: computed(() => null) as any,\n agent: agent,\n logOut: context.value.logOut,\n };\n }\n\n const contextMe = context.value.me as InstanceOfSchema<A>;\n\n const me = useCoState(\n AccountSchema as any,\n toRaw(contextMe).$jazz.id,\n options as any,\n );\n\n return {\n me: computed(() => {\n const value =\n options?.resolve === undefined ? me.value || contextMe : me.value;\n return value ? markRaw(value) : value;\n }) as any,\n agent: agent,\n logOut: context.value.logOut,\n };\n}\n\nexport function useCoState<\n S extends CoValueClassOrSchema,\n const R extends RefsToResolve<S> = true,\n>(\n Schema: S,\n id: string | undefined,\n options?: { resolve?: ResolveQueryStrict<S, R> },\n): Ref<Loaded<S, R> | undefined | null> {\n const state: ShallowRef<Loaded<S, 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 [() => id, context],\n ([currentId, currentContext]) => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = undefined;\n }\n\n if (!currentId || !currentContext) {\n state.value = undefined;\n return;\n }\n\n const loadAsAgent =\n \"me\" in currentContext ? currentContext.me : currentContext.guest;\n if (!loadAsAgent) {\n state.value = undefined;\n return;\n }\n\n const safeLoadAsAgent = toRaw(loadAsAgent);\n\n try {\n unsubscribe = subscribeToCoValue(\n coValueClassFromCoValueClassOrSchema(Schema),\n currentId as any,\n {\n resolve: options?.resolve as any,\n loadAs: safeLoadAsAgent,\n onUnavailable: () => {\n state.value = null;\n },\n onUnauthorized: () => {\n state.value = null;\n },\n syncResolution: true,\n },\n (value: any) => {\n // Use markRaw to prevent Vue from making Jazz objects reactive\n // but still allow property access and mutations\n state.value = value ? markRaw(value) : value;\n },\n );\n } catch (error) {\n console.error(\"Error in useCoState subscription:\", error);\n state.value = null;\n }\n },\n { immediate: true },\n );\n\n onUnmounted(() => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = undefined;\n }\n });\n\n return state;\n}\n\nexport function useAcceptInvite<S extends CoValueClassOrSchema>({\n invitedObjectSchema,\n onAccept,\n forValueHint,\n}: {\n invitedObjectSchema: S;\n onAccept: (projectID: string) => 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 handleInvite = () => {\n const result = consumeInviteLinkFromWindowLocation({\n as: toRaw((context.value as JazzAuthContext<Account>).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 handleInvite();\n window.addEventListener(\"hashchange\", handleInvite);\n });\n\n onUnmounted(() => {\n window.removeEventListener(\"hashchange\", handleInvite);\n });\n\n watch(\n () => onAccept,\n (newOnAccept, oldOnAccept) => {\n if (newOnAccept !== oldOnAccept) {\n handleInvite();\n }\n },\n );\n}\n\nexport function experimental_useInboxSender<\n I extends CoValue,\n O extends CoValue | undefined,\n>(inboxOwnerID: string | undefined) {\n const context = useJazzContext();\n\n if (!context.value) {\n throw new Error(\n \"experimental_useInboxSender must be used within a JazzProvider\",\n );\n }\n\n if (!(\"me\" in context.value)) {\n throw new Error(\n \"experimental_useInboxSender can't be used in a JazzProvider with auth === 'guest'.\",\n );\n }\n\n const me = computed(() => (context.value as JazzAuthContext<Account>).me);\n const inboxRef = ref<Promise<InboxSender<I, O>> | undefined>(undefined);\n\n const sendMessage = async (message: I) => {\n if (!inboxOwnerID) throw new Error(\"Inbox owner ID is required\");\n\n if (!inboxRef.value) {\n const inbox = InboxSender.load<I, O>(inboxOwnerID, toRaw(me.value));\n inboxRef.value = inbox;\n }\n\n let inbox = await inboxRef.value;\n\n if (inbox.owner.id !== inboxOwnerID) {\n const req = InboxSender.load<I, O>(inboxOwnerID, toRaw(me.value));\n inboxRef.value = req;\n inbox = await req;\n }\n\n return inbox.sendMessage(message);\n };\n\n watch(\n () => inboxOwnerID,\n () => {\n inboxRef.value = undefined;\n },\n );\n\n return sendMessage;\n}\n\n// useAccountOrGuest has been removed in v0.15.4 to match React library.\n// It has been merged into useAccount which now handles both authenticated and guest scenarios.\n// This change maintains 1:1 API compatibility with the React Jazz library.\n// If you were using useAccountOrGuest, please migrate to useAccount.\n","import { 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 = (newIsAuthenticated: boolean) => {\n isAuthenticated.value = newIsAuthenticated;\n };\n\n // Set up the listener immediately, not waiting for onMounted\n // This ensures we catch auth state changes that happen before mounting\n const cleanup = authSecretStorage.onUpdate(handleUpdate);\n\n onUnmounted(() => {\n cleanup();\n });\n\n return isAuthenticated;\n}\n","import { PassphraseAuth } from \"jazz-tools\";\nimport { computed, markRaw, 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({ wordlist }: { wordlist: string[] }) {\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 markRaw(\n new PassphraseAuth(\n context.value.node.crypto,\n context.value.authenticate,\n context.value.register,\n authSecretStorage,\n wordlist,\n ),\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-tools/browser\";\nimport { computed, markRaw } 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 markRaw(\n new BrowserPasskeyAuth(\n context.value.node.crypto,\n context.value.authenticate,\n authSecretStorage,\n appName,\n appHostname,\n ),\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","import { JazzClerkAuth, type MinimalClerkClient } from \"jazz-tools\";\nimport { computed, markRaw, onMounted, onUnmounted } from \"vue\";\nimport { useAuthSecretStorage, useJazzContext } from \"../composables.js\";\n\nexport function useClerkAuth(clerk: MinimalClerkClient) {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n\n if (\"guest\" in context.value) {\n throw new Error(\"Clerk auth is not supported in guest mode\");\n }\n\n // Create auth method similar to React's useMemo pattern\n const authMethod = computed(() => {\n return markRaw(\n new JazzClerkAuth(\n context.value.authenticate,\n context.value.logOut,\n authSecretStorage,\n ),\n );\n });\n\n onMounted(() => {\n const cleanup = authMethod.value.registerListener(clerk) as\n | (() => void)\n | void;\n\n onUnmounted(() => {\n // Clerk's addListener returns a cleanup function, but the type says void\n // Handle both cases for type safety\n if (typeof cleanup === \"function\") {\n cleanup();\n }\n });\n });\n\n return authMethod.value;\n}\n","import type {\n Account,\n AccountClass,\n AnyAccountSchema,\n CoValueFromRaw,\n SyncConfig,\n} from \"jazz-tools\";\nimport {\n InMemoryKVStore,\n JazzClerkAuth,\n KvStoreContext,\n type MinimalClerkClient,\n} from \"jazz-tools\";\nimport { LocalStorageKVStore } from \"jazz-tools/browser\";\nimport { type PropType, defineComponent, h, onMounted, ref } from \"vue\";\nimport { JazzVueProvider } from \"../provider.js\";\nimport { useClerkAuth } from \"./useClerkAuth.js\";\n\nfunction setupKvStore() {\n KvStoreContext.getInstance().initialize(\n typeof window === \"undefined\"\n ? new InMemoryKVStore()\n : new LocalStorageKVStore(),\n );\n}\n\nconst RegisterClerkAuth = defineComponent({\n name: \"RegisterClerkAuth\",\n props: {\n clerk: {\n type: Object as PropType<MinimalClerkClient>,\n required: true,\n },\n },\n setup(props, { slots }) {\n useClerkAuth(props.clerk);\n return () => slots.default?.();\n },\n});\n\nexport const JazzVueProviderWithClerk = defineComponent({\n name: \"JazzVueProviderWithClerk\",\n props: {\n clerk: {\n type: Object as PropType<MinimalClerkClient>,\n required: true,\n },\n AccountSchema: {\n type: Function as unknown as PropType<\n (AccountClass<Account> & CoValueFromRaw<Account>) | AnyAccountSchema\n >,\n required: false,\n },\n guestMode: {\n type: Boolean,\n default: false,\n },\n sync: {\n type: Object as PropType<SyncConfig>,\n required: true,\n },\n storage: {\n type: String as PropType<\"indexedDB\">,\n default: undefined,\n },\n defaultProfileName: {\n type: String,\n required: false,\n },\n onLogOut: {\n type: Function as PropType<() => void>,\n required: false,\n },\n onAnonymousAccountDiscarded: {\n type: Function as PropType<(anonymousAccount: any) => Promise<void>>,\n required: false,\n },\n enableSSR: {\n type: Boolean,\n default: false,\n },\n },\n setup(props, { slots }) {\n const isLoaded = ref(false);\n\n onMounted(async () => {\n try {\n setupKvStore();\n await JazzClerkAuth.initializeAuth(props.clerk);\n isLoaded.value = true;\n } catch (error) {\n console.error(\"Jazz + Clerk initialization error:\", error);\n // Still render even if auth init fails\n isLoaded.value = true;\n }\n });\n\n return () => {\n if (!isLoaded.value) {\n return null;\n }\n\n // Destructure props to exclude 'clerk' which JazzVueProvider doesn't accept\n const { clerk, ...jazzProviderProps } = props;\n\n return h(\n JazzVueProvider,\n {\n ...jazzProviderProps,\n logOutReplacement: clerk.signOut,\n },\n {\n default: () =>\n h(\n RegisterClerkAuth,\n { clerk },\n { default: () => slots.default?.() },\n ),\n },\n );\n };\n },\n});\n","<template>\n <div v-if=\"auth.state === 'signedIn'\">\n <slot />\n </div>\n <div v-else :style=\"containerStyle\">\n <div :style=\"cardStyle\">\n <h1 :style=\"headingStyle\">{{ appName }}</h1>\n \n <div v-if=\"error\" :style=\"errorStyle\">\n {{ error }}\n </div>\n\n <form @submit.prevent=\"handleSignUp\" :style=\"formStyle\">\n <input\n v-model=\"username\"\n type=\"text\"\n placeholder=\"Display name\"\n autocomplete=\"name\"\n :style=\"inputStyle\"\n />\n <button type=\"submit\" :style=\"primaryButtonStyle\">\n Sign up\n </button>\n </form>\n\n <button @click=\"handleLogIn\" :style=\"secondaryButtonStyle\">\n Log in with existing account\n </button>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { usePasskeyAuth } from \"./usePasskeyAuth.js\";\n\ninterface Props {\n appName: string;\n appHostname?: string;\n}\n\nconst props = defineProps<Props>();\n\nconst username = ref(\"\");\nconst error = ref<string | null>(null);\n\nconst auth = usePasskeyAuth({\n appName: props.appName,\n appHostname: props.appHostname,\n});\n\nfunction handleError(err: Error) {\n if (err.cause instanceof Error) {\n error.value = err.cause.message;\n } else {\n error.value = err.message;\n }\n}\n\nconst handleSignUp = async () => {\n if (!username.value.trim()) {\n error.value = \"Name is required\";\n return;\n }\n\n error.value = null;\n try {\n await auth.value.signUp(username.value.trim());\n } catch (err) {\n handleError(err as Error);\n }\n};\n\nconst handleLogIn = async () => {\n error.value = null;\n try {\n await auth.value.logIn();\n } catch (err) {\n handleError(err as Error);\n }\n};\n\n// Styles (matching React version)\nconst containerStyle = {\n width: \"100vw\",\n height: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f3f4f6\",\n padding: \"1rem\",\n};\n\nconst cardStyle = {\n backgroundColor: \"white\",\n padding: \"2rem\",\n borderRadius: \"0.5rem\",\n boxShadow: \"0 10px 15px -3px rgba(0, 0, 0, 0.1)\",\n width: \"100%\",\n maxWidth: \"18rem\",\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: \"2rem\",\n};\n\nconst headingStyle = {\n fontSize: \"1.5rem\",\n fontWeight: \"bold\",\n textAlign: \"center\" as const,\n margin: \"0\",\n};\n\nconst errorStyle = {\n color: \"red\",\n fontSize: \"0.875rem\",\n textAlign: \"center\" as const,\n};\n\nconst formStyle = {\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: \"0.5rem\",\n};\n\nconst inputStyle = {\n padding: \"0.75rem\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"0.375rem\",\n fontSize: \"1rem\",\n};\n\nconst primaryButtonStyle = {\n backgroundColor: \"#3b82f6\",\n color: \"white\",\n padding: \"0.75rem 1rem\",\n border: \"none\",\n borderRadius: \"0.375rem\",\n cursor: \"pointer\",\n fontSize: \"1rem\",\n fontWeight: \"500\",\n};\n\nconst secondaryButtonStyle = {\n backgroundColor: \"#e5e7eb\",\n color: \"#374151\",\n padding: \"0.75rem 1rem\",\n border: \"none\",\n borderRadius: \"0.375rem\",\n cursor: \"pointer\",\n fontSize: \"1rem\",\n fontWeight: \"500\",\n};\n</script>\n","<script setup lang=\"ts\">\nimport { ImageDefinition } from \"jazz-tools\";\nimport { highestResAvailable } from \"jazz-tools/media\";\nimport { onUnmounted, ref, watch, computed } from \"vue\";\nimport { useCoState } from \"./composables.js\";\n\nexport interface ImageProps {\n /** The ID of the ImageDefinition to display */\n imageId: string;\n /**\n * The desired width of the image. Can be a number in pixels or \"original\" to use the image's original width.\n * When set to a number, the component will select the best available resolution and maintain aspect ratio.\n */\n width?: number | \"original\";\n /**\n * The desired height of the image. Can be a number in pixels or \"original\" to use the image's original height.\n * When set to a number, the component will select the best available resolution and maintain aspect ratio.\n */\n height?: number | \"original\";\n /** Alt text for the image */\n alt?: string;\n /** CSS classes to apply to the image */\n classNames?: string;\n /** CSS styles to apply to the image */\n style?: string | Record<string, string>;\n /** Loading strategy for the image */\n loading?: \"lazy\" | \"eager\";\n}\n\nconst props = withDefaults(defineProps<ImageProps>(), {\n loading: \"eager\",\n});\n\nconst image = useCoState(ImageDefinition, props.imageId, {});\nlet lastBestImage: [string, string] | null = null;\n\n/**\n * For lazy loading, we use the browser's strategy for images with loading=\"lazy\".\n * We use an empty image, and when the browser triggers the load event, we load the best available image.\n */\nconst waitingLazyLoading = ref(props.loading === \"lazy\");\nconst lazyPlaceholder = computed(() =>\n waitingLazyLoading.value ? URL.createObjectURL(emptyPixelBlob) : undefined,\n);\n\nconst dimensions = computed(() => {\n const originalWidth = image.value?.originalSize?.[0];\n const originalHeight = image.value?.originalSize?.[1];\n\n // Both width and height are \"original\"\n if (props.width === \"original\" && props.height === \"original\") {\n return { width: originalWidth, height: originalHeight };\n }\n\n // Width is \"original\", height is a number\n if (props.width === \"original\" && typeof props.height === \"number\") {\n if (originalWidth && originalHeight) {\n return {\n width: Math.round((props.height * originalWidth) / originalHeight),\n height: props.height,\n };\n }\n return { width: undefined, height: props.height };\n }\n\n // Height is \"original\", width is a number\n if (props.height === \"original\" && typeof props.width === \"number\") {\n if (originalWidth && originalHeight) {\n return {\n width: props.width,\n height: Math.round((props.width * originalHeight) / originalWidth),\n };\n }\n return { width: props.width, height: undefined };\n }\n\n // In all other cases, use the property value:\n return {\n width: props.width === \"original\" ? originalWidth : props.width,\n height: props.height === \"original\" ? originalHeight : props.height,\n };\n});\n\nconst src = computed(() => {\n if (waitingLazyLoading.value) {\n return lazyPlaceholder.value;\n }\n\n if (!image.value) return undefined;\n\n const bestImage = highestResAvailable(\n image.value,\n dimensions.value.width || dimensions.value.height || 9999,\n dimensions.value.height || dimensions.value.width || 9999,\n );\n\n if (!bestImage) return image.value.placeholderDataURL;\n if (lastBestImage?.[0] === bestImage.image.$jazz.id)\n return lastBestImage?.[1];\n\n const blob = bestImage.image.toBlob();\n\n if (blob) {\n const url = URL.createObjectURL(blob);\n revokeObjectURL(lastBestImage?.[1]);\n lastBestImage = [bestImage.image.$jazz.id, url];\n return url;\n }\n\n return image.value.placeholderDataURL;\n});\n\nconst onThresholdReached = () => {\n waitingLazyLoading.value = false;\n};\n\n// Cleanup object URL on component destroy\nonUnmounted(() => {\n revokeObjectURL(lastBestImage?.[1]);\n});\n\nfunction revokeObjectURL(url: string | undefined) {\n if (url && url.startsWith(\"blob:\")) {\n URL.revokeObjectURL(url);\n }\n}\n\nconst emptyPixelBlob = new Blob(\n [\n Uint8Array.from(\n atob(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==\",\n ),\n (c) => c.charCodeAt(0),\n ),\n ],\n { type: \"image/png\" },\n);\n</script>\n\n<template>\n <img\n :src=\"src\"\n :width=\"dimensions.width\"\n :height=\"dimensions.height\"\n :alt=\"alt\"\n :class=\"classNames\"\n :style=\"style\"\n :loading=\"loading\"\n @load=\"waitingLazyLoading ? onThresholdReached() : undefined\"\n />\n</template>\n"],"names":["inbox"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "community-jazz-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"cojson": "0.
|
|
28
|
-
"jazz-tools": "0.
|
|
27
|
+
"cojson": "0.18.0",
|
|
28
|
+
"jazz-tools": "0.18.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@babel/plugin-syntax-jsx": "^7.25.0",
|
package/src/Image.vue
CHANGED
|
@@ -95,14 +95,15 @@ const src = computed(() => {
|
|
|
95
95
|
);
|
|
96
96
|
|
|
97
97
|
if (!bestImage) return image.value.placeholderDataURL;
|
|
98
|
-
if (lastBestImage?.[0] === bestImage.image.id)
|
|
98
|
+
if (lastBestImage?.[0] === bestImage.image.$jazz.id)
|
|
99
|
+
return lastBestImage?.[1];
|
|
99
100
|
|
|
100
101
|
const blob = bestImage.image.toBlob();
|
|
101
102
|
|
|
102
103
|
if (blob) {
|
|
103
104
|
const url = URL.createObjectURL(blob);
|
|
104
105
|
revokeObjectURL(lastBestImage?.[1]);
|
|
105
|
-
lastBestImage = [bestImage.image.id, url];
|
|
106
|
+
lastBestImage = [bestImage.image.$jazz.id, url];
|
|
106
107
|
return url;
|
|
107
108
|
}
|
|
108
109
|
|
package/src/composables.ts
CHANGED
|
@@ -121,7 +121,11 @@ export function useAccount<
|
|
|
121
121
|
|
|
122
122
|
const contextMe = context.value.me as InstanceOfSchema<A>;
|
|
123
123
|
|
|
124
|
-
const me = useCoState(
|
|
124
|
+
const me = useCoState(
|
|
125
|
+
AccountSchema as any,
|
|
126
|
+
toRaw(contextMe).$jazz.id,
|
|
127
|
+
options as any,
|
|
128
|
+
);
|
|
125
129
|
|
|
126
130
|
return {
|
|
127
131
|
me: computed(() => {
|
|
@@ -30,15 +30,10 @@ const AccountSchema = co
|
|
|
30
30
|
})
|
|
31
31
|
.withMigration((account) => {
|
|
32
32
|
if (!account.root) {
|
|
33
|
-
account.root
|
|
33
|
+
account.$jazz.set("root", { value: "test" });
|
|
34
34
|
}
|
|
35
35
|
if (!account.profile) {
|
|
36
|
-
|
|
37
|
-
const group = Group.create();
|
|
38
|
-
account.profile = AccountProfile.create(
|
|
39
|
-
{ name: "Test User" },
|
|
40
|
-
{ owner: group },
|
|
41
|
-
);
|
|
36
|
+
account.$jazz.set("profile", { name: "Test User" });
|
|
42
37
|
}
|
|
43
38
|
});
|
|
44
39
|
|
|
@@ -64,9 +59,12 @@ describe("Proxy Behavior Verification", () => {
|
|
|
64
59
|
{ owner: sharedAccount },
|
|
65
60
|
);
|
|
66
61
|
|
|
67
|
-
const [result] = withJazzTestSetup(
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
const [result] = withJazzTestSetup(
|
|
63
|
+
() => useCoState(TestMap, testMap.$jazz.id),
|
|
64
|
+
{
|
|
65
|
+
account: sharedAccount,
|
|
66
|
+
},
|
|
67
|
+
);
|
|
70
68
|
|
|
71
69
|
// The returned value should not be a Vue proxy
|
|
72
70
|
expect(isProxy(result.value)).toBe(false);
|
|
@@ -94,7 +92,7 @@ describe("Proxy Behavior Verification", () => {
|
|
|
94
92
|
);
|
|
95
93
|
|
|
96
94
|
// Update account root
|
|
97
|
-
sharedAccountWithSchema.root
|
|
95
|
+
sharedAccountWithSchema.$jazz.set("root", rootMap);
|
|
98
96
|
|
|
99
97
|
const [accountResult] = withJazzTestSetup(
|
|
100
98
|
() => useAccount(AccountSchema, { resolve: { root: { testMap: true } } }),
|
|
@@ -126,16 +124,19 @@ describe("Proxy Behavior Verification", () => {
|
|
|
126
124
|
{ owner: account },
|
|
127
125
|
);
|
|
128
126
|
|
|
129
|
-
const [result] = withJazzTestSetup(
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
const [result] = withJazzTestSetup(
|
|
128
|
+
() => useCoState(TestMap, testMap.$jazz.id),
|
|
129
|
+
{
|
|
130
|
+
account,
|
|
131
|
+
},
|
|
132
|
+
);
|
|
132
133
|
|
|
133
134
|
// Initial state
|
|
134
135
|
expect(result.value?.content).toBe("initial content");
|
|
135
136
|
expect(isProxy(result.value)).toBe(false);
|
|
136
137
|
|
|
137
138
|
// Update the Jazz object
|
|
138
|
-
testMap.content
|
|
139
|
+
testMap.$jazz.set("content", "updated content");
|
|
139
140
|
await nextTick();
|
|
140
141
|
|
|
141
142
|
// Should reactively update
|
|
@@ -155,9 +156,12 @@ describe("Proxy Behavior Verification", () => {
|
|
|
155
156
|
{ owner: account },
|
|
156
157
|
);
|
|
157
158
|
|
|
158
|
-
const [result] = withJazzTestSetup(
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
const [result] = withJazzTestSetup(
|
|
160
|
+
() => useCoState(TestMap, testMap.$jazz.id),
|
|
161
|
+
{
|
|
162
|
+
account,
|
|
163
|
+
},
|
|
164
|
+
);
|
|
161
165
|
|
|
162
166
|
// User should be able to use the object directly without toRaw()
|
|
163
167
|
const jazzObject = result.value;
|
|
@@ -189,7 +193,7 @@ describe("Proxy Behavior Verification", () => {
|
|
|
189
193
|
|
|
190
194
|
// Should be able to access agent properties without proxy issues
|
|
191
195
|
expect(() => {
|
|
192
|
-
const agentType = result.agent
|
|
196
|
+
const agentType = result.agent.$type$; // Access agent property
|
|
193
197
|
expect(agentType).toBeDefined();
|
|
194
198
|
}).not.toThrow();
|
|
195
199
|
|
|
@@ -211,21 +215,24 @@ describe("Proxy Behavior Verification", () => {
|
|
|
211
215
|
{ owner: account },
|
|
212
216
|
);
|
|
213
217
|
|
|
214
|
-
const [result] = withJazzTestSetup(
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
const [result] = withJazzTestSetup(
|
|
219
|
+
() => useCoState(TestMap, testMap.$jazz.id),
|
|
220
|
+
{
|
|
221
|
+
account,
|
|
222
|
+
},
|
|
223
|
+
);
|
|
217
224
|
|
|
218
225
|
const initialObject = result.value;
|
|
219
|
-
const initialId = initialObject
|
|
226
|
+
const initialId = initialObject?.$jazz.id;
|
|
220
227
|
|
|
221
228
|
// Update content
|
|
222
|
-
testMap.content
|
|
229
|
+
testMap.$jazz.set("content", "updated");
|
|
223
230
|
await nextTick();
|
|
224
231
|
|
|
225
232
|
const updatedObject = result.value;
|
|
226
233
|
|
|
227
234
|
// Object identity should be maintained (same Jazz object)
|
|
228
|
-
expect(updatedObject
|
|
235
|
+
expect(updatedObject?.$jazz.id).toBe(initialId);
|
|
229
236
|
expect(isProxy(updatedObject)).toBe(false);
|
|
230
237
|
});
|
|
231
238
|
|
|
@@ -248,7 +255,7 @@ describe("Proxy Behavior Verification", () => {
|
|
|
248
255
|
);
|
|
249
256
|
|
|
250
257
|
const [projectResult] = withJazzTestSetup(
|
|
251
|
-
() => useCoState(TestMap, newProject.id),
|
|
258
|
+
() => useCoState(TestMap, newProject.$jazz.id),
|
|
252
259
|
{
|
|
253
260
|
account,
|
|
254
261
|
},
|
|
@@ -261,7 +268,7 @@ describe("Proxy Behavior Verification", () => {
|
|
|
261
268
|
expect(isProxy(projectResult.value)).toBe(false);
|
|
262
269
|
|
|
263
270
|
// Should be able to access properties without toRaw()
|
|
264
|
-
expect(accountResult.me.value
|
|
271
|
+
expect(accountResult.me.value?.$jazz.id).toBeDefined();
|
|
265
272
|
expect(projectResult.value?.content).toBe("new project");
|
|
266
273
|
});
|
|
267
274
|
});
|
|
@@ -21,15 +21,12 @@ const AccountSchema = co
|
|
|
21
21
|
})
|
|
22
22
|
.withMigration((account) => {
|
|
23
23
|
if (!account.root) {
|
|
24
|
-
account.root
|
|
24
|
+
account.$jazz.set("root", { value: "123" });
|
|
25
25
|
}
|
|
26
26
|
if (!account.profile) {
|
|
27
27
|
// Profile must be owned by a Group, not the account itself
|
|
28
28
|
const group = Group.create();
|
|
29
|
-
account.profile
|
|
30
|
-
{ name: "Test User" },
|
|
31
|
-
{ owner: group },
|
|
32
|
-
);
|
|
29
|
+
account.$jazz.set("profile", { name: "Test User" });
|
|
33
30
|
}
|
|
34
31
|
});
|
|
35
32
|
|
|
@@ -53,7 +50,7 @@ describe("useAccount", () => {
|
|
|
53
50
|
|
|
54
51
|
// In guest mode, me should be null and agent should be the guest
|
|
55
52
|
expect(result.me.value).toBe(null);
|
|
56
|
-
expect(result.agent
|
|
53
|
+
expect(result.agent.$type$).toBe("Anonymous");
|
|
57
54
|
expect(typeof result.logOut).toBe("function");
|
|
58
55
|
});
|
|
59
56
|
});
|
|
@@ -28,9 +28,12 @@ describe("useCoState", () => {
|
|
|
28
28
|
{ owner: account },
|
|
29
29
|
);
|
|
30
30
|
|
|
31
|
-
const [result] = withJazzTestSetup(
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const [result] = withJazzTestSetup(
|
|
32
|
+
() => useCoState(TestMap, map.$jazz.id, {}),
|
|
33
|
+
{
|
|
34
|
+
account,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
34
37
|
|
|
35
38
|
expect(result.value?.content).toBe("123");
|
|
36
39
|
});
|
|
@@ -49,13 +52,16 @@ describe("useCoState", () => {
|
|
|
49
52
|
{ owner: account },
|
|
50
53
|
);
|
|
51
54
|
|
|
52
|
-
const [result] = withJazzTestSetup(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
const [result] = withJazzTestSetup(
|
|
56
|
+
() => useCoState(TestMap, map.$jazz.id, {}),
|
|
57
|
+
{
|
|
58
|
+
account,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
55
61
|
|
|
56
62
|
expect(result.value?.content).toBe("123");
|
|
57
63
|
|
|
58
|
-
map.content
|
|
64
|
+
map.$jazz.set("content", "456");
|
|
59
65
|
|
|
60
66
|
expect(result.value?.content).toBe("456");
|
|
61
67
|
});
|
|
@@ -87,7 +93,7 @@ describe("useCoState", () => {
|
|
|
87
93
|
|
|
88
94
|
const [result] = withJazzTestSetup(
|
|
89
95
|
() =>
|
|
90
|
-
useCoState(TestMap, map.id, {
|
|
96
|
+
useCoState(TestMap, map.$jazz.id, {
|
|
91
97
|
resolve: {
|
|
92
98
|
nested: true,
|
|
93
99
|
},
|
|
@@ -126,9 +132,12 @@ describe("useCoState", () => {
|
|
|
126
132
|
{ owner: account },
|
|
127
133
|
);
|
|
128
134
|
|
|
129
|
-
const [result] = withJazzTestSetup(
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
const [result] = withJazzTestSetup(
|
|
136
|
+
() => useCoState(TestMap, map.$jazz.id, {}),
|
|
137
|
+
{
|
|
138
|
+
account,
|
|
139
|
+
},
|
|
140
|
+
);
|
|
132
141
|
|
|
133
142
|
expect(result.value?.content).toBe("123");
|
|
134
143
|
expect(result.value?.nested?.content).toBe("456");
|
|
@@ -164,7 +173,7 @@ describe("useCoState", () => {
|
|
|
164
173
|
});
|
|
165
174
|
|
|
166
175
|
const [result] = withJazzTestSetup(() =>
|
|
167
|
-
useCoState(TestMap, map.id as ID<CoValue>, {
|
|
176
|
+
useCoState(TestMap, map.$jazz.id as ID<CoValue>, {
|
|
168
177
|
resolve: true,
|
|
169
178
|
}),
|
|
170
179
|
);
|
|
@@ -22,7 +22,7 @@ describe("useInboxSender", () => {
|
|
|
22
22
|
experimental_useInboxSender<
|
|
23
23
|
Loaded<typeof TestMap>,
|
|
24
24
|
Loaded<typeof TestMap>
|
|
25
|
-
>(inboxReceiver.id),
|
|
25
|
+
>(inboxReceiver.$jazz.id),
|
|
26
26
|
{
|
|
27
27
|
account,
|
|
28
28
|
},
|
|
@@ -43,7 +43,10 @@ describe("useInboxSender", () => {
|
|
|
43
43
|
inbox.subscribe(TestMap, async (message) => {
|
|
44
44
|
resolve(message);
|
|
45
45
|
|
|
46
|
-
return TestMap.create(
|
|
46
|
+
return TestMap.create(
|
|
47
|
+
{ value: "got it" },
|
|
48
|
+
{ owner: message.$jazz.owner },
|
|
49
|
+
);
|
|
47
50
|
});
|
|
48
51
|
});
|
|
49
52
|
|