jazz-tools 0.18.8 → 0.18.11

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 (49) hide show
  1. package/.svelte-kit/__package__/jazz.svelte.d.ts +1 -1
  2. package/.svelte-kit/__package__/jazz.svelte.d.ts.map +1 -1
  3. package/.svelte-kit/__package__/jazz.svelte.js +19 -26
  4. package/.turbo/turbo-build.log +43 -43
  5. package/CHANGELOG.md +31 -0
  6. package/dist/better-auth/auth/client.d.ts +1 -1
  7. package/dist/better-auth/auth/client.d.ts.map +1 -1
  8. package/dist/better-auth/auth/client.js.map +1 -1
  9. package/dist/{chunk-QF3R3C4N.js → chunk-RQHJFPIB.js} +56 -25
  10. package/dist/{chunk-QF3R3C4N.js.map → chunk-RQHJFPIB.js.map} +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/react/hooks.d.ts +1 -1
  13. package/dist/react/hooks.d.ts.map +1 -1
  14. package/dist/react/index.d.ts +1 -1
  15. package/dist/react/index.d.ts.map +1 -1
  16. package/dist/react/index.js +3 -1
  17. package/dist/react/index.js.map +1 -1
  18. package/dist/react-core/hooks.d.ts +56 -0
  19. package/dist/react-core/hooks.d.ts.map +1 -1
  20. package/dist/react-core/index.js +20 -0
  21. package/dist/react-core/index.js.map +1 -1
  22. package/dist/react-core/tests/useAccountWithSelector.test.d.ts +2 -0
  23. package/dist/react-core/tests/useAccountWithSelector.test.d.ts.map +1 -0
  24. package/dist/react-native-core/hooks.d.ts +1 -1
  25. package/dist/react-native-core/hooks.d.ts.map +1 -1
  26. package/dist/react-native-core/index.js +3 -1
  27. package/dist/react-native-core/index.js.map +1 -1
  28. package/dist/svelte/jazz.svelte.d.ts +1 -1
  29. package/dist/svelte/jazz.svelte.d.ts.map +1 -1
  30. package/dist/svelte/jazz.svelte.js +19 -26
  31. package/dist/testing.js +1 -1
  32. package/dist/tools/implementation/ContextManager.d.ts +2 -0
  33. package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
  34. package/dist/worker/index.d.ts +26 -0
  35. package/dist/worker/index.d.ts.map +1 -1
  36. package/dist/worker/index.js +29 -2
  37. package/dist/worker/index.js.map +1 -1
  38. package/package.json +4 -4
  39. package/src/better-auth/auth/client.ts +1 -1
  40. package/src/better-auth/auth/tests/client.test.ts +229 -0
  41. package/src/react/hooks.tsx +1 -0
  42. package/src/react/index.ts +1 -0
  43. package/src/react-core/hooks.ts +84 -0
  44. package/src/react-core/tests/useAccountWithSelector.test.ts +411 -0
  45. package/src/react-native-core/hooks.tsx +1 -0
  46. package/src/svelte/jazz.svelte.ts +23 -27
  47. package/src/tools/implementation/ContextManager.ts +75 -32
  48. package/src/tools/tests/ContextManager.test.ts +252 -0
  49. package/src/worker/index.ts +28 -1
