community-jazz-vue 0.15.4

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.
Files changed (56) hide show
  1. package/.turbo/turbo-build.log +21 -0
  2. package/CHANGELOG.md +2201 -0
  3. package/LICENSE.txt +19 -0
  4. package/README.md +26 -0
  5. package/dist/Image.vue.d.ts +26 -0
  6. package/dist/auth/JazzVueProviderWithClerk.d.ts +83 -0
  7. package/dist/auth/PasskeyAuthBasicUI.vue.d.ts +21 -0
  8. package/dist/auth/useClerkAuth.d.ts +2 -0
  9. package/dist/auth/useIsAuthenticated.d.ts +1 -0
  10. package/dist/auth/usePasskeyAuth.d.ts +18 -0
  11. package/dist/auth/usePassphraseAuth.d.ts +20 -0
  12. package/dist/composables.d.ts +22 -0
  13. package/dist/index.d.ts +11 -0
  14. package/dist/index.js +667 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/provider-CCZVJj45.js +143 -0
  17. package/dist/provider-CCZVJj45.js.map +1 -0
  18. package/dist/provider.d.ts +172 -0
  19. package/dist/testing.d.ts +30 -0
  20. package/dist/testing.js +41 -0
  21. package/dist/testing.js.map +1 -0
  22. package/dist/tests/fixtures.d.ts +1 -0
  23. package/dist/tests/proxyBehavior.test.d.ts +1 -0
  24. package/dist/tests/testUtils.d.ts +9 -0
  25. package/dist/tests/useAcceptInvite.test.d.ts +1 -0
  26. package/dist/tests/useAccount.test.d.ts +1 -0
  27. package/dist/tests/useCoState.test.d.ts +1 -0
  28. package/dist/tests/useInboxSender.test.d.ts +1 -0
  29. package/dist/tests/useIsAuthenticated.test.d.ts +1 -0
  30. package/dist/tests/usePassphraseAuth.test.d.ts +1 -0
  31. package/dist/utils/contextManager.d.ts +3 -0
  32. package/package.json +53 -0
  33. package/src/Image.vue +151 -0
  34. package/src/auth/JazzVueProviderWithClerk.ts +123 -0
  35. package/src/auth/PasskeyAuthBasicUI.vue +153 -0
  36. package/src/auth/useClerkAuth.ts +35 -0
  37. package/src/auth/useIsAuthenticated.ts +21 -0
  38. package/src/auth/usePasskeyAuth.ts +48 -0
  39. package/src/auth/usePassphraseAuth.ts +57 -0
  40. package/src/composables.ts +323 -0
  41. package/src/index.ts +14 -0
  42. package/src/provider.ts +192 -0
  43. package/src/testing.ts +45 -0
  44. package/src/tests/fixtures.ts +2050 -0
  45. package/src/tests/proxyBehavior.test.ts +267 -0
  46. package/src/tests/testUtils.ts +75 -0
  47. package/src/tests/useAcceptInvite.test.ts +55 -0
  48. package/src/tests/useAccount.test.ts +59 -0
  49. package/src/tests/useCoState.test.ts +175 -0
  50. package/src/tests/useInboxSender.test.ts +58 -0
  51. package/src/tests/useIsAuthenticated.test.ts +35 -0
  52. package/src/tests/usePassphraseAuth.test.ts +95 -0
  53. package/src/utils/contextManager.ts +31 -0
  54. package/src/vite-env.d.ts +7 -0
  55. package/tsconfig.json +20 -0
  56. package/vite.config.ts +31 -0
