jazz-tools 0.19.19 → 0.19.21

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 (127) hide show
  1. package/.svelte-kit/__package__/client.d.ts.map +1 -1
  2. package/.svelte-kit/__package__/client.js +3 -1
  3. package/.svelte-kit/__package__/server.d.ts.map +1 -1
  4. package/.svelte-kit/__package__/server.js +9 -7
  5. package/.svelte-kit/__package__/tests/client.test.js +48 -0
  6. package/.turbo/turbo-build.log +70 -66
  7. package/dist/better-auth/auth/client.d.ts.map +1 -1
  8. package/dist/better-auth/auth/client.js +1 -1
  9. package/dist/better-auth/auth/client.js.map +1 -1
  10. package/dist/better-auth/auth/server.d.ts.map +1 -1
  11. package/dist/better-auth/auth/server.js +4 -4
  12. package/dist/better-auth/auth/server.js.map +1 -1
  13. package/dist/better-auth/database-adapter/index.js.map +1 -1
  14. package/dist/better-auth/database-adapter/repository/generic.d.ts +3 -3
  15. package/dist/better-auth/database-adapter/repository/session.d.ts +2 -2
  16. package/dist/better-auth/database-adapter/schema.d.ts +3 -3
  17. package/dist/better-auth/database-adapter/schema.d.ts.map +1 -1
  18. package/dist/{chunk-PEHQ7TN2.js → chunk-QCTQH5RS.js} +31 -4
  19. package/dist/chunk-QCTQH5RS.js.map +1 -0
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/react/hooks.d.ts +1 -2
  23. package/dist/react/hooks.d.ts.map +1 -1
  24. package/dist/react/index.js +7 -2
  25. package/dist/react/index.js.map +1 -1
  26. package/dist/react-core/hooks.d.ts +94 -3
  27. package/dist/react-core/hooks.d.ts.map +1 -1
  28. package/dist/react-core/index.js +130 -135
  29. package/dist/react-core/index.js.map +1 -1
  30. package/dist/react-core/tests/useCoStates.test.d.ts +2 -0
  31. package/dist/react-core/tests/useCoStates.test.d.ts.map +1 -0
  32. package/dist/react-native/chunk-DGUM43GV.js +11 -0
  33. package/dist/react-native/chunk-DGUM43GV.js.map +1 -0
  34. package/dist/react-native/crypto.js +2 -0
  35. package/dist/react-native/crypto.js.map +1 -1
  36. package/dist/react-native/index.js +544 -29
  37. package/dist/react-native/index.js.map +1 -1
  38. package/dist/react-native-core/auth/PasskeyAuth.d.ts +123 -0
  39. package/dist/react-native-core/auth/PasskeyAuth.d.ts.map +1 -0
  40. package/dist/react-native-core/auth/PasskeyAuthBasicUI.d.ts +34 -0
  41. package/dist/react-native-core/auth/PasskeyAuthBasicUI.d.ts.map +1 -0
  42. package/dist/react-native-core/auth/auth.d.ts +3 -0
  43. package/dist/react-native-core/auth/auth.d.ts.map +1 -1
  44. package/dist/react-native-core/auth/passkey-utils.d.ts +16 -0
  45. package/dist/react-native-core/auth/passkey-utils.d.ts.map +1 -0
  46. package/dist/react-native-core/auth/usePasskeyAuth.d.ts +48 -0
  47. package/dist/react-native-core/auth/usePasskeyAuth.d.ts.map +1 -0
  48. package/dist/react-native-core/chunk-DGUM43GV.js +11 -0
  49. package/dist/react-native-core/chunk-DGUM43GV.js.map +1 -0
  50. package/dist/react-native-core/crypto.js +2 -0
  51. package/dist/react-native-core/crypto.js.map +1 -1
  52. package/dist/react-native-core/hooks.d.ts +1 -1
  53. package/dist/react-native-core/hooks.d.ts.map +1 -1
  54. package/dist/react-native-core/index.js +539 -24
  55. package/dist/react-native-core/index.js.map +1 -1
  56. package/dist/react-native-core/tests/PasskeyAuth.test.d.ts +2 -0
  57. package/dist/react-native-core/tests/PasskeyAuth.test.d.ts.map +1 -0
  58. package/dist/react-native-core/tests/passkey-utils.test.d.ts +2 -0
  59. package/dist/react-native-core/tests/passkey-utils.test.d.ts.map +1 -0
  60. package/dist/svelte/auth/ClerkAuth.svelte.d.ts +38 -0
  61. package/dist/svelte/auth/ClerkAuth.svelte.d.ts.map +1 -0
  62. package/dist/svelte/auth/ClerkAuth.svelte.js +47 -0
  63. package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte +156 -0
  64. package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte.d.ts +67 -0
  65. package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte.d.ts.map +1 -0
  66. package/dist/svelte/auth/RegisterClerkAuth.svelte +27 -0
  67. package/dist/svelte/auth/RegisterClerkAuth.svelte.d.ts +17 -0
  68. package/dist/svelte/auth/RegisterClerkAuth.svelte.d.ts.map +1 -0
  69. package/dist/svelte/auth/index.d.ts +2 -0
  70. package/dist/svelte/auth/index.d.ts.map +1 -1
  71. package/dist/svelte/auth/index.js +2 -0
  72. package/dist/svelte/tests/ClerkAuth.svelte.test.d.ts +2 -0
  73. package/dist/svelte/tests/ClerkAuth.svelte.test.d.ts.map +1 -0
  74. package/dist/svelte/tests/ClerkAuth.svelte.test.js +202 -0
  75. package/dist/svelte/tests/TestClerkAuthWrapper.svelte +16 -0
  76. package/dist/svelte/tests/TestClerkAuthWrapper.svelte.d.ts +8 -0
  77. package/dist/svelte/tests/TestClerkAuthWrapper.svelte.d.ts.map +1 -0
  78. package/dist/svelte/tests/testUtils.d.ts +1 -0
  79. package/dist/svelte/tests/testUtils.d.ts.map +1 -1
  80. package/dist/svelte/tests/testUtils.js +3 -1
  81. package/dist/testing.js +1 -1
  82. package/dist/tools/auth/clerk/index.d.ts +1 -1
  83. package/dist/tools/auth/clerk/types.d.ts +1 -1
  84. package/dist/tools/auth/clerk/types.d.ts.map +1 -1
  85. package/dist/tools/coValues/account.d.ts +5 -1
  86. package/dist/tools/coValues/account.d.ts.map +1 -1
  87. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +30 -1
  88. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  89. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  90. package/dist/tools/subscribe/types.d.ts +1 -1
  91. package/dist/tools/subscribe/types.d.ts.map +1 -1
  92. package/dist/tools/testing.d.ts.map +1 -1
  93. package/package.json +8 -4
  94. package/src/better-auth/auth/client.ts +3 -1
  95. package/src/better-auth/auth/server.ts +9 -7
  96. package/src/better-auth/auth/tests/client.test.ts +66 -2
  97. package/src/better-auth/database-adapter/repository/generic.ts +3 -3
  98. package/src/better-auth/database-adapter/repository/session.ts +2 -2
  99. package/src/better-auth/database-adapter/schema.ts +5 -5
  100. package/src/react/hooks.tsx +4 -2
  101. package/src/react-core/hooks.ts +332 -178
  102. package/src/react-core/tests/useCoState.selector.test.ts +309 -22
  103. package/src/react-core/tests/useCoStates.test.tsx +414 -0
  104. package/src/react-native-core/auth/PasskeyAuth.ts +316 -0
  105. package/src/react-native-core/auth/PasskeyAuthBasicUI.tsx +284 -0
  106. package/src/react-native-core/auth/auth.ts +3 -0
  107. package/src/react-native-core/auth/passkey-utils.ts +47 -0
  108. package/src/react-native-core/auth/usePasskeyAuth.tsx +85 -0
  109. package/src/react-native-core/hooks.tsx +2 -0
  110. package/src/react-native-core/tests/PasskeyAuth.test.ts +463 -0
  111. package/src/react-native-core/tests/passkey-utils.test.ts +144 -0
  112. package/src/svelte/auth/ClerkAuth.svelte.ts +67 -0
  113. package/src/svelte/auth/JazzSvelteProviderWithClerk.svelte +156 -0
  114. package/src/svelte/auth/RegisterClerkAuth.svelte +27 -0
  115. package/src/svelte/auth/index.ts +2 -0
  116. package/src/svelte/tests/ClerkAuth.svelte.test.ts +305 -0
  117. package/src/svelte/tests/TestClerkAuthWrapper.svelte +16 -0
  118. package/src/svelte/tests/testUtils.ts +4 -1
  119. package/src/tools/auth/clerk/types.ts +1 -1
  120. package/src/tools/coValues/account.ts +11 -3
  121. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +27 -1
  122. package/src/tools/subscribe/types.ts +1 -1
  123. package/src/tools/tests/account.test.ts +2 -1
  124. package/src/tools/tests/inbox.test.ts +7 -7
  125. package/testSetup.ts +4 -0
  126. package/vitest.config.ts +1 -0
  127. package/dist/chunk-PEHQ7TN2.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { CoValueClassOrSchema } from "jazz-tools";