@@ -32,7 +32,7 @@ export declare function getAuthSecretStorage(): AuthSecretStorage;
32
32
  export declare class InviteListener<V extends CoValueClassOrSchema> {
33
33
  constructor({ invitedObjectSchema, onAccept, forValueHint, }: {
34
34
  invitedObjectSchema: V;
35
- onAccept: (projectID: ID<V>) => void;
35
+ onAccept: (coValueID: ID<V>) => void;
36
36
  forValueHint?: string;
37
37
  });
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jazz.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/jazz.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,EAEF,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,QAAQ,IAAK,CAAC;AAC3B,eAAO,MAAM,aAAa,IAAK,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,GAAG,SAAS,OAAO,IAAI;IAC7C,OAAO,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,SAAS,OAAO,KAW9B;IAChB,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;CAC/B,CACF;AAED,wBAAgB,oBAAoB,sBAUnC;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,oBAAoB;gBAC5C,EACV,mBAAmB,EACnB,QAAQ,EACR,YAAY,GACb,EAAE;QACD,mBAAmB,EAAE,CAAC,CAAC;QACvB,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QACrC,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;CA+BF"}
1
+ {"version":3,"file":"jazz.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/jazz.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,EAEF,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,QAAQ,IAAK,CAAC;AAC3B,eAAO,MAAM,aAAa,IAAK,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,GAAG,SAAS,OAAO,IAAI;IAC7C,OAAO,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,SAAS,OAAO,KAW9B;IAChB,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;CAC/B,CACF;AAED,wBAAgB,oBAAoB,sBAUnC;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,oBAAoB;gBAC5C,EACV,mBAAmB,EACnB,QAAQ,EACR,YAAY,GACb,EAAE;QACD,mBAAmB,EAAE,CAAC,CAAC;QACvB,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QACrC,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;CA2BF"}
@@ -1,5 +1,5 @@
1
1
  import { consumeInviteLinkFromWindowLocation } from "jazz-tools/browser";
2
- import { getContext, untrack } from "svelte";
2
+ import { getContext, onDestroy, untrack } from "svelte";
3
3
  import Provider from "./Provider.svelte";
4
4
  export { Provider as JazzSvelteProvider };
5
5
  /**
@@ -38,33 +38,26 @@ export function getAuthSecretStorage() {
38
38
  */
39
39
  export class InviteListener {
40
40
  constructor({ invitedObjectSchema, onAccept, forValueHint, }) {
41
- // TODO Listen to the hashchange event
42
41
  const _onAccept = onAccept;
43
- // Subscribe to the onAccept function.
42
+ const ctx = getJazzContext();
43
+ const tryConsume = () => {
44
+ if (!ctx.current || !("me" in ctx.current))
45
+ return;
46
+ consumeInviteLinkFromWindowLocation({
47
+ as: ctx.current.me,
48
+ invitedObjectSchema,
49
+ forValueHint,
50
+ })
51
+ .then((result) => result && _onAccept(result.valueID))
52
+ .catch((e) => console.error("Failed to accept invite", e));
53
+ };
54
+ // run once when instantiated
44
55
  $effect(() => {
45
- const ctx = getJazzContext();
46
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
47
- _onAccept;
48
- // Subscribe to the onAccept function.
49
- untrack(() => {
50
- // If there is no context, return.
51
- if (!ctx.current)
52
- return;
53
- if (!("me" in ctx.current))
54
- return;
55
- // Consume the invite link from the window location.
56
- const result = consumeInviteLinkFromWindowLocation({
57
- as: ctx.current.me,
58
- invitedObjectSchema,
59
- forValueHint,
60
- });
61
- // If the result is valid, call the onAccept function.
62
- result
63
- .then((result) => result && _onAccept(result?.valueID))
64
- .catch((e) => {
65
- console.error("Failed to accept invite", e);
66
- });
67
- });
56
+ untrack(tryConsume);
57
+ });
58
+ window.addEventListener("hashchange", tryConsume);
59
+ onDestroy(() => {
60
+ window.removeEventListener("hashchange", tryConsume);
68
61
  });
69
62
  }
70
63
  }
@@ -1,5 +1,5 @@
1
1
 
2
- > jazz-tools@0.18.8 build /home/runner/_work/jazz/jazz/packages/jazz-tools
2
+ > jazz-tools@0.18.11 build /home/runner/_work/jazz/jazz/packages/jazz-tools
3
3
  > tsup && pnpm types && pnpm build:svelte
4
4
 
5
5
  CLI Building entry: {"index":"src/index.ts","testing":"src/testing.ts"}
@@ -107,22 +107,22 @@
107
107
  ESM Build start
108
108
  CLI Cleaning output folder
109
109
  ESM Build start
110
+ ESM dist/tiptap/index.js 564.00 B
111
+ ESM dist/tiptap/index.js.map 1.21 KB
112
+ ESM ⚡️ Build success in 11ms
110
113
  ESM dist/react/ssr.js 688.00 B
111
114
  ESM dist/react/ssr.js.map 1.12 KB
112
- ESM ⚡️ Build success in 17ms
113
- ESM dist/react-native/testing.js 120.00 B
114
- ESM dist/react-native/index.js 2.53 KB
115
- ESM dist/react-native/crypto.js 161.00 B
116
- ESM dist/react-native/testing.js.map 176.00 B
117
- ESM dist/react-native/index.js.map 5.68 KB
118
- ESM dist/react-native/crypto.js.map 197.00 B
115
+ ESM ⚡️ Build success in 14ms
116
+ ESM dist/worker/index.js 3.19 KB
117
+ ESM dist/worker/index.js.map 6.17 KB
118
+ ESM ⚡️ Build success in 14ms
119
+ ESM dist/better-auth/auth/client.js 4.44 KB
120
+ ESM dist/better-auth/auth/server.js 8.36 KB
121
+ ESM dist/better-auth/auth/react.js 799.00 B
122
+ ESM dist/better-auth/auth/client.js.map 8.24 KB
123
+ ESM dist/better-auth/auth/server.js.map 15.29 KB
124
+ ESM dist/better-auth/auth/react.js.map 2.04 KB
119
125
  ESM ⚡️ Build success in 18ms
120
- ESM dist/tiptap/index.js 564.00 B
121
- ESM dist/tiptap/index.js.map 1.21 KB
122
- ESM ⚡️ Build success in 22ms
123
- ESM dist/worker/index.js 2.47 KB
124
- ESM dist/worker/index.js.map 5.26 KB
125
- ESM ⚡️ Build success in 21ms
126
126
  ESM dist/media/index.js 236.00 B
127
127
  ESM dist/media/index.browser.js 2.79 KB
128
128
  ESM dist/media/index.native.js 2.90 KB
@@ -133,67 +133,67 @@
133
133
  ESM dist/media/index.native.js.map 6.09 KB
134
134
  ESM dist/media/index.server.js.map 6.37 KB
135
135
  ESM dist/media/chunk-W3S526L3.js.map 16.57 KB
136
- ESM ⚡️ Build success in 32ms
137
- ESM dist/better-auth/auth/client.js 4.44 KB
138
- ESM dist/better-auth/auth/server.js 8.36 KB
139
- ESM dist/better-auth/auth/react.js 799.00 B
140
- ESM dist/better-auth/auth/client.js.map 8.24 KB
141
- ESM dist/better-auth/auth/react.js.map 2.04 KB
142
- ESM dist/better-auth/auth/server.js.map 15.29 KB
143
- ESM ⚡️ Build success in 29ms
144
- ESM dist/browser/index.js 13.64 KB
145
- ESM dist/browser/index.js.map 29.14 KB
146
- ESM ⚡️ Build success in 38ms
136
+ ESM ⚡️ Build success in 25ms
147
137
  ESM dist/expo/index.js 4.68 KB
148
138
  ESM dist/expo/testing.js 112.00 B
149
139
  ESM dist/expo/crypto.js 153.00 B
150
140
  ESM dist/expo/index.js.map 10.23 KB
151
141
  ESM dist/expo/testing.js.map 168.00 B
152
142
  ESM dist/expo/crypto.js.map 189.00 B
153
- ESM ⚡️ Build success in 41ms
154
- ESM dist/react-native-core/index.js 17.95 KB
143
+ ESM ⚡️ Build success in 24ms
144
+ ESM dist/browser/index.js 13.64 KB
145
+ ESM dist/browser/index.js.map 29.14 KB
146
+ ESM ⚡️ Build success in 34ms
147
+ ESM dist/react-native/index.js 2.53 KB
148
+ ESM dist/react-native/testing.js 120.00 B
149
+ ESM dist/react-native/crypto.js 161.00 B
150
+ ESM dist/react-native/index.js.map 5.68 KB
151
+ ESM dist/react-native/testing.js.map 176.00 B
152
+ ESM dist/react-native/crypto.js.map 197.00 B
153
+ ESM ⚡️ Build success in 29ms
154
+ ESM dist/react-native-core/index.js 18.00 KB
155
155
  ESM dist/react-native-core/testing.js 119.00 B
156
156
  ESM dist/react-native-core/crypto.js 2.10 KB
157
+ ESM dist/react-native-core/index.js.map 36.73 KB
157
158
  ESM dist/react-native-core/testing.js.map 175.00 B
158
159
  ESM dist/react-native-core/crypto.js.map 4.25 KB
159
- ESM dist/react-native-core/index.js.map 36.70 KB
160
- ESM ⚡️ Build success in 41ms
161
- ESM dist/react/index.js 24.71 KB
160
+ ESM ⚡️ Build success in 38ms
162
161
  ESM dist/react/testing.js 122.00 B
163
- ESM dist/react/index.js.map 53.50 KB
162
+ ESM dist/react/index.js 24.76 KB
164
163
  ESM dist/react/testing.js.map 165.00 B
165
- ESM ⚡️ Build success in 42ms
164
+ ESM dist/react/index.js.map 53.56 KB
165
+ ESM ⚡️ Build success in 41ms
166
166
  ESM dist/prosemirror/index.js 77.63 KB
167
167
  ESM dist/prosemirror/index.js.map 306.98 KB
168
- ESM ⚡️ Build success in 44ms
168
+ ESM ⚡️ Build success in 43ms
169
169
  ESM dist/inspector/index.js 69.71 KB
170
170
  ESM dist/inspector/index.js.map 121.38 KB
171
- ESM ⚡️ Build success in 57ms
171
+ ESM ⚡️ Build success in 54ms
172
172
  ESM dist/testing.js 7.17 KB
173
173
  ESM dist/index.js 26.13 KB
174
- ESM dist/chunk-QF3R3C4N.js 168.58 KB
174
+ ESM dist/chunk-RQHJFPIB.js 169.74 KB
175
175
  ESM dist/testing.js.map 14.10 KB
176
176
  ESM dist/index.js.map 52.92 KB
177
- ESM dist/chunk-QF3R3C4N.js.map 400.77 KB
178
- ESM ⚡️ Build success in 81ms
179
- ESM dist/react-core/index.js 145.59 KB
177
+ ESM dist/chunk-RQHJFPIB.js.map 402.59 KB
178
+ ESM ⚡️ Build success in 78ms
180
179
  ESM dist/react-core/testing.js 1.17 KB
181
180
  ESM dist/react-core/chunk-7DYMJ74I.js 279.00 B
182
- ESM dist/react-core/index.js.map 399.79 KB
181
+ ESM dist/react-core/index.js 146.19 KB
183
182
  ESM dist/react-core/testing.js.map 1.82 KB
184
183
  ESM dist/react-core/chunk-7DYMJ74I.js.map 533.00 B
185
- ESM ⚡️ Build success in 78ms
184
+ ESM dist/react-core/index.js.map 404.45 KB
185
+ ESM ⚡️ Build success in 77ms
186
186
  ESM dist/inspector/register-custom-element.js 218.00 B
187
187
  ESM dist/inspector/register-custom-element.js.map 314.00 B
188
188
  ESM dist/inspector/custom-element-G6SPZEBR.js 1.54 MB
189
189
  ESM dist/inspector/custom-element-G6SPZEBR.js.map 2.36 MB
190
- ESM ⚡️ Build success in 114ms
190
+ ESM ⚡️ Build success in 109ms
191
191
 
192
- > jazz-tools@0.18.8 types /home/runner/_work/jazz/jazz/packages/jazz-tools
192
+ > jazz-tools@0.18.11 types /home/runner/_work/jazz/jazz/packages/jazz-tools
193
193
  > tsc --outDir dist
194
194
 
195
195
 
196
- > jazz-tools@0.18.8 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
196
+ > jazz-tools@0.18.11 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
197
197
  > rm -rf dist/svelte && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json
198
198
 
199
199
  src/svelte -> dist/svelte
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # jazz-tools
2
2
 
3
+ ## 0.18.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 06b4617: Update the Svelte InviteListener to listen to hash change events
8
+ - 70eb465: Add docs to the worker API and deprecate done in favor of shutdownWorker
9
+ - Updated dependencies [a4a9a1e]
10
+ - cojson@0.18.11
11
+ - cojson-storage-indexeddb@0.18.11
12
+ - cojson-transport-ws@0.18.11
13
+
14
+ ## 0.18.10
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [95cc9af]
19
+ - cojson-transport-ws@0.18.10
20
+ - cojson@0.18.10
21
+ - cojson-storage-indexeddb@0.18.10
22
+
23
+ ## 0.18.9
24
+
25
+ ### Patch Changes
26
+
27
+ - c8167de: fix: improve handling of concurrent authentication attempts in ContextManager
28
+ - 910b8d6: Added useAccountWithSelector hook for granular account data selection with custom equality checking
29
+ - Updated dependencies [f058875]
30
+ - cojson@0.18.9
31
+ - cojson-storage-indexeddb@0.18.9
32
+ - cojson-transport-ws@0.18.9
33
+
3
34
  ## 0.18.8
4
35
 
5
36
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import type { AuthSecretStorage, Account, JazzContextType } from "jazz-tools";
1
+ import type { Account, AuthSecretStorage, JazzContextType } from "jazz-tools";
2
2
  import type { jazzPlugin } from "./server.js";
3
3
  /**
4
4
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/better-auth/auth/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAEjB,OAAO,EACP,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;wBAmBC,UAAU,CAAC,OAAO,UAAU,CAAC;;;sCAIvB,eAAe,CAAC,OAAO,CAAC;4CAGlB,iBAAiB;;;;;;;;;;;CA4H1D,CAAC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/better-auth/auth/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,iBAAiB,EAEjB,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;wBAmBC,UAAU,CAAC,OAAO,UAAU,CAAC;;;sCAIvB,eAAe,CAAC,OAAO,CAAC;4CAGlB,iBAAiB;;;;;;;;;;;CA4H1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/better-auth/auth/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from \"better-auth\";\nimport type {\n AuthSecretStorage,\n AuthSetPayload,\n Account,\n JazzContextType,\n} from \"jazz-tools\";\nimport type { jazzPlugin } from \"./server.js\";\n\nconst SIGNUP_URLS = [\n \"/sign-up\",\n \"/sign-in/social\",\n \"/sign-in/oauth2\",\n \"/email-otp/send-verification-otp\",\n];\n\n/**\n * @example\n * ```ts\n * const auth = betterAuth({\n * plugins: [jazzPluginClient()],\n * });\n * ```\n */\nexport const jazzPluginClient = () => {\n let jazzContext: JazzContextType<Account>;\n let authSecretStorage: AuthSecretStorage;\n let signOutUnsubscription: () => void;\n\n const authenticateOnJazz = async (jazzAuth: AuthSetPayload) => {\n const parsedJazzAuth = {\n ...jazzAuth,\n secretSeed: jazzAuth.secretSeed\n ? Uint8Array.from(jazzAuth.secretSeed)\n : undefined,\n };\n\n await jazzContext.authenticate(parsedJazzAuth);\n await authSecretStorage.set(parsedJazzAuth);\n };\n\n return {\n id: \"jazz-plugin\",\n $InferServerPlugin: {} as ReturnType<typeof jazzPlugin>,\n getActions: ($fetch, $store) => {\n return {\n jazz: {\n setJazzContext: (context: JazzContextType<Account>) => {\n jazzContext = context;\n },\n setAuthSecretStorage: (storage: AuthSecretStorage) => {\n authSecretStorage = storage;\n if (signOutUnsubscription) signOutUnsubscription();\n\n // This is a workaround to logout from Better Auth when user logs out directly from Jazz\n signOutUnsubscription = authSecretStorage.onUpdate(\n (isAuthenticated) => {\n if (isAuthenticated === false) {\n const session = $store.atoms.session?.get();\n if (!session) return;\n\n // if the user logs out from Better Auth, the get session is immediately called\n // so we must wait the next fetched session to understand if we need to call sign-out\n if (session.isPending || session.isRefetching) {\n // listen once for next session's data\n const unsub = $store.atoms.session?.listen((session) => {\n unsub?.();\n // if the session is null, user has been already logged out from Better Auth\n if (session.data !== null) {\n $fetch(\"/sign-out\", { method: \"POST\" });\n }\n });\n }\n // if the session is not pending, it means user logged out from Jazz only\n // so we call the sign-out api\n else {\n $fetch(\"/sign-out\", { method: \"POST\" });\n }\n }\n },\n );\n },\n },\n };\n },\n fetchPlugins: [\n {\n id: \"jazz-plugin\",\n name: \"jazz-plugin\",\n hooks: {\n async onRequest(context) {\n if (\n SIGNUP_URLS.some((url) => context.url.toString().includes(url))\n ) {\n const credentials = await authSecretStorage.get();\n\n if (!credentials) {\n throw new Error(\"Jazz credentials not found\");\n }\n\n context.headers.set(\n \"x-jazz-auth\",\n JSON.stringify({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n accountSecret: credentials.accountSecret,\n }),\n );\n }\n },\n async onSuccess(context) {\n if (context.request.url.toString().includes(\"/sign-up\")) {\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n if (context.request.url.toString().includes(\"/sign-in/email\")) {\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n if (context.request.url.toString().includes(\"/get-session\")) {\n if (context.data === null) {\n if (authSecretStorage.isAuthenticated === true) {\n console.warn(\n \"Jazz is authenticated, but the session is null\",\n );\n }\n return;\n }\n\n if (!context.data?.user) {\n return;\n }\n\n if (authSecretStorage.isAuthenticated === false) {\n console.info(\n \"Jazz is not authenticated, using Better Auth stored credentials\",\n );\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n const sessionAccountID = context.data.user.accountID;\n\n const credentials = await authSecretStorage.get();\n\n if (!credentials) {\n throw new Error(\"Jazz credentials not found\");\n }\n\n if (credentials.accountID !== sessionAccountID) {\n console.info(\n \"Jazz credentials mismatch, using Better Auth stored credentials\",\n );\n await authenticateOnJazz(context.data.jazzAuth);\n }\n return;\n }\n\n if (context.request.url.toString().includes(\"/sign-out\")) {\n await jazzContext.logOut();\n return;\n }\n\n if (context.request.url.toString().includes(\"/delete-user\")) {\n await jazzContext.logOut();\n return;\n }\n },\n },\n },\n ],\n } satisfies BetterAuthClientPlugin;\n};\n"],"mappings":"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","names":["session"]}
1
+ {"version":3,"sources":["../../../src/better-auth/auth/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from \"better-auth\";\nimport type {\n Account,\n AuthSecretStorage,\n AuthSetPayload,\n JazzContextType,\n} from \"jazz-tools\";\nimport type { jazzPlugin } from \"./server.js\";\n\nconst SIGNUP_URLS = [\n \"/sign-up\",\n \"/sign-in/social\",\n \"/sign-in/oauth2\",\n \"/email-otp/send-verification-otp\",\n];\n\n/**\n * @example\n * ```ts\n * const auth = betterAuth({\n * plugins: [jazzPluginClient()],\n * });\n * ```\n */\nexport const jazzPluginClient = () => {\n let jazzContext: JazzContextType<Account>;\n let authSecretStorage: AuthSecretStorage;\n let signOutUnsubscription: () => void;\n\n const authenticateOnJazz = async (jazzAuth: AuthSetPayload) => {\n const parsedJazzAuth = {\n ...jazzAuth,\n secretSeed: jazzAuth.secretSeed\n ? Uint8Array.from(jazzAuth.secretSeed)\n : undefined,\n };\n\n await jazzContext.authenticate(parsedJazzAuth);\n await authSecretStorage.set(parsedJazzAuth);\n };\n\n return {\n id: \"jazz-plugin\",\n $InferServerPlugin: {} as ReturnType<typeof jazzPlugin>,\n getActions: ($fetch, $store) => {\n return {\n jazz: {\n setJazzContext: (context: JazzContextType<Account>) => {\n jazzContext = context;\n },\n setAuthSecretStorage: (storage: AuthSecretStorage) => {\n authSecretStorage = storage;\n if (signOutUnsubscription) signOutUnsubscription();\n\n // This is a workaround to logout from Better Auth when user logs out directly from Jazz\n signOutUnsubscription = authSecretStorage.onUpdate(\n (isAuthenticated) => {\n if (isAuthenticated === false) {\n const session = $store.atoms.session?.get();\n if (!session) return;\n\n // if the user logs out from Better Auth, the get session is immediately called\n // so we must wait the next fetched session to understand if we need to call sign-out\n if (session.isPending || session.isRefetching) {\n // listen once for next session's data\n const unsub = $store.atoms.session?.listen((session) => {\n unsub?.();\n // if the session is null, user has been already logged out from Better Auth\n if (session.data !== null) {\n $fetch(\"/sign-out\", { method: \"POST\" });\n }\n });\n }\n // if the session is not pending, it means user logged out from Jazz only\n // so we call the sign-out api\n else {\n $fetch(\"/sign-out\", { method: \"POST\" });\n }\n }\n },\n );\n },\n },\n };\n },\n fetchPlugins: [\n {\n id: \"jazz-plugin\",\n name: \"jazz-plugin\",\n hooks: {\n async onRequest(context) {\n if (\n SIGNUP_URLS.some((url) => context.url.toString().includes(url))\n ) {\n const credentials = await authSecretStorage.get();\n\n if (!credentials) {\n throw new Error(\"Jazz credentials not found\");\n }\n\n context.headers.set(\n \"x-jazz-auth\",\n JSON.stringify({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n accountSecret: credentials.accountSecret,\n }),\n );\n }\n },\n async onSuccess(context) {\n if (context.request.url.toString().includes(\"/sign-up\")) {\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n if (context.request.url.toString().includes(\"/sign-in/email\")) {\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n if (context.request.url.toString().includes(\"/get-session\")) {\n if (context.data === null) {\n if (authSecretStorage.isAuthenticated === true) {\n console.warn(\n \"Jazz is authenticated, but the session is null\",\n );\n }\n return;\n }\n\n if (!context.data?.user) {\n return;\n }\n\n if (authSecretStorage.isAuthenticated === false) {\n console.info(\n \"Jazz is not authenticated, using Better Auth stored credentials\",\n );\n await authenticateOnJazz(context.data.jazzAuth);\n return;\n }\n\n const sessionAccountID = context.data.user.accountID;\n\n const credentials = await authSecretStorage.get();\n\n if (!credentials) {\n throw new Error(\"Jazz credentials not found\");\n }\n\n if (credentials.accountID !== sessionAccountID) {\n console.info(\n \"Jazz credentials mismatch, using Better Auth stored credentials\",\n );\n await authenticateOnJazz(context.data.jazzAuth);\n }\n return;\n }\n\n if (context.request.url.toString().includes(\"/sign-out\")) {\n await jazzContext.logOut();\n return;\n }\n\n if (context.request.url.toString().includes(\"/delete-user\")) {\n await jazzContext.logOut();\n return;\n }\n },\n },\n },\n ],\n } satisfies BetterAuthClientPlugin;\n};\n"],"mappings":"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","names":["session"]}
@@ -5366,10 +5366,12 @@ var JazzContextManager = class {
5366
5366
  constructor(opts) {
5367
5367
  this.authSecretStorage = new AuthSecretStorage();
5368
5368
  this.keepContextOpen = false;
5369
+ this.authenticatingAccountID = null;
5369
5370
  this.logOut = async () => {
5370
5371
  if (!this.context || !this.props) {
5371
5372
  return;
5372
5373
  }
5374
+ this.authenticatingAccountID = null;
5373
5375
  await this.props.onLogOut?.();
5374
5376
  if (this.props.logOutReplacement) {
5375
5377
  await this.props.logOutReplacement();
@@ -5399,38 +5401,64 @@ var JazzContextManager = class {
5399
5401
  if (!this.props) {
5400
5402
  throw new Error("Props required");
5401
5403
  }
5402
- const prevContext = this.context;
5403
- const migratingAnonymousAccount = await this.shouldMigrateAnonymousAccount();
5404
- this.keepContextOpen = migratingAnonymousAccount;
5405
- await this.createContext(this.props, { credentials }).finally(() => {
5406
- this.keepContextOpen = false;
5407
- });
5408
- if (migratingAnonymousAccount) {
5409
- await this.handleAnonymousAccountMigration(prevContext);
5404
+ if (this.authenticatingAccountID && this.authenticatingAccountID === credentials.accountID) {
5405
+ console.info(
5406
+ "Authentication already in progress for account",
5407
+ credentials.accountID,
5408
+ "skipping duplicate request"
5409
+ );
5410
+ return;
5411
+ }
5412
+ if (this.authenticatingAccountID && this.authenticatingAccountID !== credentials.accountID) {
5413
+ throw new Error(
5414
+ `Authentication already in progress for different account (${this.authenticatingAccountID}), cannot authenticate ${credentials.accountID}`
5415
+ );
5416
+ }
5417
+ this.authenticatingAccountID = credentials.accountID;
5418
+ try {
5419
+ const prevContext = this.context;
5420
+ const migratingAnonymousAccount = await this.shouldMigrateAnonymousAccount();
5421
+ this.keepContextOpen = migratingAnonymousAccount;
5422
+ await this.createContext(this.props, { credentials }).finally(() => {
5423
+ this.keepContextOpen = false;
5424
+ });
5425
+ if (migratingAnonymousAccount) {
5426
+ await this.handleAnonymousAccountMigration(prevContext);
5427
+ }
5428
+ } finally {
5429
+ this.authenticatingAccountID = null;
5410
5430
  }
5411
5431
  };
5412
5432
  this.register = async (accountSecret, creationProps) => {
5413
5433
  if (!this.props) {
5414
5434
  throw new Error("Props required");
5415
5435
  }
5416
- const prevContext = this.context;
5417
- const migratingAnonymousAccount = await this.shouldMigrateAnonymousAccount();
5418
- this.keepContextOpen = migratingAnonymousAccount;
5419
- await this.createContext(this.props, {
5420
- newAccountProps: {
5421
- secret: accountSecret,
5422
- creationProps
5423
- }
5424
- }).finally(() => {
5425
- this.keepContextOpen = false;
5426
- });
5427
- if (migratingAnonymousAccount) {
5428
- await this.handleAnonymousAccountMigration(prevContext);
5436
+ if (this.authenticatingAccountID) {
5437
+ throw new Error("Authentication already in progress");
5429
5438
  }
5430
- if (this.context && "me" in this.context) {
5431
- return this.context.me.$jazz.id;
5439
+ this.authenticatingAccountID = "register";
5440
+ try {
5441
+ const prevContext = this.context;
5442
+ const migratingAnonymousAccount = await this.shouldMigrateAnonymousAccount();
5443
+ this.keepContextOpen = migratingAnonymousAccount;
5444
+ await this.createContext(this.props, {
5445
+ newAccountProps: {
5446
+ secret: accountSecret,
5447
+ creationProps
5448
+ }
5449
+ }).finally(() => {
5450
+ this.keepContextOpen = false;
5451
+ });
5452
+ if (migratingAnonymousAccount) {
5453
+ await this.handleAnonymousAccountMigration(prevContext);
5454
+ }
5455
+ if (this.context && "me" in this.context) {
5456
+ return this.context.me.$jazz.id;
5457
+ }
5458
+ throw new Error("The registration hasn't created a new account");
5459
+ } finally {
5460
+ this.authenticatingAccountID = null;
5432
5461
  }
5433
- throw new Error("The registration hasn't created a new account");
5434
5462
  };
5435
5463
  this.listeners = /* @__PURE__ */ new Set();
5436
5464
  this.subscribe = (callback) => {
@@ -5500,6 +5528,9 @@ var JazzContextManager = class {
5500
5528
  getAuthSecretStorage() {
5501
5529
  return this.authSecretStorage;
5502
5530
  }
5531
+ getAuthenticatingAccountID() {
5532
+ return this.authenticatingAccountID;
5533
+ }
5503
5534
  async handleAnonymousAccountMigration(prevContext) {
5504
5535
  if (!this.props) {
5505
5536
  throw new Error("Props required");
@@ -5911,4 +5942,4 @@ export {
5911
5942
  JazzContextManager
5912
5943
  };
5913
5944
  /* istanbul ignore file -- @preserve */
5914
- //# sourceMappingURL=chunk-QF3R3C4N.js.map
5945
+ //# sourceMappingURL=chunk-RQHJFPIB.js.map