package/dist/index.js ADDED
@@ -0,0 +1,667 @@
1
+ import { Account, subscribeToCoValue, coValueClassFromCoValueClassOrSchema, InboxSender, PassphraseAuth, JazzClerkAuth, KvStoreContext, InMemoryKVStore, ImageDefinition } from "jazz-tools";
2
+ import { consumeInviteLinkFromWindowLocation, BrowserPasskeyAuth, LocalStorageKVStore } from "jazz-tools/browser";
3
+ import { createInviteLink, parseInviteLink } from "jazz-tools/browser";
4
+ import { ref, inject, shallowRef, watch, toRaw, markRaw, onUnmounted, computed, onMounted, watchEffect, defineComponent, h, createElementBlock, unref, openBlock, renderSlot, createElementVNode, createCommentVNode, toDisplayString, withModifiers, withDirectives, vModelText, normalizeStyle, normalizeClass } from "vue";
5
+ import { J as JazzContextSymbol, a as JazzAuthContextSymbol, b as JazzContextManagerSymbol, c as JazzVueProvider } from "./provider-CCZVJj45.js";
6
+ import { d } from "./provider-CCZVJj45.js";
7
+ import { highestResAvailable } from "jazz-tools/media";
8
+ import { createImage } from "jazz-tools/media";
9
+ const logoutHandler = ref();
10
+ function getCurrentAccountFromContextManager(contextManager) {
11
+ const context = contextManager.getCurrentValue();
12
+ if (!context) {
13
+ throw new Error("No context found");
14
+ }
15
+ return "me" in context ? context.me : context.guest;
16
+ }
17
+ function useJazzContext() {
18
+ const context = inject(JazzContextSymbol);
19
+ if (!context) {
20
+ throw new Error("useJazzContext must be used within a JazzProvider");
21
+ }
22
+ return context;
23
+ }
24
+ function useJazzContextManager() {
25
+ const context = inject(
26
+ JazzContextManagerSymbol
27
+ );
28
+ if (!(context == null ? void 0 : context.value)) {
29
+ throw new Error(
30
+ "You need to set up a JazzProvider on top of your app to use this hook."
31
+ );
32
+ }
33
+ return context;
34
+ }
35
+ function useAuthSecretStorage() {
36
+ const context = inject(JazzAuthContextSymbol);
37
+ if (!context) {
38
+ throw new Error("useAuthSecretStorage must be used within a JazzProvider");
39
+ }
40
+ return context;
41
+ }
42
+ function useAccount(AccountSchema = Account, options) {
43
+ const context = useJazzContext();
44
+ const contextManager = useJazzContextManager();
45
+ if (!context.value) {
46
+ throw new Error("useAccount must be used within a JazzProvider");
47
+ }
48
+ const agent = getCurrentAccountFromContextManager(contextManager.value);
49
+ if (!("me" in context.value)) {
50
+ return {
51
+ me: computed(() => null),
52
+ agent,
53
+ logOut: context.value.logOut
54
+ };
55
+ }
56
+ const contextMe = context.value.me;
57
+ const me = useCoState(AccountSchema, contextMe.id, options);
58
+ return {
59
+ me: computed(() => {
60
+ const value = (options == null ? void 0 : options.resolve) === void 0 ? me.value || contextMe : me.value;
61
+ return value ? markRaw(value) : value;
62
+ }),
63
+ agent,
64
+ logOut: context.value.logOut
65
+ };
66
+ }
67
+ function useCoState(Schema, id, options) {
68
+ const state = shallowRef(void 0);
69
+ const context = useJazzContext();
70
+ if (!context.value) {
71
+ throw new Error("useCoState must be used within a JazzProvider");
72
+ }
73
+ let unsubscribe;
74
+ watch(
75
+ [() => id, context],
76
+ ([currentId, currentContext]) => {
77
+ if (unsubscribe) {
78
+ unsubscribe();
79
+ unsubscribe = void 0;
80
+ }
81
+ if (!currentId || !currentContext) {
82
+ state.value = void 0;
83
+ return;
84
+ }
85
+ const loadAsAgent = "me" in currentContext ? currentContext.me : currentContext.guest;
86
+ if (!loadAsAgent) {
87
+ state.value = void 0;
88
+ return;
89
+ }
90
+ const safeLoadAsAgent = toRaw(loadAsAgent);
91
+ try {
92
+ unsubscribe = subscribeToCoValue(
93
+ coValueClassFromCoValueClassOrSchema(Schema),
94
+ currentId,
95
+ {
96
+ resolve: options == null ? void 0 : options.resolve,
97
+ loadAs: safeLoadAsAgent,
98
+ onUnavailable: () => {
99
+ state.value = null;
100
+ },
101
+ onUnauthorized: () => {
102
+ state.value = null;
103
+ },
104
+ syncResolution: true
105
+ },
106
+ (value) => {
107
+ state.value = value ? markRaw(value) : value;
108
+ }
109
+ );
110
+ } catch (error) {
111
+ console.error("Error in useCoState subscription:", error);
112
+ state.value = null;
113
+ }
114
+ },
115
+ { immediate: true }
116
+ );
117
+ onUnmounted(() => {
118
+ if (unsubscribe) {
119
+ unsubscribe();
120
+ unsubscribe = void 0;
121
+ }
122
+ });
123
+ return state;
124
+ }
125
+ function useAcceptInvite({
126
+ invitedObjectSchema,
127
+ onAccept,
128
+ forValueHint
129
+ }) {
130
+ const context = useJazzContext();
131
+ if (!context.value) {
132
+ throw new Error("useAcceptInvite must be used within a JazzProvider");
133
+ }
134
+ if (!("me" in context.value)) {
135
+ throw new Error(
136
+ "useAcceptInvite can't be used in a JazzProvider with auth === 'guest'."
137
+ );
138
+ }
139
+ const handleInvite = () => {
140
+ const result = consumeInviteLinkFromWindowLocation({
141
+ as: toRaw(context.value.me),
142
+ invitedObjectSchema,
143
+ forValueHint
144
+ });
145
+ result.then((res) => res && onAccept(res.valueID)).catch((e) => {
146
+ console.error("Failed to accept invite", e);
147
+ });
148
+ };
149
+ onMounted(() => {
150
+ handleInvite();
151
+ window.addEventListener("hashchange", handleInvite);
152
+ });
153
+ onUnmounted(() => {
154
+ window.removeEventListener("hashchange", handleInvite);
155
+ });
156
+ watch(
157
+ () => onAccept,
158
+ (newOnAccept, oldOnAccept) => {
159
+ if (newOnAccept !== oldOnAccept) {
160
+ handleInvite();
161
+ }
162
+ }
163
+ );
164
+ }
165
+ function experimental_useInboxSender(inboxOwnerID) {
166
+ const context = useJazzContext();
167
+ if (!context.value) {
168
+ throw new Error(
169
+ "experimental_useInboxSender must be used within a JazzProvider"
170
+ );
171
+ }
172
+ if (!("me" in context.value)) {
173
+ throw new Error(
174
+ "experimental_useInboxSender can't be used in a JazzProvider with auth === 'guest'."
175
+ );
176
+ }
177
+ const me = computed(() => context.value.me);
178
+ const inboxRef = ref(void 0);
179
+ const sendMessage = async (message) => {
180
+ if (!inboxOwnerID) throw new Error("Inbox owner ID is required");
181
+ if (!inboxRef.value) {
182
+ const inbox2 = InboxSender.load(inboxOwnerID, toRaw(me.value));
183
+ inboxRef.value = inbox2;
184
+ }
185
+ let inbox = await inboxRef.value;
186
+ if (inbox.owner.id !== inboxOwnerID) {
187
+ const req = InboxSender.load(inboxOwnerID, toRaw(me.value));
188
+ inboxRef.value = req;
189
+ inbox = await req;
190
+ }
191
+ return inbox.sendMessage(message);
192
+ };
193
+ watch(
194
+ () => inboxOwnerID,
195
+ () => {
196
+ inboxRef.value = void 0;
197
+ }
198
+ );
199
+ return sendMessage;
200
+ }
201
+ function useIsAuthenticated() {
202
+ const authSecretStorage = useAuthSecretStorage();
203
+ const isAuthenticated = ref(authSecretStorage.isAuthenticated);
204
+ const handleUpdate = (newIsAuthenticated) => {
205
+ isAuthenticated.value = newIsAuthenticated;
206
+ };
207
+ const cleanup = authSecretStorage.onUpdate(handleUpdate);
208
+ onUnmounted(() => {
209
+ cleanup();
210
+ });
211
+ return isAuthenticated;
212
+ }
213
+ function usePassphraseAuth({ wordlist }) {
214
+ const context = useJazzContext();
215
+ const authSecretStorage = useAuthSecretStorage();
216
+ const isAuthenticated = useIsAuthenticated();
217
+ if ("guest" in context.value) {
218
+ throw new Error("Passphrase auth is not supported in guest mode");
219
+ }
220
+ const authMethod = computed(() => {
221
+ return markRaw(
222
+ new PassphraseAuth(
223
+ context.value.node.crypto,
224
+ context.value.authenticate,
225
+ context.value.register,
226
+ authSecretStorage,
227
+ wordlist
228
+ )
229
+ );
230
+ });
231
+ const passphrase = ref(authMethod.value.passphrase);
232
+ watchEffect((onCleanup) => {
233
+ authMethod.value.loadCurrentAccountPassphrase();
234
+ const unsubscribe = authMethod.value.subscribe(() => {
235
+ passphrase.value = authMethod.value.passphrase;
236
+ });
237
+ onCleanup(unsubscribe);
238
+ });
239
+ return computed(() => ({
240
+ state: isAuthenticated.value ? "signedIn" : "anonymous",
241
+ logIn: authMethod.value.logIn,
242
+ signUp: authMethod.value.signUp,
243
+ registerNewAccount: authMethod.value.registerNewAccount,
244
+ generateRandomPassphrase: authMethod.value.generateRandomPassphrase,
245
+ passphrase: passphrase.value
246
+ }));
247
+ }
248
+ function usePasskeyAuth({
249
+ appName,
250
+ appHostname
251
+ }) {
252
+ const context = useJazzContext();
253
+ const authSecretStorage = useAuthSecretStorage();
254
+ const isAuthenticated = useIsAuthenticated();
255
+ if ("guest" in context.value) {
256
+ throw new Error("Passkey auth is not supported in guest mode");
257
+ }
258
+ const authMethod = computed(() => {
259
+ return markRaw(
260
+ new BrowserPasskeyAuth(
261
+ context.value.node.crypto,
262
+ context.value.authenticate,
263
+ authSecretStorage,
264
+ appName,
265
+ appHostname
266
+ )
267
+ );
268
+ });
269
+ return computed(() => ({
270
+ state: isAuthenticated.value ? "signedIn" : "anonymous",
271
+ logIn: authMethod.value.logIn,
272
+ signUp: authMethod.value.signUp
273
+ }));
274
+ }
275
+ function useClerkAuth(clerk) {
276
+ const context = useJazzContext();
277
+ const authSecretStorage = useAuthSecretStorage();
278
+ if ("guest" in context.value) {
279
+ throw new Error("Clerk auth is not supported in guest mode");
280
+ }
281
+ const authMethod = computed(() => {
282
+ return markRaw(
283
+ new JazzClerkAuth(context.value.authenticate, authSecretStorage)
284
+ );
285
+ });
286
+ onMounted(() => {
287
+ const cleanup = authMethod.value.registerListener(clerk);
288
+ onUnmounted(() => {
289
+ if (typeof cleanup === "function") {
290
+ cleanup();
291
+ }
292
+ });
293
+ });
294
+ return authMethod.value;
295
+ }
296
+ function setupKvStore() {
297
+ KvStoreContext.getInstance().initialize(
298
+ typeof window === "undefined" ? new InMemoryKVStore() : new LocalStorageKVStore()
299
+ );
300
+ }
301
+ const RegisterClerkAuth = defineComponent({
302
+ name: "RegisterClerkAuth",
303
+ props: {
304
+ clerk: {
305
+ type: Object,
306
+ required: true
307
+ }
308
+ },
309
+ setup(props, { slots }) {
310
+ useClerkAuth(props.clerk);
311
+ return () => {
312
+ var _a;
313
+ return (_a = slots.default) == null ? void 0 : _a.call(slots);
314
+ };
315
+ }
316
+ });
317
+ const JazzVueProviderWithClerk = defineComponent({
318
+ name: "JazzVueProviderWithClerk",
319
+ props: {
320
+ clerk: {
321
+ type: Object,
322
+ required: true
323
+ },
324
+ AccountSchema: {
325
+ type: Function,
326
+ required: false
327
+ },
328
+ guestMode: {
329
+ type: Boolean,
330
+ default: false
331
+ },
332
+ sync: {
333
+ type: Object,
334
+ required: true
335
+ },
336
+ storage: {
337
+ type: String,
338
+ default: void 0
339
+ },
340
+ defaultProfileName: {
341
+ type: String,
342
+ required: false
343
+ },
344
+ onLogOut: {
345
+ type: Function,
346
+ required: false
347
+ },
348
+ onAnonymousAccountDiscarded: {
349
+ type: Function,
350
+ required: false
351
+ },
352
+ enableSSR: {
353
+ type: Boolean,
354
+ default: false
355
+ }
356
+ },
357
+ setup(props, { slots }) {
358
+ const isLoaded = ref(false);
359
+ onMounted(async () => {
360
+ try {
361
+ setupKvStore();
362
+ await JazzClerkAuth.initializeAuth(props.clerk);
363
+ isLoaded.value = true;
364
+ } catch (error) {
365
+ console.error("Jazz + Clerk initialization error:", error);
366
+ isLoaded.value = true;
367
+ }
368
+ });
369
+ return () => {
370
+ if (!isLoaded.value) {
371
+ return null;
372
+ }
373
+ const { clerk, ...jazzProviderProps } = props;
374
+ return h(
375
+ JazzVueProvider,
376
+ {
377
+ ...jazzProviderProps,
378
+ logOutReplacement: clerk.signOut
379
+ },
380
+ {
381
+ default: () => h(
382
+ RegisterClerkAuth,
383
+ { clerk },
384
+ { default: () => {
385
+ var _a;
386
+ return (_a = slots.default) == null ? void 0 : _a.call(slots);
387
+ } }
388
+ )
389
+ }
390
+ );
391
+ };
392
+ }
393
+ });
394
+ const _hoisted_1$1 = { key: 0 };
395
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
396
+ __name: "PasskeyAuthBasicUI",
397
+ props: {
398
+ appName: {},
399
+ appHostname: {}
400
+ },
401
+ setup(__props) {
402
+ const props = __props;
403
+ const username = ref("");
404
+ const error = ref(null);
405
+ const auth = usePasskeyAuth({
406
+ appName: props.appName,
407
+ appHostname: props.appHostname
408
+ });
409
+ function handleError(err) {
410
+ if (err.cause instanceof Error) {
411
+ error.value = err.cause.message;
412
+ } else {
413
+ error.value = err.message;
414
+ }
415
+ }
416
+ const handleSignUp = async () => {
417
+ if (!username.value.trim()) {
418
+ error.value = "Name is required";
419
+ return;
420
+ }
421
+ error.value = null;
422
+ try {
423
+ await auth.value.signUp(username.value.trim());
424
+ } catch (err) {
425
+ handleError(err);
426
+ }
427
+ };
428
+ const handleLogIn = async () => {
429
+ error.value = null;
430
+ try {
431
+ await auth.value.logIn();
432
+ } catch (err) {
433
+ handleError(err);
434
+ }
435
+ };
436
+ const containerStyle = {
437
+ width: "100vw",
438
+ height: "100vh",
439
+ display: "flex",
440
+ alignItems: "center",
441
+ justifyContent: "center",
442
+ backgroundColor: "#f3f4f6",
443
+ padding: "1rem"
444
+ };
445
+ const cardStyle = {
446
+ backgroundColor: "white",
447
+ padding: "2rem",
448
+ borderRadius: "0.5rem",
449
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
450
+ width: "100%",
451
+ maxWidth: "18rem",
452
+ display: "flex",
453
+ flexDirection: "column",
454
+ gap: "2rem"
455
+ };
456
+ const headingStyle = {
457
+ fontSize: "1.5rem",
458
+ fontWeight: "bold",
459
+ textAlign: "center",
460
+ margin: "0"
461
+ };
462
+ const errorStyle = {
463
+ color: "red",
464
+ fontSize: "0.875rem",
465
+ textAlign: "center"
466
+ };
467
+ const formStyle = {
468
+ display: "flex",
469
+ flexDirection: "column",
470
+ gap: "0.5rem"
471
+ };
472
+ const inputStyle = {
473
+ padding: "0.75rem",
474
+ border: "1px solid #d1d5db",
475
+ borderRadius: "0.375rem",
476
+ fontSize: "1rem"
477
+ };
478
+ const primaryButtonStyle = {
479
+ backgroundColor: "#3b82f6",
480
+ color: "white",
481
+ padding: "0.75rem 1rem",
482
+ border: "none",
483
+ borderRadius: "0.375rem",
484
+ cursor: "pointer",
485
+ fontSize: "1rem",
486
+ fontWeight: "500"
487
+ };
488
+ const secondaryButtonStyle = {
489
+ backgroundColor: "#e5e7eb",
490
+ color: "#374151",
491
+ padding: "0.75rem 1rem",
492
+ border: "none",
493
+ borderRadius: "0.375rem",
494
+ cursor: "pointer",
495
+ fontSize: "1rem",
496
+ fontWeight: "500"
497
+ };
498
+ return (_ctx, _cache) => {
499
+ return unref(auth).state === "signedIn" ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
500
+ renderSlot(_ctx.$slots, "default")
501
+ ])) : (openBlock(), createElementBlock("div", {
502
+ key: 1,
503
+ style: containerStyle
504
+ }, [
505
+ createElementVNode("div", { style: cardStyle }, [
506
+ createElementVNode("h1", { style: headingStyle }, toDisplayString(_ctx.appName), 1),
507
+ error.value ? (openBlock(), createElementBlock("div", {
508
+ key: 0,
509
+ style: errorStyle
510
+ }, toDisplayString(error.value), 1)) : createCommentVNode("", true),
511
+ createElementVNode("form", {
512
+ onSubmit: withModifiers(handleSignUp, ["prevent"]),
513
+ style: formStyle
514
+ }, [
515
+ withDirectives(createElementVNode("input", {
516
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => username.value = $event),
517
+ type: "text",
518
+ placeholder: "Display name",
519
+ autocomplete: "name",
520
+ style: inputStyle
521
+ }, null, 512), [
522
+ [vModelText, username.value]
523
+ ]),
524
+ createElementVNode("button", {
525
+ type: "submit",
526
+ style: primaryButtonStyle
527
+ }, " Sign up ")
528
+ ], 32),
529
+ createElementVNode("button", {
530
+ onClick: handleLogIn,
531
+ style: secondaryButtonStyle
532
+ }, " Log in with existing account ")
533
+ ])
534
+ ]));
535
+ };
536
+ }
537
+ });
538
+ const _hoisted_1 = ["src", "width", "height", "alt", "loading"];
539
+ const _sfc_main = /* @__PURE__ */ defineComponent({
540
+ __name: "Image",
541
+ props: {
542
+ imageId: {},
543
+ width: {},
544
+ height: {},
545
+ alt: {},
546
+ classNames: {},
547
+ style: {},
548
+ loading: { default: "eager" }
549
+ },
550
+ setup(__props) {
551
+ const props = __props;
552
+ const image = useCoState(ImageDefinition, props.imageId, {});
553
+ let lastBestImage = null;
554
+ const waitingLazyLoading = ref(props.loading === "lazy");
555
+ const lazyPlaceholder = computed(
556
+ () => waitingLazyLoading.value ? URL.createObjectURL(emptyPixelBlob) : void 0
557
+ );
558
+ const dimensions = computed(() => {
559
+ var _a, _b, _c, _d;
560
+ const originalWidth = (_b = (_a = image.value) == null ? void 0 : _a.originalSize) == null ? void 0 : _b[0];
561
+ const originalHeight = (_d = (_c = image.value) == null ? void 0 : _c.originalSize) == null ? void 0 : _d[1];
562
+ if (props.width === "original" && props.height === "original") {
563
+ return { width: originalWidth, height: originalHeight };
564
+ }
565
+ if (props.width === "original" && typeof props.height === "number") {
566
+ if (originalWidth && originalHeight) {
567
+ return {
568
+ width: Math.round(props.height * originalWidth / originalHeight),
569
+ height: props.height
570
+ };
571
+ }
572
+ return { width: void 0, height: props.height };
573
+ }
574
+ if (props.height === "original" && typeof props.width === "number") {
575
+ if (originalWidth && originalHeight) {
576
+ return {
577
+ width: props.width,
578
+ height: Math.round(props.width * originalHeight / originalWidth)
579
+ };
580
+ }
581
+ return { width: props.width, height: void 0 };
582
+ }
583
+ return {
584
+ width: props.width === "original" ? originalWidth : props.width,
585
+ height: props.height === "original" ? originalHeight : props.height
586
+ };
587
+ });
588
+ const src = computed(() => {
589
+ if (waitingLazyLoading.value) {
590
+ return lazyPlaceholder.value;
591
+ }
592
+ if (!image.value) return void 0;
593
+ const bestImage = highestResAvailable(
594
+ image.value,
595
+ dimensions.value.width || dimensions.value.height || 9999,
596
+ dimensions.value.height || dimensions.value.width || 9999
597
+ );
598
+ if (!bestImage) return image.value.placeholderDataURL;
599
+ if ((lastBestImage == null ? void 0 : lastBestImage[0]) === bestImage.image.id) return lastBestImage == null ? void 0 : lastBestImage[1];
600
+ const blob = bestImage.image.toBlob();
601
+ if (blob) {
602
+ const url = URL.createObjectURL(blob);
603
+ revokeObjectURL(lastBestImage == null ? void 0 : lastBestImage[1]);
604
+ lastBestImage = [bestImage.image.id, url];
605
+ return url;
606
+ }
607
+ return image.value.placeholderDataURL;
608
+ });
609
+ const onThresholdReached = () => {
610
+ waitingLazyLoading.value = false;
611
+ };
612
+ onUnmounted(() => {
613
+ revokeObjectURL(lastBestImage == null ? void 0 : lastBestImage[1]);
614
+ });
615
+ function revokeObjectURL(url) {
616
+ if (url && url.startsWith("blob:")) {
617
+ URL.revokeObjectURL(url);
618
+ }
619
+ }
620
+ const emptyPixelBlob = new Blob(
621
+ [
622
+ Uint8Array.from(
623
+ atob(
624
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=="
625
+ ),
626
+ (c) => c.charCodeAt(0)
627
+ )
628
+ ],
629
+ { type: "image/png" }
630
+ );
631
+ return (_ctx, _cache) => {
632
+ return openBlock(), createElementBlock("img", {
633
+ src: src.value,
634
+ width: dimensions.value.width,
635
+ height: dimensions.value.height,
636
+ alt: _ctx.alt,
637
+ class: normalizeClass(_ctx.classNames),
638
+ style: normalizeStyle(_ctx.style),
639
+ loading: _ctx.loading,
640
+ onLoad: _cache[0] || (_cache[0] = ($event) => waitingLazyLoading.value ? onThresholdReached() : void 0)
641
+ }, null, 46, _hoisted_1);
642
+ };
643
+ }
644
+ });
645
+ export {
646
+ _sfc_main as Image,
647
+ d as JazzProvider,
648
+ JazzVueProvider,
649
+ JazzVueProviderWithClerk,
650
+ _sfc_main$1 as PasskeyAuthBasicUI,
651
+ createImage,
652
+ createInviteLink,
653
+ experimental_useInboxSender,
654
+ logoutHandler,
655
+ parseInviteLink,
656
+ useAcceptInvite,
657
+ useAccount,
658
+ useAuthSecretStorage,
659
+ useClerkAuth,
660
+ useCoState,
661
+ useIsAuthenticated,
662
+ useJazzContext,
663
+ useJazzContextManager,
664
+ usePasskeyAuth,
665
+ usePassphraseAuth
666
+ };
667
+ //# sourceMappingURL=index.js.map