2
- export { useCoState, experimental_useInboxSender, useDemoAuth, usePassphraseAuth, useJazzContext, useAuthSecretStorage, useIsAuthenticated, useAccount, useAgent, useLogOut, useSyncConnectionStatus, useCoValueSubscription, useAccountSubscription, useSubscriptionSelector, useSuspenseCoState, useSuspenseAccount, } from "jazz-tools/react-core";
2
+ export { useCoState, useCoStates, experimental_useInboxSender, useDemoAuth, usePassphraseAuth, useJazzContext, useAuthSecretStorage, useIsAuthenticated, useAccount, useAgent, useLogOut, useSyncConnectionStatus, useCoValueSubscription, useAccountSubscription, useSubscriptionSelector, useSuspenseCoState, useSuspenseCoStates, useSuspenseAccount, } from "jazz-tools/react-core";
3
3
  export declare function useAcceptInviteNative<S extends CoValueClassOrSchema>({ invitedObjectSchema, onAccept, forValueHint, }: {
4
4
  invitedObjectSchema: S;
5
5
  onAccept: (projectID: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react-native-core/hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,YAAY,CAAC;AAInE,OAAO,EACL,UAAU,EACV,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,oBAAoB,EAAE,EACpE,mBAAmB,EACnB,QAAQ,EACR,YAAY,GACb,EAAE;IACD,mBAAmB,EAAE,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAsCP"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react-native-core/hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,YAAY,CAAC;AAInE,OAAO,EACL,UAAU,EACV,WAAW,EACX,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,oBAAoB,EAAE,EACpE,mBAAmB,EACnB,QAAQ,EACR,YAAY,GACb,EAAE;IACD,mBAAmB,EAAE,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAsCP"}
@@ -1,3 +1,7 @@
1
+ import {
2
+ __require
3
+ } from "./chunk-DGUM43GV.js";
4
+
1
5
  // src/react-native-core/storage/kv-store-context.ts
2
6
  var KvStoreContext = class _KvStoreContext {
3
7
  constructor() {
@@ -222,6 +226,507 @@ var styles = StyleSheet.create({
222
226
  }
223
227
  });
224
228
 
229
+ // src/react-native-core/auth/PasskeyAuth.ts
230
+ import { cojsonInternals } from "cojson";
231
+ import {
232
+ Account
233
+ } from "jazz-tools";
234
+
235
+ // src/react-native-core/auth/passkey-utils.ts
236
+ function uint8ArrayToBase64Url(bytes) {
237
+ let binary = "";
238
+ for (let i = 0; i < bytes.length; i++) {
239
+ binary += String.fromCharCode(bytes[i]);
240
+ }
241
+ const base64 = btoa(binary);
242
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
243
+ }
244
+ function base64UrlToUint8Array(base64url) {
245
+ let base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
246
+ const padding = base64.length % 4;
247
+ if (padding > 0) {
248
+ base64 += "=".repeat(4 - padding);
249
+ }
250
+ const binary = atob(base64);
251
+ const bytes = new Uint8Array(binary.length);
252
+ for (let i = 0; i < binary.length; i++) {
253
+ bytes[i] = binary.charCodeAt(i);
254
+ }
255
+ return bytes;
256
+ }
257
+
258
+ // src/react-native-core/auth/PasskeyAuth.ts
259
+ var cachedPasskeyModule = null;
260
+ function getPasskeyModule() {
261
+ if (cachedPasskeyModule) {
262
+ return cachedPasskeyModule;
263
+ }
264
+ try {
265
+ const module = __require("react-native-passkey");
266
+ const passkeyModule = module.Passkey || module.default || module;
267
+ cachedPasskeyModule = passkeyModule;
268
+ return passkeyModule;
269
+ } catch (e) {
270
+ console.error("Failed to load react-native-passkey:", e);
271
+ throw new Error(
272
+ "react-native-passkey is not installed. Please install it to use passkey authentication: npm install react-native-passkey"
273
+ );
274
+ }
275
+ }
276
+ function setPasskeyModule(module) {
277
+ cachedPasskeyModule = module;
278
+ }
279
+ async function isPasskeySupported() {
280
+ try {
281
+ const module = getPasskeyModule();
282
+ return await module.isSupported();
283
+ } catch {
284
+ return false;
285
+ }
286
+ }
287
+ var ReactNativePasskeyAuth = class {
288
+ constructor(crypto, authenticate, authSecretStorage, appName, rpId) {
289
+ this.crypto = crypto;
290
+ this.authenticate = authenticate;
291
+ this.authSecretStorage = authSecretStorage;
292
+ this.appName = appName;
293
+ this.rpId = rpId;
294
+ /**
295
+ * Log in using an existing passkey.
296
+ * This will prompt the user to authenticate with their device biometrics.
297
+ */
298
+ this.logIn = async () => {
299
+ const { crypto, authenticate } = this;
300
+ const webAuthNCredential = await this.getPasskeyCredentials();
301
+ if (!webAuthNCredential) {
302
+ return;
303
+ }
304
+ if (!webAuthNCredential.response.userHandle) {
305
+ throw new Error("Passkey credential is missing userHandle");
306
+ }
307
+ const webAuthNCredentialPayload = base64UrlToUint8Array(
308
+ webAuthNCredential.response.userHandle
309
+ );
310
+ const accountSecretSeed = webAuthNCredentialPayload.slice(
311
+ 0,
312
+ cojsonInternals.secretSeedLength
313
+ );
314
+ const secret = crypto.agentSecretFromSecretSeed(accountSecretSeed);
315
+ const accountID = cojsonInternals.rawCoIDfromBytes(
316
+ webAuthNCredentialPayload.slice(
317
+ cojsonInternals.secretSeedLength,
318
+ cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength
319
+ )
320
+ );
321
+ await authenticate({
322
+ accountID,
323
+ accountSecret: secret
324
+ });
325
+ await this.authSecretStorage.set({
326
+ accountID,
327
+ secretSeed: accountSecretSeed,
328
+ accountSecret: secret,
329
+ provider: "passkey"
330
+ });
331
+ };
332
+ /**
333
+ * Register a new passkey for the current account.
334
+ * This will create a passkey that stores the account credentials securely on the device.
335
+ *
336
+ * @param username - The display name for the passkey
337
+ */
338
+ this.signUp = async (username) => {
339
+ const credentials = await this.authSecretStorage.get();
340
+ if (!credentials?.secretSeed) {
341
+ throw new Error(
342
+ "Not enough credentials to register the account with passkey"
343
+ );
344
+ }
345
+ await this.createPasskeyCredentials({
346
+ accountID: credentials.accountID,
347
+ secretSeed: credentials.secretSeed,
348
+ username
349
+ });
350
+ const currentAccount = await Account.getMe().$jazz.ensureLoaded({
351
+ resolve: {
352
+ profile: true
353
+ }
354
+ });
355
+ if (username.trim().length !== 0) {
356
+ currentAccount.profile.$jazz.set("name", username);
357
+ }
358
+ await this.authSecretStorage.set({
359
+ accountID: credentials.accountID,
360
+ secretSeed: credentials.secretSeed,
361
+ accountSecret: credentials.accountSecret,
362
+ provider: "passkey"
363
+ });
364
+ };
365
+ }
366
+ async createPasskeyCredentials({
367
+ accountID,
368
+ secretSeed,
369
+ username
370
+ }) {
371
+ const webAuthNCredentialPayload = new Uint8Array(
372
+ cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength
373
+ );
374
+ webAuthNCredentialPayload.set(secretSeed);
375
+ webAuthNCredentialPayload.set(
376
+ cojsonInternals.rawCoIDtoBytes(accountID),
377
+ cojsonInternals.secretSeedLength
378
+ );
379
+ const challenge = uint8ArrayToBase64Url(
380
+ new Uint8Array(this.crypto.randomBytes(32))
381
+ );
382
+ const userId = uint8ArrayToBase64Url(webAuthNCredentialPayload);
383
+ const passkey = getPasskeyModule();
384
+ try {
385
+ await passkey.create({
386
+ challenge,
387
+ rp: {
388
+ id: this.rpId,
389
+ name: this.appName
390
+ },
391
+ user: {
392
+ id: userId,
393
+ name: `${username} (${(/* @__PURE__ */ new Date()).toLocaleString()})`,
394
+ displayName: username
395
+ },
396
+ pubKeyCredParams: [
397
+ { alg: -7, type: "public-key" },
398
+ // ES256
399
+ { alg: -257, type: "public-key" }
400
+ // RS256
401
+ ],
402
+ authenticatorSelection: {
403
+ residentKey: "required",
404
+ userVerification: "preferred"
405
+ },
406
+ timeout: 6e4,
407
+ attestation: "none"
408
+ });
409
+ } catch (error) {
410
+ throw new Error("Passkey creation aborted", { cause: error });
411
+ }
412
+ }
413
+ async getPasskeyCredentials() {
414
+ const challenge = uint8ArrayToBase64Url(
415
+ new Uint8Array(this.crypto.randomBytes(32))
416
+ );
417
+ const passkey = getPasskeyModule();
418
+ try {
419
+ const result = await passkey.get({
420
+ challenge,
421
+ rpId: this.rpId,
422
+ timeout: 6e4,
423
+ userVerification: "preferred"
424
+ });
425
+ return result;
426
+ } catch (error) {
427
+ throw new Error("Passkey authentication aborted", { cause: error });
428
+ }
429
+ }
430
+ };
431
+ ReactNativePasskeyAuth.id = "passkey";
432
+
433
+ // src/react-native-core/auth/usePasskeyAuth.tsx
434
+ import {
435
+ useAuthSecretStorage,
436
+ useIsAuthenticated,
437
+ useJazzContext
438
+ } from "jazz-tools/react-core";
439
+ import { useMemo } from "react";
440
+ function usePasskeyAuth({
441
+ appName,
442
+ rpId
443
+ }) {
444
+ const context = useJazzContext();
445
+ const authSecretStorage = useAuthSecretStorage();
446
+ if ("guest" in context) {
447
+ throw new Error("Passkey auth is not supported in guest mode");
448
+ }
449
+ const authMethod = useMemo(() => {
450
+ return new ReactNativePasskeyAuth(
451
+ context.node.crypto,
452
+ context.authenticate,
453
+ authSecretStorage,
454
+ appName,
455
+ rpId
456
+ );
457
+ }, [
458
+ appName,
459
+ rpId,
460
+ authSecretStorage,
461
+ context.node.crypto,
462
+ context.authenticate
463
+ ]);
464
+ const isAuthenticated = useIsAuthenticated();
465
+ return {
466
+ state: isAuthenticated ? "signedIn" : "anonymous",
467
+ logIn: authMethod.logIn,
468
+ signUp: authMethod.signUp
469
+ };
470
+ }
471
+
472
+ // src/react-native-core/auth/PasskeyAuthBasicUI.tsx
473
+ import { useState as useState2 } from "react";
474
+ import {
475
+ StyleSheet as StyleSheet2,
476
+ Text as Text2,
477
+ TextInput as TextInput2,
478
+ TouchableOpacity as TouchableOpacity2,
479
+ View as View2,
480
+ useColorScheme as useColorScheme2
481
+ } from "react-native";
482
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
483
+ var PasskeyAuthBasicUI = ({
484
+ appName,
485
+ rpId,
486
+ children
487
+ }) => {
488
+ const colorScheme = useColorScheme2();
489
+ const darkMode = colorScheme === "dark";
490
+ const [username, setUsername] = useState2("");
491
+ const [errorMessage, setErrorMessage] = useState2(null);
492
+ const auth = usePasskeyAuth({ appName, rpId });
493
+ const handleSignUp = () => {
494
+ setErrorMessage(null);
495
+ auth.signUp(username).catch((error) => {
496
+ if (error.cause instanceof Error) {
497
+ setErrorMessage(error.cause.message);
498
+ } else {
499
+ setErrorMessage(error.message);
500
+ }
501
+ });
502
+ };
503
+ const handleLogIn = () => {
504
+ setErrorMessage(null);
505
+ auth.logIn().catch((error) => {
506
+ if (error.cause instanceof Error) {
507
+ setErrorMessage(error.cause.message);
508
+ } else {
509
+ setErrorMessage(error.message);
510
+ }
511
+ });
512
+ };
513
+ if (auth.state === "signedIn") {
514
+ return children;
515
+ }
516
+ return /* @__PURE__ */ jsx2(
517
+ View2,
518
+ {
519
+ style: [
520
+ styles2.container,
521
+ darkMode ? styles2.darkBackground : styles2.lightBackground
522
+ ],
523
+ children: /* @__PURE__ */ jsxs2(View2, { style: styles2.formContainer, children: [
524
+ /* @__PURE__ */ jsx2(
525
+ Text2,
526
+ {
527
+ style: [
528
+ styles2.headerText,
529
+ darkMode ? styles2.darkText : styles2.lightText
530
+ ],
531
+ children: appName
532
+ }
533
+ ),
534
+ errorMessage && /* @__PURE__ */ jsx2(Text2, { style: styles2.errorText, children: errorMessage }),
535
+ /* @__PURE__ */ jsx2(
536
+ TextInput2,
537
+ {
538
+ placeholder: "Display name",
539
+ value: username,
540
+ onChangeText: setUsername,
541
+ placeholderTextColor: darkMode ? "#999" : "#666",
542
+ style: [
543
+ styles2.textInput,
544
+ darkMode ? styles2.darkInput : styles2.lightInput
545
+ ],
546
+ autoCapitalize: "words",
547
+ autoCorrect: false
548
+ }
549
+ ),
550
+ /* @__PURE__ */ jsx2(
551
+ TouchableOpacity2,
552
+ {
553
+ onPress: handleSignUp,
554
+ style: [
555
+ styles2.button,
556
+ darkMode ? styles2.darkButton : styles2.lightButton
557
+ ],
558
+ children: /* @__PURE__ */ jsx2(
559
+ Text2,
560
+ {
561
+ style: darkMode ? styles2.darkButtonText : styles2.lightButtonText,
562
+ children: "Sign Up with Passkey"
563
+ }
564
+ )
565
+ }
566
+ ),
567
+ /* @__PURE__ */ jsxs2(View2, { style: styles2.divider, children: [
568
+ /* @__PURE__ */ jsx2(
569
+ View2,
570
+ {
571
+ style: [
572
+ styles2.dividerLine,
573
+ darkMode ? styles2.darkDivider : styles2.lightDivider
574
+ ]
575
+ }
576
+ ),
577
+ /* @__PURE__ */ jsx2(
578
+ Text2,
579
+ {
580
+ style: [
581
+ styles2.dividerText,
582
+ darkMode ? styles2.darkText : styles2.lightText
583
+ ],
584
+ children: "or"
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsx2(
588
+ View2,
589
+ {
590
+ style: [
591
+ styles2.dividerLine,
592
+ darkMode ? styles2.darkDivider : styles2.lightDivider
593
+ ]
594
+ }
595
+ )
596
+ ] }),
597
+ /* @__PURE__ */ jsx2(
598
+ TouchableOpacity2,
599
+ {
600
+ onPress: handleLogIn,
601
+ style: [
602
+ styles2.secondaryButton,
603
+ darkMode ? styles2.darkSecondaryButton : styles2.lightSecondaryButton
604
+ ],
605
+ children: /* @__PURE__ */ jsx2(Text2, { style: darkMode ? styles2.darkText : styles2.lightText, children: "Log In with Existing Passkey" })
606
+ }
607
+ )
608
+ ] })
609
+ }
610
+ );
611
+ };
612
+ var styles2 = StyleSheet2.create({
613
+ container: {
614
+ flex: 1,
615
+ justifyContent: "center",
616
+ alignItems: "center",
617
+ padding: 20
618
+ },
619
+ formContainer: {
620
+ width: "80%",
621
+ maxWidth: 300,
622
+ alignItems: "center",
623
+ justifyContent: "center"
624
+ },
625
+ headerText: {
626
+ fontSize: 24,
627
+ fontWeight: "600",
628
+ marginBottom: 30
629
+ },
630
+ errorText: {
631
+ color: "#ff4444",
632
+ marginVertical: 10,
633
+ textAlign: "center",
634
+ fontSize: 14
635
+ },
636
+ textInput: {
637
+ borderWidth: 1,
638
+ padding: 12,
639
+ marginVertical: 10,
640
+ width: "100%",
641
+ borderRadius: 8,
642
+ fontSize: 16
643
+ },
644
+ darkInput: {
645
+ borderColor: "#444",
646
+ backgroundColor: "#1a1a1a",
647
+ color: "#fff"
648
+ },
649
+ lightInput: {
650
+ borderColor: "#ddd",
651
+ backgroundColor: "#fff",
652
+ color: "#000"
653
+ },
654
+ button: {
655
+ paddingVertical: 14,
656
+ paddingHorizontal: 10,
657
+ borderRadius: 8,
658
+ width: "100%",
659
+ marginVertical: 10
660
+ },
661
+ darkButton: {
662
+ backgroundColor: "#0066cc"
663
+ },
664
+ lightButton: {
665
+ backgroundColor: "#007aff"
666
+ },
667
+ darkButtonText: {
668
+ color: "#fff",
669
+ textAlign: "center",
670
+ fontWeight: "600",
671
+ fontSize: 16
672
+ },
673
+ lightButtonText: {
674
+ color: "#fff",
675
+ textAlign: "center",
676
+ fontWeight: "600",
677
+ fontSize: 16
678
+ },
679
+ divider: {
680
+ flexDirection: "row",
681
+ alignItems: "center",
682
+ width: "100%",
683
+ marginVertical: 20
684
+ },
685
+ dividerLine: {
686
+ flex: 1,
687
+ height: 1
688
+ },
689
+ darkDivider: {
690
+ backgroundColor: "#444"
691
+ },
692
+ lightDivider: {
693
+ backgroundColor: "#ddd"
694
+ },
695
+ dividerText: {
696
+ marginHorizontal: 10,
697
+ fontSize: 14
698
+ },
699
+ secondaryButton: {
700
+ paddingVertical: 14,
701
+ paddingHorizontal: 10,
702
+ borderRadius: 8,
703
+ width: "100%",
704
+ borderWidth: 1
705
+ },
706
+ darkSecondaryButton: {
707
+ borderColor: "#444",
708
+ backgroundColor: "transparent"
709
+ },
710
+ lightSecondaryButton: {
711
+ borderColor: "#ddd",
712
+ backgroundColor: "transparent"
713
+ },
714
+ darkText: {
715
+ color: "#fff",
716
+ textAlign: "center"
717
+ },
718
+ lightText: {
719
+ color: "#000",
720
+ textAlign: "center"
721
+ },
722
+ darkBackground: {
723
+ backgroundColor: "#000"
724
+ },
725
+ lightBackground: {
726
+ backgroundColor: "#fff"
727
+ }
728
+ });
729
+
225
730
  // src/react-native-core/auth/auth.ts
226
731
  function clearUserCredentials() {
227
732
  const kvStore = KvStoreContext.getInstance().getStorage();
@@ -235,16 +740,17 @@ function clearUserCredentials() {
235
740
  // src/react-native-core/hooks.tsx
236
741
  import { useEffect } from "react";
237
742
  import { parseInviteLink } from "jazz-tools";
238
- import { useJazzContext } from "jazz-tools/react-core";
743
+ import { useJazzContext as useJazzContext2 } from "jazz-tools/react-core";
239
744
  import { Linking } from "react-native";
240
745
  import {
241
746
  useCoState,
747
+ useCoStates,
242
748
  experimental_useInboxSender,
243
749
  useDemoAuth,
244
750
  usePassphraseAuth,
245
- useJazzContext as useJazzContext2,
246
- useAuthSecretStorage,
247
- useIsAuthenticated,
751
+ useJazzContext as useJazzContext3,
752
+ useAuthSecretStorage as useAuthSecretStorage2,
753
+ useIsAuthenticated as useIsAuthenticated2,
248
754
  useAccount,
249
755
  useAgent,
250
756
  useLogOut,
@@ -253,6 +759,7 @@ import {
253
759
  useAccountSubscription,
254
760
  useSubscriptionSelector,
255
761
  useSuspenseCoState,
762
+ useSuspenseCoStates,
256
763
  useSuspenseAccount
257
764
  } from "jazz-tools/react-core";
258
765
  function useAcceptInviteNative({
@@ -260,7 +767,7 @@ function useAcceptInviteNative({
260
767
  onAccept,
261
768
  forValueHint
262
769
  }) {
263
- const context = useJazzContext();
770
+ const context = useJazzContext2();
264
771
  if (!("me" in context)) {
265
772
  throw new Error(
266
773
  "useAcceptInviteNative can't be used in a JazzProvider with auth === 'guest'."
@@ -293,7 +800,7 @@ function useAcceptInviteNative({
293
800
 
294
801
  // src/react-native-core/provider.tsx
295
802
  import { JazzContext, JazzContextManagerContext } from "jazz-tools/react-core";
296
- import React2, { useEffect as useEffect2, useRef } from "react";
803
+ import React3, { useEffect as useEffect2, useRef } from "react";
297
804
 
298
805
  // src/react-native-core/ReactNativeContextManager.ts
299
806
  import {
@@ -376,8 +883,8 @@ var ReactNativeWebSocketPeerWithReconnection = class extends WebSocketPeerWithRe
376
883
  }
377
884
  };
378
885
  async function setupPeers(options) {
379
- const CryptoProvider2 = options.CryptoProvider || PureJSCrypto;
380
- const crypto = await CryptoProvider2.create();
886
+ const CryptoProvider3 = options.CryptoProvider || PureJSCrypto;
887
+ const crypto = await CryptoProvider3.create();
381
888
  let node = void 0;
382
889
  const peers = [];
383
890
  const storage = options.storage && options.storage !== "disabled" ? await getSqliteStorageAsync(options.storage) : void 0;
@@ -577,7 +1084,7 @@ var ReactNativeContextManager = class extends JazzContextManager {
577
1084
  };
578
1085
 
579
1086
  // src/react-native-core/provider.tsx
580
- import { jsx as jsx2 } from "react/jsx-runtime";
1087
+ import { jsx as jsx3 } from "react/jsx-runtime";
581
1088
  function JazzProviderCore({
582
1089
  children,
583
1090
  guestMode,
@@ -589,11 +1096,11 @@ function JazzProviderCore({
589
1096
  logOutReplacement,
590
1097
  onAnonymousAccountDiscarded,
591
1098
  kvStore,
592
- CryptoProvider: CryptoProvider2,
1099
+ CryptoProvider: CryptoProvider3,
593
1100
  authSecretStorageKey
594
1101
  }) {
595
1102
  setupKvStore(kvStore);
596
- const [contextManager] = React2.useState(
1103
+ const [contextManager] = React3.useState(
597
1104
  () => new ReactNativeContextManager({ authSecretStorageKey })
598
1105
  );
599
1106
  const onLogOutRefCallback = useRefCallback(onLogOut);
@@ -606,8 +1113,8 @@ function JazzProviderCore({
606
1113
  const onAnonymousAccountDiscardedEnabled = Boolean(
607
1114
  onAnonymousAccountDiscarded
608
1115
  );
609
- const value = React2.useSyncExternalStore(
610
- React2.useCallback(
1116
+ const value = React3.useSyncExternalStore(
1117
+ React3.useCallback(
611
1118
  (callback) => {
612
1119
  const props = {
613
1120
  AccountSchema,
@@ -618,7 +1125,7 @@ function JazzProviderCore({
618
1125
  onLogOut: onLogOutRefCallback,
619
1126
  logOutReplacement: logoutReplacementActiveRef.current ? logOutReplacementRefCallback : void 0,
620
1127
  onAnonymousAccountDiscarded: onAnonymousAccountDiscardedEnabled ? onAnonymousAccountDiscardedRefCallback : void 0,
621
- CryptoProvider: CryptoProvider2
1128
+ CryptoProvider: CryptoProvider3
622
1129
  };
623
1130
  if (contextManager.propsChanged(props)) {
624
1131
  contextManager.createContext(props).catch((error) => {
@@ -639,10 +1146,10 @@ function JazzProviderCore({
639
1146
  contextManager.done();
640
1147
  };
641
1148
  }, []);
642
- return /* @__PURE__ */ jsx2(JazzContext.Provider, { value, children: /* @__PURE__ */ jsx2(JazzContextManagerContext.Provider, { value: contextManager, children: value && children }) });
1149
+ return /* @__PURE__ */ jsx3(JazzContext.Provider, { value, children: /* @__PURE__ */ jsx3(JazzContextManagerContext.Provider, { value: contextManager, children: value && children }) });
643
1150
  }
644
1151
  function useRefCallback(callback) {
645
- const callbackRef = React2.useRef(callback);
1152
+ const callbackRef = React3.useRef(callback);
646
1153
  callbackRef.current = callback;
647
1154
  return useRef(
648
1155
  (...args) => callbackRef.current?.(...args)
@@ -652,17 +1159,17 @@ function useRefCallback(callback) {
652
1159
  // src/react-native-core/media/image.tsx
653
1160
  import { ImageDefinition } from "jazz-tools";
654
1161
  import { highestResAvailable } from "jazz-tools/media";
655
- import { forwardRef, useEffect as useEffect3, useMemo, useState as useState2 } from "react";
1162
+ import { forwardRef, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
656
1163
  import { Image as RNImage } from "react-native";
657
- import { jsx as jsx3 } from "react/jsx-runtime";
1164
+ import { jsx as jsx4 } from "react/jsx-runtime";
658
1165
  var Image = forwardRef(function Image2({ imageId, width, height, placeholder, ...props }, ref) {
659
1166
  const image = useCoState(ImageDefinition, imageId, {
660
1167
  select: (image2) => image2.$isLoaded ? image2 : null
661
1168
  });
662
- const [src, setSrc] = useState2(
1169
+ const [src, setSrc] = useState3(
663
1170
  image?.placeholderDataURL ?? "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
664
1171
  );
665
- const dimensions = useMemo(() => {
1172
+ const dimensions = useMemo2(() => {
666
1173
  const originalWidth = image?.originalSize?.[0];
667
1174
  const originalHeight = image?.originalSize?.[1];
668
1175
  if (width === "original" && height === "original") {
@@ -717,7 +1224,7 @@ var Image = forwardRef(function Image2({ imageId, width, height, placeholder, ..
717
1224
  if (!src) {
718
1225
  return null;
719
1226
  }
720
- return /* @__PURE__ */ jsx3(
1227
+ return /* @__PURE__ */ jsx4(
721
1228
  RNImage,
722
1229
  {
723
1230
  ref,
@@ -741,30 +1248,38 @@ export {
741
1248
  Image,
742
1249
  JazzProviderCore,
743
1250
  KvStoreContext,
1251
+ PasskeyAuthBasicUI,
744
1252
  ReactNativeContextManager,
1253
+ ReactNativePasskeyAuth,
745
1254
  SQLiteDatabaseDriverAsync,
746
1255
  clearUserCredentials,
747
1256
  createAccountSubscriptionContext,
748
1257
  createCoValueSubscriptionContext,
749
1258
  createInviteLink,
750
1259
  experimental_useInboxSender,
1260
+ getPasskeyModule,
1261
+ isPasskeySupported,
751
1262
  parseInviteLink2 as parseInviteLink,
1263
+ setPasskeyModule,
752
1264
  setupKvStore,
753
1265
  useAcceptInviteNative,
754
1266
  useAccount,
755
1267
  useAccountSubscription,
756
1268
  useAgent,
757
- useAuthSecretStorage,
1269
+ useAuthSecretStorage2 as useAuthSecretStorage,
758
1270
  useCoState,
1271
+ useCoStates,
759
1272
  useCoValueSubscription,
760
1273
  useDemoAuth,
761
- useIsAuthenticated,
762
- useJazzContext2 as useJazzContext,
1274
+ useIsAuthenticated2 as useIsAuthenticated,
1275
+ useJazzContext3 as useJazzContext,
763
1276
  useLogOut,
1277
+ usePasskeyAuth,
764
1278
  usePassphraseAuth,
765
1279
  useSubscriptionSelector,
766
1280
  useSuspenseAccount,
767
1281
  useSuspenseCoState,
1282
+ useSuspenseCoStates,
768
1283
  useSyncConnectionStatus
769
1284
  };
770
1285
  //# sourceMappingURL=index.js.map