jazz-tools 0.19.12 → 0.19.13

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 (119) hide show
  1. package/.turbo/turbo-build.log +50 -50
  2. package/CHANGELOG.md +10 -0
  3. package/dist/browser/createBrowserContext.d.ts +1 -5
  4. package/dist/browser/createBrowserContext.d.ts.map +1 -1
  5. package/dist/browser/index.js +124 -47
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/browser/provideBrowserLockSession/BrowserSessionProvider.d.ts +12 -0
  8. package/dist/browser/provideBrowserLockSession/BrowserSessionProvider.d.ts.map +1 -0
  9. package/dist/browser/provideBrowserLockSession/BrowserSessionProvider.test.d.ts +2 -0
  10. package/dist/browser/provideBrowserLockSession/BrowserSessionProvider.test.d.ts.map +1 -0
  11. package/dist/browser/provideBrowserLockSession/SessionIDStorage.d.ts +6 -0
  12. package/dist/browser/provideBrowserLockSession/SessionIDStorage.d.ts.map +1 -0
  13. package/dist/browser/provideBrowserLockSession/index.d.ts +4 -0
  14. package/dist/browser/provideBrowserLockSession/index.d.ts.map +1 -0
  15. package/dist/{chunk-AGF4HEDH.js → chunk-GAPMDNJY.js} +437 -82
  16. package/dist/chunk-GAPMDNJY.js.map +1 -0
  17. package/dist/index.js +5 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/react-native/index.js +41 -12
  20. package/dist/react-native/index.js.map +1 -1
  21. package/dist/react-native-core/ReactNativeSessionProvider.d.ts +11 -0
  22. package/dist/react-native-core/ReactNativeSessionProvider.d.ts.map +1 -0
  23. package/dist/react-native-core/index.js +41 -12
  24. package/dist/react-native-core/index.js.map +1 -1
  25. package/dist/react-native-core/platform.d.ts +2 -8
  26. package/dist/react-native-core/platform.d.ts.map +1 -1
  27. package/dist/react-native-core/tests/ReactNativeSessionProvider.test.d.ts +2 -0
  28. package/dist/react-native-core/tests/ReactNativeSessionProvider.test.d.ts.map +1 -0
  29. package/dist/testing.js +4 -3
  30. package/dist/testing.js.map +1 -1
  31. package/dist/tools/coValues/account.d.ts.map +1 -1
  32. package/dist/tools/coValues/coFeed.d.ts +2 -2
  33. package/dist/tools/coValues/coFeed.d.ts.map +1 -1
  34. package/dist/tools/coValues/coList.d.ts +1 -2
  35. package/dist/tools/coValues/coList.d.ts.map +1 -1
  36. package/dist/tools/coValues/coMap.d.ts.map +1 -1
  37. package/dist/tools/coValues/coVector.d.ts.map +1 -1
  38. package/dist/tools/coValues/group.d.ts +5 -1
  39. package/dist/tools/coValues/group.d.ts.map +1 -1
  40. package/dist/tools/coValues/interfaces.d.ts +2 -1
  41. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  42. package/dist/tools/exports.d.ts +2 -2
  43. package/dist/tools/exports.d.ts.map +1 -1
  44. package/dist/tools/implementation/createContext.d.ts +21 -11
  45. package/dist/tools/implementation/createContext.d.ts.map +1 -1
  46. package/dist/tools/implementation/schema.d.ts +14 -6
  47. package/dist/tools/implementation/schema.d.ts.map +1 -1
  48. package/dist/tools/implementation/schemaUtils.d.ts +1 -1
  49. package/dist/tools/implementation/schemaUtils.d.ts.map +1 -1
  50. package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
  51. package/dist/tools/implementation/zodSchema/schemaPermissions.d.ts +99 -0
  52. package/dist/tools/implementation/zodSchema/schemaPermissions.d.ts.map +1 -0
  53. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +11 -0
  54. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
  55. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +11 -0
  56. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
  57. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +15 -1
  58. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
  59. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +10 -0
  60. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
  61. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts +9 -0
  62. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts.map +1 -1
  63. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +13 -1
  64. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
  65. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +10 -0
  66. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
  67. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +6 -0
  68. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
  69. package/dist/tools/implementation/zodSchema/unionUtils.d.ts +12 -1
  70. package/dist/tools/implementation/zodSchema/unionUtils.d.ts.map +1 -1
  71. package/dist/tools/internal.d.ts +1 -0
  72. package/dist/tools/internal.d.ts.map +1 -1
  73. package/dist/tools/testing.d.ts.map +1 -1
  74. package/dist/tools/tests/schema.withPermissions.test.d.ts +2 -0
  75. package/dist/tools/tests/schema.withPermissions.test.d.ts.map +1 -0
  76. package/dist/worker/index.js +2 -2
  77. package/dist/worker/index.js.map +1 -1
  78. package/package.json +4 -4
  79. package/src/browser/createBrowserContext.ts +3 -62
  80. package/src/browser/provideBrowserLockSession/BrowserSessionProvider.test.ts +406 -0
  81. package/src/browser/provideBrowserLockSession/BrowserSessionProvider.ts +132 -0
  82. package/src/browser/provideBrowserLockSession/SessionIDStorage.ts +33 -0
  83. package/src/browser/provideBrowserLockSession/index.ts +11 -0
  84. package/src/react-native-core/ReactNativeSessionProvider.ts +52 -0
  85. package/src/react-native-core/platform.ts +5 -30
  86. package/src/react-native-core/tests/ReactNativeSessionProvider.test.ts +124 -0
  87. package/src/tools/coValues/account.ts +4 -0
  88. package/src/tools/coValues/coFeed.ts +8 -3
  89. package/src/tools/coValues/coList.ts +6 -3
  90. package/src/tools/coValues/coMap.ts +10 -0
  91. package/src/tools/coValues/coVector.ts +2 -1
  92. package/src/tools/coValues/group.ts +6 -4
  93. package/src/tools/coValues/interfaces.ts +19 -7
  94. package/src/tools/exports.ts +3 -1
  95. package/src/tools/implementation/createContext.ts +43 -15
  96. package/src/tools/implementation/schema.ts +23 -13
  97. package/src/tools/implementation/schemaUtils.ts +1 -1
  98. package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +105 -4
  99. package/src/tools/implementation/zodSchema/schemaPermissions.ts +188 -0
  100. package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +46 -3
  101. package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +46 -3
  102. package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +50 -13
  103. package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +14 -0
  104. package/src/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.ts +24 -1
  105. package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +51 -4
  106. package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +25 -1
  107. package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +21 -1
  108. package/src/tools/implementation/zodSchema/unionUtils.ts +72 -20
  109. package/src/tools/internal.ts +1 -0
  110. package/src/tools/testing.ts +3 -1
  111. package/src/tools/tests/ContextManager.test.ts +2 -1
  112. package/src/tools/tests/coPlainText.test.ts +2 -2
  113. package/src/tools/tests/createContext.test.ts +79 -1
  114. package/src/tools/tests/deepLoading.test.ts +25 -2
  115. package/src/tools/tests/schema.resolved.test.ts +10 -0
  116. package/src/tools/tests/schema.withPermissions.test.ts +859 -0
  117. package/src/tools/tests/utils.ts +2 -2
  118. package/src/worker/index.ts +2 -2
  119. package/dist/chunk-AGF4HEDH.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
 
2
- > jazz-tools@0.19.12 build /home/runner/_work/jazz/jazz/packages/jazz-tools
2
+ > jazz-tools@0.19.13 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","tools/ssr":"src/tools/ssr/index.ts"}
@@ -107,23 +107,23 @@
107
107
  ESM Build start
108
108
  CLI Cleaning output folder
109
109
  ESM Build start
110
- ESM dist/worker/index.js 3.19 KB
111
- ESM dist/worker/edge-wasm.js 215.00 B
112
- ESM dist/worker/napi-crypto.js 110.00 B
113
- ESM dist/worker/index.js.map 6.24 KB
114
- ESM dist/worker/edge-wasm.js.map 434.00 B
115
- ESM dist/worker/napi-crypto.js.map 162.00 B
116
- ESM ⚡️ Build success in 49ms
117
110
  ESM dist/tiptap/index.js 564.00 B
118
111
  ESM dist/tiptap/index.js.map 1.21 KB
119
- ESM ⚡️ Build success in 52ms
112
+ ESM ⚡️ Build success in 62ms
120
113
  ESM dist/better-auth/auth/client.js 4.50 KB
121
114
  ESM dist/better-auth/auth/server.js 8.36 KB
122
115
  ESM dist/better-auth/auth/react.js 799.00 B
123
116
  ESM dist/better-auth/auth/client.js.map 8.32 KB
124
117
  ESM dist/better-auth/auth/server.js.map 15.31 KB
125
118
  ESM dist/better-auth/auth/react.js.map 2.04 KB
126
- ESM ⚡️ Build success in 43ms
119
+ ESM ⚡️ Build success in 50ms
120
+ ESM dist/worker/index.js 3.19 KB
121
+ ESM dist/worker/edge-wasm.js 215.00 B
122
+ ESM dist/worker/napi-crypto.js 110.00 B
123
+ ESM dist/worker/index.js.map 6.26 KB
124
+ ESM dist/worker/edge-wasm.js.map 434.00 B
125
+ ESM dist/worker/napi-crypto.js.map 162.00 B
126
+ ESM ⚡️ Build success in 72ms
127
127
  ESM dist/media/index.js 236.00 B
128
128
  ESM dist/media/index.browser.js 2.79 KB
129
129
  ESM dist/media/index.native.js 4.01 KB
@@ -134,88 +134,88 @@
134
134
  ESM dist/media/index.native.js.map 8.10 KB
135
135
  ESM dist/media/index.server.js.map 6.37 KB
136
136
  ESM dist/media/chunk-3LKBM3G3.js.map 16.99 KB
137
- ESM ⚡️ Build success in 48ms
138
- ESM dist/react-core/testing.js 1.22 KB
137
+ ESM ⚡️ Build success in 82ms
139
138
  ESM dist/react-core/index.js 17.05 KB
139
+ ESM dist/react-core/testing.js 1.22 KB
140
140
  ESM dist/react-core/chunk-7DYMJ74I.js 279.00 B
141
- ESM dist/react-core/testing.js.map 1.86 KB
142
141
  ESM dist/react-core/index.js.map 49.77 KB
142
+ ESM dist/react-core/testing.js.map 1.86 KB
143
143
  ESM dist/react-core/chunk-7DYMJ74I.js.map 533.00 B
144
- ESM ⚡️ Build success in 47ms
144
+ ESM ⚡️ Build success in 91ms
145
145
  ESM dist/expo/index.js 4.68 KB
146
146
  ESM dist/expo/testing.js 112.00 B
147
- ESM dist/expo/polyfills.js 858.00 B
148
147
  ESM dist/expo/crypto.js 153.00 B
148
+ ESM dist/expo/polyfills.js 858.00 B
149
149
  ESM dist/expo/index.js.map 10.23 KB
150
150
  ESM dist/expo/testing.js.map 168.00 B
151
- ESM dist/expo/polyfills.js.map 1.61 KB
152
151
  ESM dist/expo/crypto.js.map 189.00 B
153
- ESM ⚡️ Build success in 52ms
154
- ESM dist/better-auth/database-adapter/index.js 26.65 KB
155
- ESM dist/better-auth/database-adapter/index.js.map 58.26 KB
156
- ESM ⚡️ Build success in 47ms
157
- ESM dist/browser/index.js 14.06 KB
158
- ESM dist/browser/index.js.map 29.94 KB
159
- ESM ⚡️ Build success in 70ms
152
+ ESM dist/expo/polyfills.js.map 1.61 KB
153
+ ESM ⚡️ Build success in 84ms
160
154
  ESM dist/prosemirror/index.js 77.76 KB
161
155
  ESM dist/prosemirror/index.js.map 307.20 KB
162
- ESM ⚡️ Build success in 79ms
156
+ ESM ⚡️ Build success in 108ms
157
+ ESM dist/better-auth/database-adapter/index.js 26.65 KB
158
+ ESM dist/better-auth/database-adapter/index.js.map 58.26 KB
159
+ ESM ⚡️ Build success in 93ms
160
+ ESM dist/browser/index.js 16.14 KB
161
+ ESM dist/browser/index.js.map 34.66 KB
162
+ ESM ⚡️ Build success in 114ms
163
+ ESM dist/react-native-core/index.js 19.96 KB
163
164
  ESM dist/react-native-core/testing.js 119.00 B
164
- ESM dist/react-native-core/index.js 19.19 KB
165
- ESM dist/react-native-core/crypto/RNCrypto.js 120.00 B
166
165
  ESM dist/react-native-core/crypto.js 2.58 KB
166
+ ESM dist/react-native-core/crypto/RNCrypto.js 120.00 B
167
+ ESM dist/react-native-core/index.js.map 40.58 KB
167
168
  ESM dist/react-native-core/testing.js.map 175.00 B
168
- ESM dist/react-native-core/index.js.map 38.96 KB
169
- ESM dist/react-native-core/crypto/RNCrypto.js.map 178.00 B
170
169
  ESM dist/react-native-core/crypto.js.map 5.25 KB
171
- ESM ⚡️ Build success in 78ms
172
- ESM dist/react/testing.js 122.00 B
173
- ESM dist/react/index.js 25.96 KB
174
- ESM dist/react/ssr.js 697.00 B
175
- ESM dist/react/testing.js.map 165.00 B
176
- ESM dist/react/ssr.js.map 1.11 KB
177
- ESM dist/react/index.js.map 55.44 KB
178
- ESM ⚡️ Build success in 70ms
170
+ ESM dist/react-native-core/crypto/RNCrypto.js.map 178.00 B
171
+ ESM ⚡️ Build success in 107ms
172
+ ESM dist/react-native/index.js 22.50 KB
179
173
  ESM dist/react-native/testing.js 120.00 B
180
174
  ESM dist/react-native/crypto.js 161.00 B
181
175
  ESM dist/react-native/polyfills.js 858.00 B
182
- ESM dist/react-native/index.js 21.73 KB
176
+ ESM dist/react-native/index.js.map 46.13 KB
183
177
  ESM dist/react-native/testing.js.map 176.00 B
184
178
  ESM dist/react-native/crypto.js.map 197.00 B
185
179
  ESM dist/react-native/polyfills.js.map 1.61 KB
186
- ESM dist/react-native/index.js.map 44.50 KB
187
- ESM ⚡️ Build success in 80ms
180
+ ESM ⚡️ Build success in 111ms
181
+ ESM dist/react/index.js 25.96 KB
182
+ ESM dist/react/testing.js 122.00 B
183
+ ESM dist/react/ssr.js 697.00 B
184
+ ESM dist/react/index.js.map 55.44 KB
185
+ ESM dist/react/testing.js.map 165.00 B
186
+ ESM dist/react/ssr.js.map 1.11 KB
187
+ ESM ⚡️ Build success in 111ms
188
188
  ESM dist/inspector/index.js 6.29 KB
189
189
  ESM dist/inspector/standalone.js 12.61 KB
190
190
  ESM dist/inspector/chunk-YQNK5Y7B.js 127.21 KB
191
191
  ESM dist/inspector/index.js.map 9.65 KB
192
192
  ESM dist/inspector/standalone.js.map 20.11 KB
193
193
  ESM dist/inspector/chunk-YQNK5Y7B.js.map 221.30 KB
194
- ESM ⚡️ Build success in 91ms
195
- ESM dist/index.js 29.76 KB
196
- ESM dist/testing.js 8.51 KB
197
- ESM dist/chunk-AGF4HEDH.js 214.23 KB
194
+ ESM ⚡️ Build success in 153ms
195
+ ESM dist/index.js 29.82 KB
196
+ ESM dist/testing.js 8.56 KB
198
197
  ESM dist/tools/ssr.js 156.00 B
199
198
  ESM dist/chunk-M2HGBOXS.js 694.00 B
200
199
  ESM dist/chunk-PZ5AY32C.js 233.00 B
200
+ ESM dist/chunk-GAPMDNJY.js 225.38 KB
201
201
  ESM dist/tools/ssr.js.map 71.00 B
202
- ESM dist/testing.js.map 16.13 KB
202
+ ESM dist/testing.js.map 16.21 KB
203
203
  ESM dist/chunk-PZ5AY32C.js.map 71.00 B
204
- ESM dist/chunk-M2HGBOXS.js.map 1.10 KB
205
204
  ESM dist/index.js.map 60.59 KB
206
- ESM dist/chunk-AGF4HEDH.js.map 504.49 KB
207
- ESM ⚡️ Build success in 93ms
205
+ ESM dist/chunk-M2HGBOXS.js.map 1.10 KB
206
+ ESM dist/chunk-GAPMDNJY.js.map 530.58 KB
207
+ ESM ⚡️ Build success in 193ms
208
208
  ESM dist/inspector/register-custom-element.js 218.00 B
209
209
  ESM dist/inspector/register-custom-element.js.map 314.00 B
210
210
  ESM dist/inspector/custom-element-KYV64IOC.js 1.60 MB
211
211
  ESM dist/inspector/custom-element-KYV64IOC.js.map 2.47 MB
212
- ESM ⚡️ Build success in 141ms
212
+ ESM ⚡️ Build success in 215ms
213
213
 
214
- > jazz-tools@0.19.12 types /home/runner/_work/jazz/jazz/packages/jazz-tools
214
+ > jazz-tools@0.19.13 types /home/runner/_work/jazz/jazz/packages/jazz-tools
215
215
  > tsc --outDir dist
216
216
 
217
217
 
218
- > jazz-tools@0.19.12 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
218
+ > jazz-tools@0.19.13 build:svelte /home/runner/_work/jazz/jazz/packages/jazz-tools
219
219
  > rm -rf dist/svelte && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json
220
220
 
221
221
  src/svelte -> dist/svelte
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # jazz-tools
2
2
 
3
+ ## 0.19.13
4
+
5
+ ### Patch Changes
6
+
7
+ - bef1cc6: Bugfix: rewrittern the session provider to prevent race conditions and reuse also the new accounts sessions
8
+ - b839147: Add schema-level permissions to centralize permission configuration
9
+ - cojson@0.19.13
10
+ - cojson-storage-indexeddb@0.19.13
11
+ - cojson-transport-ws@0.19.13
12
+
3
13
  ## 0.19.12
4
14
 
5
15
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { LocalNode, RawAccountID } from "cojson";
1
+ import { LocalNode } from "cojson";
2
2
  import { Account, AccountClass, AgentID, AnyAccountSchema, AuthCredentials, AuthSecretStorage, CoValue, CoValueFromRaw, CryptoProvider, ID, InviteSecret, NewAccountProps, SessionID, SyncConfig } from "jazz-tools";
3
3
  import { StorageConfig } from "./storageOptions.js";
4
4
  export type BaseBrowserContextOptions = {
@@ -33,10 +33,6 @@ export declare function createJazzBrowserContext<S extends (AccountClass<Account
33
33
  }>;
34
34
  /** @category Auth Providers */
35
35
  export type SessionProvider = (accountID: ID<Account> | AgentID) => Promise<SessionID>;
36
- export declare function provideBrowserLockSession(accountID: ID<Account> | AgentID, crypto: CryptoProvider): Promise<{
37
- sessionID: `${RawAccountID}_session_z${string}` | `sealer_z${string}/signer_z${string}_session_z${string}`;
38
- sessionDone: () => void;
39
- }>;
40
36
  /** @category Invite Links */
41
37
  export declare function createInviteLink<C extends CoValue>(value: C, role: "reader" | "writer" | "admin" | "writeOnly", { baseURL, valueHint, }?: {
42
38
  baseURL?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"createBrowserContext.d.ts","sourceRoot":"","sources":["../../src/browser/createBrowserContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAQ,YAAY,EAAE,MAAM,QAAQ,CAAC;AAIvD,OAAO,EACL,OAAO,EACP,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,cAAc,EACd,EAAE,EACF,YAAY,EACZ,eAAe,EACf,SAAS,EACT,UAAU,EAGX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAKvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,iBAAiB,CAAC;CACtC,CAAC;AAuFF,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,yBAAyB;;;;;sCAlBA,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;GAsD/D;AAED,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SACG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GACjD,gBAAgB,IAClB;IACF,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,yBAAyB,CAAC;AAE9B,wBAAsB,wBAAwB,CAC5C,CAAC,SACG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GACjD,gBAAgB,EACpB,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;;;;;;sCAvEC,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;GAmI/D;AAED,+BAA+B;AAC/B,MAAM,MAAM,eAAe,GAAG,CAC5B,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,KAC7B,OAAO,CAAC,SAAS,CAAC,CAAC;AAExB,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,EAChC,MAAM,EAAE,cAAc;;;GAwDvB;AAED,6BAA6B;AAC7B,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAChD,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,EAEjD,EACE,OAAkD,EAClD,SAAS,GACV,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,MAAM,CAoBR;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/C,SAAS,EAAE,MAAM,GAEf;IACE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;CAC5B,GACD,SAAS,CAuBZ"}
1
+ {"version":3,"file":"createBrowserContext.d.ts","sourceRoot":"","sources":["../../src/browser/createBrowserContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAQ,MAAM,QAAQ,CAAC;AAIzC,OAAO,EACL,OAAO,EACP,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,cAAc,EACd,EAAE,EACF,YAAY,EACZ,eAAe,EACf,SAAS,EACT,UAAU,EAGX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAMvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,iBAAiB,CAAC;CACtC,CAAC;AAuFF,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,yBAAyB;;;;;sCAlBA,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;GAsD/D;AAED,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SACG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GACjD,gBAAgB,IAClB;IACF,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,yBAAyB,CAAC;AAE9B,wBAAsB,wBAAwB,CAC5C,CAAC,SACG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GACjD,gBAAgB,EACpB,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;;;;;;sCAvEC,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;GAmI/D;AAED,+BAA+B;AAC/B,MAAM,MAAM,eAAe,GAAG,CAC5B,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,KAC7B,OAAO,CAAC,SAAS,CAAC,CAAC;AAExB,6BAA6B;AAC7B,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAChD,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,EAEjD,EACE,OAAkD,EAClD,SAAS,GACV,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,MAAM,CAoBR;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAC/C,SAAS,EAAE,MAAM,GAEf;IACE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;CAC5B,GACD,SAAS,CAuBZ"}
@@ -198,6 +198,128 @@ function getStorageOptions(storage) {
198
198
  return { useIndexedDB };
199
199
  }
200
200
 
201
+ // src/browser/provideBrowserLockSession/index.ts
202
+ import { MockSessionProvider } from "jazz-tools";
203
+
204
+ // src/browser/provideBrowserLockSession/SessionIDStorage.ts
205
+ function getSessionKey(accountID, index) {
206
+ return accountID + "_" + index;
207
+ }
208
+ var SessionIDStorage = class {
209
+ static getSessionsList(accountID) {
210
+ let sessionsList = [];
211
+ let i = 0;
212
+ let lastSessionID;
213
+ do {
214
+ lastSessionID = localStorage.getItem(
215
+ getSessionKey(accountID, i)
216
+ );
217
+ if (lastSessionID) {
218
+ sessionsList.push(lastSessionID);
219
+ }
220
+ i++;
221
+ } while (lastSessionID);
222
+ return sessionsList;
223
+ }
224
+ static storeSessionID(accountID, sessionID, index) {
225
+ localStorage.setItem(getSessionKey(accountID, index), sessionID);
226
+ }
227
+ };
228
+
229
+ // src/browser/provideBrowserLockSession/BrowserSessionProvider.ts
230
+ var BrowserSessionProvider = class {
231
+ async acquireSession(accountID, crypto) {
232
+ const { sessionPromise, resolveSession } = createSessionLockPromise();
233
+ const sessionsList = SessionIDStorage.getSessionsList(accountID);
234
+ for (const [index, sessionID] of sessionsList.entries()) {
235
+ const sessionAcquired = await tryToAcquireSession(
236
+ sessionID,
237
+ sessionPromise
238
+ );
239
+ if (sessionAcquired) {
240
+ console.log("Using existing session", sessionID, "at index", index);
241
+ return {
242
+ sessionID,
243
+ sessionDone: resolveSession
244
+ };
245
+ }
246
+ }
247
+ const newSessionID = crypto.newRandomSessionID(
248
+ accountID
249
+ );
250
+ await lockAndStoreSession(accountID, newSessionID, sessionPromise);
251
+ console.log("Created new session", newSessionID);
252
+ return {
253
+ sessionID: newSessionID,
254
+ sessionDone: resolveSession
255
+ };
256
+ }
257
+ async persistSession(accountID, sessionID) {
258
+ const { sessionPromise, resolveSession } = createSessionLockPromise();
259
+ await lockAndStoreSession(accountID, sessionID, sessionPromise);
260
+ console.log("Stored new session", sessionID);
261
+ return { sessionDone: resolveSession };
262
+ }
263
+ };
264
+ async function lockAndStoreSession(accountID, sessionID, sessionPromise) {
265
+ const sessionAcquired = await tryToAcquireSession(sessionID, sessionPromise);
266
+ if (!sessionAcquired) {
267
+ throw new Error("Couldn't get lock on new session");
268
+ }
269
+ storeSessionID(accountID, sessionID);
270
+ }
271
+ function tryToAcquireSession(sessionID, sessionDonePromise) {
272
+ return new Promise((resolve) => {
273
+ navigator.locks.request(
274
+ `load_session_${sessionID}`,
275
+ { mode: "exclusive", ifAvailable: true },
276
+ async (lock) => {
277
+ if (!lock) {
278
+ resolve(false);
279
+ return;
280
+ }
281
+ resolve(true);
282
+ return sessionDonePromise;
283
+ }
284
+ );
285
+ });
286
+ }
287
+ function storeSessionID(accountID, sessionID) {
288
+ return navigator.locks.request(
289
+ `store_session_${accountID}`,
290
+ { mode: "exclusive" },
291
+ async (lock) => {
292
+ if (!lock) {
293
+ console.error("Couldn't get lock to store session ID", accountID);
294
+ }
295
+ const sessionsList = SessionIDStorage.getSessionsList(accountID);
296
+ SessionIDStorage.storeSessionID(
297
+ accountID,
298
+ sessionID,
299
+ sessionsList.length
300
+ );
301
+ }
302
+ );
303
+ }
304
+ function createSessionLockPromise() {
305
+ let resolveSession;
306
+ const sessionPromise = new Promise((resolve) => {
307
+ resolveSession = resolve;
308
+ });
309
+ return {
310
+ sessionPromise,
311
+ resolveSession
312
+ };
313
+ }
314
+
315
+ // src/browser/provideBrowserLockSession/index.ts
316
+ function getBrowserLockSessionProvider() {
317
+ if (typeof navigator === "undefined" || !navigator.locks?.request) {
318
+ return new MockSessionProvider();
319
+ }
320
+ return new BrowserSessionProvider();
321
+ }
322
+
201
323
  // src/browser/createBrowserContext.ts
202
324
  setupInspector();
203
325
  var BrowserWebSocketPeerWithReconnection = class extends WebSocketPeerWithReconnection {
@@ -340,7 +462,7 @@ async function createJazzBrowserContext(options) {
340
462
  crypto,
341
463
  defaultProfileName: options.defaultProfileName,
342
464
  AccountSchema: options.AccountSchema,
343
- sessionProvider: provideBrowserLockSession,
465
+ sessionProvider: getBrowserLockSessionProvider(),
344
466
  authSecretStorage: options.authSecretStorage
345
467
  });
346
468
  setNode(context.node);
@@ -361,50 +483,6 @@ async function createJazzBrowserContext(options) {
361
483
  connected
362
484
  };
363
485
  }
364
- function provideBrowserLockSession(accountID, crypto) {
365
- if (typeof navigator === "undefined" || !navigator.locks?.request) {
366
- return Promise.resolve({
367
- sessionID: crypto.newRandomSessionID(accountID),
368
- sessionDone: () => {
369
- }
370
- });
371
- }
372
- let sessionDone;
373
- const donePromise = new Promise((resolve) => {
374
- sessionDone = resolve;
375
- });
376
- let resolveSession;
377
- const sessionPromise = new Promise((resolve) => {
378
- resolveSession = resolve;
379
- });
380
- void async function() {
381
- for (let idx = 0; idx < 100; idx++) {
382
- for (let retry = 0; retry < 2; retry++) {
383
- const sessionFinishedOrNoLock = await navigator.locks.request(
384
- accountID + "_" + idx,
385
- { ifAvailable: true },
386
- async (lock) => {
387
- if (!lock) return "noLock";
388
- const sessionID = localStorage.getItem(accountID + "_" + idx) || crypto.newRandomSessionID(accountID);
389
- localStorage.setItem(accountID + "_" + idx, sessionID);
390
- resolveSession(sessionID);
391
- await donePromise;
392
- console.log("Done with lock", accountID + "_" + idx, sessionID);
393
- return "sessionFinished";
394
- }
395
- );
396
- if (sessionFinishedOrNoLock === "sessionFinished") {
397
- return;
398
- }
399
- }
400
- }
401
- throw new Error("Couldn't get lock on session after 100x2 tries");
402
- }();
403
- return sessionPromise.then((sessionID) => ({
404
- sessionID,
405
- sessionDone
406
- }));
407
- }
408
486
 
409
487
  // src/browser/BrowserContextManager.ts
410
488
  import {
@@ -504,7 +582,6 @@ export {
504
582
  createInviteLink,
505
583
  createJazzBrowserContext,
506
584
  createJazzBrowserGuestContext,
507
- parseInviteLink,
508
- provideBrowserLockSession
585
+ parseInviteLink
509
586
  };
510
587
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/browser/index.ts","../../src/browser/utils/export-account-inspector.ts","../../src/browser/auth/PasskeyAuth.ts","../../src/browser/createBrowserContext.ts","../../src/browser/storageOptions.ts","../../src/browser/BrowserContextManager.ts","../../src/browser/auth/LocalStorageKVStore.ts"],"sourcesContent":["import { AccountRole } from \"cojson\";\nimport {\n Account,\n CoValue,\n CoValueClassOrSchema,\n InviteSecret,\n createInviteLink as baseCreateInviteLink,\n consumeInviteLink,\n} from \"jazz-tools\";\nimport { setupInspector } from \"./utils/export-account-inspector.js\";\nexport { BrowserPasskeyAuth } from \"./auth/PasskeyAuth.js\";\n\nsetupInspector();\n\nexport * from \"./createBrowserContext.js\";\nexport * from \"./BrowserContextManager.js\";\n\nexport { LocalStorageKVStore } from \"./auth/LocalStorageKVStore.js\";\n\n/** @category Invite Links */\nexport function createInviteLink<C extends CoValue>(\n value: C,\n role: AccountRole,\n // default to same address as window.location, but without hash\n {\n baseURL = window.location.href.replace(/#.*$/, \"\"),\n valueHint,\n }: { baseURL?: string; valueHint?: string } = {},\n): string {\n return baseCreateInviteLink(value, role, baseURL, valueHint);\n}\n\n/** @category Invite Links */\nexport { parseInviteLink } from \"jazz-tools\";\n\n/** @category Invite Links */\nexport async function consumeInviteLinkFromWindowLocation<\n S extends CoValueClassOrSchema,\n>({\n as,\n forValueHint,\n invitedObjectSchema,\n}: {\n as?: Account;\n forValueHint?: string;\n invitedObjectSchema: S;\n}): Promise<\n | {\n valueID: string;\n valueHint?: string;\n inviteSecret: InviteSecret;\n }\n | undefined\n> {\n const result = await consumeInviteLink({\n inviteURL: window.location.href,\n as,\n forValueHint,\n invitedObjectSchema,\n });\n\n if (result) {\n window.history.replaceState(\n {},\n \"\",\n window.location.href.replace(/#.*$/, \"\"),\n );\n }\n\n return result;\n}\n","import { AuthSecretStorage } from \"jazz-tools\";\n\nasync function exportAccountToInspector() {\n const authSecretStorage = new AuthSecretStorage();\n const localStorageData = await authSecretStorage.get();\n\n if (!localStorageData) {\n console.error(\"No account data found in localStorage\");\n return;\n }\n\n const encodedAccountSecret = btoa(localStorageData.accountSecret);\n window.open(\n new URL(\n `#/import/${localStorageData?.accountID}/${encodedAccountSecret}`,\n \"https://inspector.jazz.tools\",\n ).toString(),\n \"_blank\",\n );\n}\n\nfunction listenForCmdJ() {\n if (typeof window === \"undefined\") return;\n\n const cb = (e: any) => {\n if (e.metaKey && e.key === \"j\") {\n if (\n confirm(\n \"Are you sure you want to inspect your account using inspector.jazz.tools? This lets anyone with the secret inspector URL read your data and impersonate you.\",\n )\n ) {\n exportAccountToInspector();\n }\n }\n };\n\n window.addEventListener(\"keydown\", cb);\n\n return () => {\n window.removeEventListener(\"keydown\", cb);\n };\n}\n\n/**\n * Automatically sets up the Cmd+J listener if 'allowJazzInspector' is present in the URL\n * @returns A cleanup function if the listener was set up, undefined otherwise\n */\nexport function setupInspector() {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n if (\n url.hash.includes(\"allowJazzInspector\") ||\n process.env.NODE_ENV === \"development\"\n ) {\n return listenForCmdJ();\n }\n}\n","import { CryptoProvider, RawAccountID, cojsonInternals } from \"cojson\";\nimport {\n Account,\n AuthSecretStorage,\n AuthenticateAccountFunction,\n ID,\n} from \"jazz-tools\";\n\n/**\n * `BrowserPasskeyAuth` provides a `JazzAuth` object for passkey authentication.\n *\n * ```ts\n * import { BrowserPasskeyAuth } from \"jazz-tools/browser\";\n *\n * const auth = new BrowserPasskeyAuth(driver, appName);\n * ```\n *\n * @category Auth Providers\n */\nexport class BrowserPasskeyAuth {\n constructor(\n protected crypto: CryptoProvider,\n protected authenticate: AuthenticateAccountFunction,\n protected authSecretStorage: AuthSecretStorage,\n public appName: string,\n public appHostname: string = window.location.hostname,\n ) {}\n\n static readonly id = \"passkey\";\n\n logIn = async () => {\n const { crypto, authenticate } = this;\n\n const webAuthNCredential = await this.getPasskeyCredentials();\n\n if (!webAuthNCredential) {\n return;\n }\n\n const webAuthNCredentialPayload = new Uint8Array(\n webAuthNCredential.response.userHandle,\n );\n const accountSecretSeed = webAuthNCredentialPayload.slice(\n 0,\n cojsonInternals.secretSeedLength,\n );\n\n const secret = crypto.agentSecretFromSecretSeed(accountSecretSeed);\n\n const accountID = cojsonInternals.rawCoIDfromBytes(\n webAuthNCredentialPayload.slice(\n cojsonInternals.secretSeedLength,\n cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength,\n ),\n ) as ID<Account>;\n\n await authenticate({\n accountID,\n accountSecret: secret,\n });\n\n await this.authSecretStorage.set({\n accountID,\n secretSeed: accountSecretSeed,\n accountSecret: secret,\n provider: \"passkey\",\n });\n };\n\n signUp = async (username: string) => {\n const credentials = await this.authSecretStorage.get();\n\n if (!credentials?.secretSeed) {\n throw new Error(\n \"Not enough credentials to register the account with passkey\",\n );\n }\n\n await this.createPasskeyCredentials({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n username,\n });\n\n const currentAccount = await Account.getMe().$jazz.ensureLoaded({\n resolve: {\n profile: true,\n },\n });\n\n if (username.trim().length !== 0) {\n currentAccount.profile.$jazz.set(\"name\", username);\n }\n\n await this.authSecretStorage.set({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n accountSecret: credentials.accountSecret,\n provider: \"passkey\",\n });\n };\n\n private async createPasskeyCredentials({\n accountID,\n secretSeed,\n username,\n }: {\n accountID: ID<Account>;\n secretSeed: Uint8Array;\n username: string;\n }) {\n const webAuthNCredentialPayload = new Uint8Array(\n cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength,\n );\n\n webAuthNCredentialPayload.set(secretSeed);\n webAuthNCredentialPayload.set(\n cojsonInternals.rawCoIDtoBytes(accountID as unknown as RawAccountID),\n cojsonInternals.secretSeedLength,\n );\n\n try {\n await navigator.credentials.create({\n publicKey: {\n challenge: new Uint8Array(this.crypto.randomBytes(20)),\n rp: {\n name: this.appName,\n id: this.appHostname,\n },\n user: {\n id: webAuthNCredentialPayload,\n name: username + ` (${new Date().toLocaleString()})`,\n displayName: username,\n },\n pubKeyCredParams: [\n { alg: -7, type: \"public-key\" },\n { alg: -8, type: \"public-key\" },\n { alg: -37, type: \"public-key\" },\n { alg: -257, type: \"public-key\" },\n ],\n authenticatorSelection: {\n requireResidentKey: true,\n residentKey: \"required\",\n userVerification: \"preferred\",\n },\n timeout: 60000,\n attestation: \"direct\",\n },\n });\n } catch (error) {\n throw new Error(\"Passkey creation aborted\", { cause: error });\n }\n }\n\n private async getPasskeyCredentials() {\n try {\n const value = await navigator.credentials.get({\n publicKey: {\n challenge: new Uint8Array(this.crypto.randomBytes(20)),\n rpId: this.appHostname,\n allowCredentials: [],\n timeout: 60000,\n userVerification: \"preferred\",\n },\n mediation: \"optional\",\n });\n\n return value as\n | (Credential & { response: { userHandle: ArrayBuffer } })\n | null;\n } catch (error) {\n throw new Error(\"Passkey creation aborted\", { cause: error });\n }\n }\n}\n","import { LocalNode, Peer, RawAccountID } from \"cojson\";\nimport { getIndexedDBStorage } from \"cojson-storage-indexeddb\";\nimport { WebSocketPeerWithReconnection } from \"cojson-transport-ws\";\nimport { WasmCrypto } from \"cojson/crypto/WasmCrypto\";\nimport {\n Account,\n AccountClass,\n AgentID,\n AnyAccountSchema,\n AuthCredentials,\n AuthSecretStorage,\n CoValue,\n CoValueFromRaw,\n CryptoProvider,\n ID,\n InviteSecret,\n NewAccountProps,\n SessionID,\n SyncConfig,\n cojsonInternals,\n createAnonymousJazzContext,\n} from \"jazz-tools\";\nimport { createJazzContext } from \"jazz-tools\";\nimport { StorageConfig, getStorageOptions } from \"./storageOptions.js\";\nimport { setupInspector } from \"./utils/export-account-inspector.js\";\n\nsetupInspector();\n\nexport type BaseBrowserContextOptions = {\n sync: SyncConfig;\n reconnectionTimeout?: number;\n storage?: StorageConfig;\n crypto?: CryptoProvider;\n authSecretStorage: AuthSecretStorage;\n};\n\nclass BrowserWebSocketPeerWithReconnection extends WebSocketPeerWithReconnection {\n onNetworkChange(callback: (connected: boolean) => void): () => void {\n const handler = () => callback(navigator.onLine);\n window.addEventListener(\"online\", handler);\n window.addEventListener(\"offline\", handler);\n\n return () => {\n window.removeEventListener(\"online\", handler);\n window.removeEventListener(\"offline\", handler);\n };\n }\n}\n\nasync function setupPeers(options: BaseBrowserContextOptions) {\n const crypto = options.crypto || (await WasmCrypto.create());\n let node: LocalNode | undefined = undefined;\n\n const { useIndexedDB } = getStorageOptions(options.storage);\n\n const peers: Peer[] = [];\n\n const storage = useIndexedDB ? await getIndexedDBStorage() : undefined;\n\n if (options.sync.when === \"never\") {\n return {\n addConnectionListener: () => () => {},\n connected: () => false,\n toggleNetwork: () => {},\n peers,\n storage,\n setNode: () => {},\n crypto,\n };\n }\n\n const wsPeer = new BrowserWebSocketPeerWithReconnection({\n peer: options.sync.peer,\n reconnectionTimeout: options.reconnectionTimeout,\n addPeer: (peer) => {\n if (node) {\n node.syncManager.addPeer(peer);\n } else {\n peers.push(peer);\n }\n },\n removePeer: (peer) => {\n peers.splice(peers.indexOf(peer), 1);\n },\n });\n\n function toggleNetwork(enabled: boolean) {\n if (enabled) {\n wsPeer.enable();\n } else {\n wsPeer.disable();\n }\n }\n\n function setNode(value: LocalNode) {\n node = value;\n }\n\n if (options.sync.when === \"always\" || !options.sync.when) {\n toggleNetwork(true);\n }\n\n return {\n toggleNetwork,\n addConnectionListener(listener: (connected: boolean) => void) {\n wsPeer.subscribe(listener);\n\n return () => {\n wsPeer.unsubscribe(listener);\n };\n },\n connected() {\n return wsPeer.connected;\n },\n peers,\n storage,\n setNode,\n crypto,\n };\n}\n\nexport async function createJazzBrowserGuestContext(\n options: BaseBrowserContextOptions,\n) {\n const {\n toggleNetwork,\n peers,\n setNode,\n crypto,\n storage,\n addConnectionListener,\n connected,\n } = await setupPeers(options);\n\n const context = await createAnonymousJazzContext({\n crypto,\n peers,\n storage,\n });\n\n setNode(context.agent.node);\n\n options.authSecretStorage.emitUpdate(null);\n\n return {\n guest: context.agent,\n node: context.agent.node,\n done: () => {\n // TODO: Sync all the covalues before closing the connection & context\n toggleNetwork(false);\n context.done();\n },\n logOut: () => {\n return context.logOut();\n },\n addConnectionListener,\n connected,\n };\n}\n\nexport type BrowserContextOptions<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> = {\n credentials?: AuthCredentials;\n AccountSchema?: S;\n newAccountProps?: NewAccountProps;\n defaultProfileName?: string;\n} & BaseBrowserContextOptions;\n\nexport async function createJazzBrowserContext<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n>(options: BrowserContextOptions<S>) {\n const {\n toggleNetwork,\n peers,\n setNode,\n crypto,\n storage,\n addConnectionListener,\n connected,\n } = await setupPeers(options);\n\n let unsubscribeAuthUpdate = () => {};\n\n if (options.sync.when === \"signedUp\") {\n const authSecretStorage = options.authSecretStorage;\n const credentials = options.credentials ?? (await authSecretStorage.get());\n\n function handleAuthUpdate(isAuthenticated: boolean) {\n if (isAuthenticated) {\n toggleNetwork(true);\n } else {\n toggleNetwork(false);\n }\n }\n\n unsubscribeAuthUpdate = authSecretStorage.onUpdate(handleAuthUpdate);\n handleAuthUpdate(authSecretStorage.getIsAuthenticated(credentials));\n }\n\n const context = await createJazzContext({\n credentials: options.credentials,\n newAccountProps: options.newAccountProps,\n peers,\n storage,\n crypto,\n defaultProfileName: options.defaultProfileName,\n AccountSchema: options.AccountSchema,\n sessionProvider: provideBrowserLockSession,\n authSecretStorage: options.authSecretStorage,\n });\n\n setNode(context.node);\n\n return {\n me: context.account,\n node: context.node,\n authSecretStorage: context.authSecretStorage,\n done: () => {\n // TODO: Sync all the covalues before closing the connection & context\n toggleNetwork(false);\n unsubscribeAuthUpdate();\n context.done();\n },\n logOut: () => {\n unsubscribeAuthUpdate();\n return context.logOut();\n },\n addConnectionListener,\n connected,\n };\n}\n\n/** @category Auth Providers */\nexport type SessionProvider = (\n accountID: ID<Account> | AgentID,\n) => Promise<SessionID>;\n\nexport function provideBrowserLockSession(\n accountID: ID<Account> | AgentID,\n crypto: CryptoProvider,\n) {\n if (typeof navigator === \"undefined\" || !navigator.locks?.request) {\n // Fallback to random session ID for each tab session\n return Promise.resolve({\n sessionID: crypto.newRandomSessionID(accountID as RawAccountID | AgentID),\n sessionDone: () => {},\n });\n }\n\n let sessionDone!: () => void;\n const donePromise = new Promise<void>((resolve) => {\n sessionDone = resolve;\n });\n\n let resolveSession: (sessionID: SessionID) => void;\n const sessionPromise = new Promise<SessionID>((resolve) => {\n resolveSession = resolve;\n });\n\n void (async function () {\n for (let idx = 0; idx < 100; idx++) {\n // To work better around StrictMode\n for (let retry = 0; retry < 2; retry++) {\n // console.debug(\"Trying to get lock\", accountID + \"_\" + idx);\n const sessionFinishedOrNoLock = await navigator.locks.request(\n accountID + \"_\" + idx,\n { ifAvailable: true },\n async (lock) => {\n if (!lock) return \"noLock\";\n\n const sessionID =\n localStorage.getItem(accountID + \"_\" + idx) ||\n crypto.newRandomSessionID(accountID as RawAccountID | AgentID);\n localStorage.setItem(accountID + \"_\" + idx, sessionID);\n\n resolveSession(sessionID as SessionID);\n\n await donePromise;\n console.log(\"Done with lock\", accountID + \"_\" + idx, sessionID);\n return \"sessionFinished\";\n },\n );\n\n if (sessionFinishedOrNoLock === \"sessionFinished\") {\n return;\n }\n }\n }\n throw new Error(\"Couldn't get lock on session after 100x2 tries\");\n })();\n\n return sessionPromise.then((sessionID) => ({\n sessionID,\n sessionDone,\n }));\n}\n\n/** @category Invite Links */\nexport function createInviteLink<C extends CoValue>(\n value: C,\n role: \"reader\" | \"writer\" | \"admin\" | \"writeOnly\",\n // default to same address as window.location, but without hash\n {\n baseURL = window.location.href.replace(/#.*$/, \"\"),\n valueHint,\n }: { baseURL?: string; valueHint?: string } = {},\n): string {\n const coValueCore = value.$jazz.raw.core;\n let currentCoValue = coValueCore;\n\n while (currentCoValue.verified.header.ruleset.type === \"ownedByGroup\") {\n currentCoValue = currentCoValue.getGroup().core;\n }\n\n const { ruleset, meta } = currentCoValue.verified.header;\n\n if (ruleset.type !== \"group\" || meta?.type === \"account\") {\n throw new Error(\"Can't create invite link for object without group\");\n }\n\n const group = cojsonInternals.expectGroup(currentCoValue.getCurrentContent());\n const inviteSecret = group.createInvite(role);\n\n return `${baseURL}#/invite/${valueHint ? valueHint + \"/\" : \"\"}${\n value.$jazz.id\n }/${inviteSecret}`;\n}\n\n/** @category Invite Links */\nexport function parseInviteLink<C extends CoValue>(\n inviteURL: string,\n):\n | {\n valueID: ID<C>;\n valueHint?: string;\n inviteSecret: InviteSecret;\n }\n | undefined {\n const url = new URL(inviteURL);\n const parts = url.hash.split(\"/\");\n\n let valueHint: string | undefined;\n let valueID: ID<C> | undefined;\n let inviteSecret: InviteSecret | undefined;\n\n if (parts[0] === \"#\" && parts[1] === \"invite\") {\n if (parts.length === 5) {\n valueHint = parts[2];\n valueID = parts[3] as ID<C>;\n inviteSecret = parts[4] as InviteSecret;\n } else if (parts.length === 4) {\n valueID = parts[2] as ID<C>;\n inviteSecret = parts[3] as InviteSecret;\n }\n\n if (!valueID || !inviteSecret) {\n return undefined;\n }\n return { valueID, inviteSecret, valueHint };\n }\n}\n","type StorageOption = \"indexedDB\";\ntype CombinedStorageOption = [\"indexedDB\"];\nexport type StorageConfig =\n | StorageOption\n | CombinedStorageOption\n | [StorageOption];\n\nexport function getStorageOptions(storage?: StorageConfig): {\n useIndexedDB: boolean;\n} {\n const useIndexedDB =\n !storage ||\n (Array.isArray(storage) && storage.includes(\"indexedDB\")) ||\n storage === \"indexedDB\";\n\n return { useIndexedDB };\n}\n","import {\n Account,\n AccountClass,\n AnyAccountSchema,\n CoValueFromRaw,\n InMemoryKVStore,\n InstanceOfSchema,\n JazzContextManager,\n SyncConfig,\n} from \"jazz-tools\";\nimport { JazzContextManagerAuthProps } from \"jazz-tools\";\nimport { LocalStorageKVStore } from \"./auth/LocalStorageKVStore.js\";\nimport {\n BaseBrowserContextOptions,\n createJazzBrowserContext,\n createJazzBrowserGuestContext,\n} from \"./createBrowserContext.js\";\n\nexport type JazzContextManagerProps<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> = {\n guestMode?: boolean;\n sync: SyncConfig;\n onLogOut?: () => void;\n logOutReplacement?: () => void;\n onAnonymousAccountDiscarded?: (\n anonymousAccount: InstanceOfSchema<S>,\n ) => Promise<void>;\n storage?: BaseBrowserContextOptions[\"storage\"];\n AccountSchema?: S;\n defaultProfileName?: string;\n};\n\nexport class JazzBrowserContextManager<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> extends JazzContextManager<InstanceOfSchema<S>, JazzContextManagerProps<S>> {\n // TODO: When the storage changes, if the user is changed, update the context\n getKvStore() {\n if (typeof window === \"undefined\") {\n // To handle running in SSR\n return new InMemoryKVStore();\n } else {\n return new LocalStorageKVStore();\n }\n }\n\n async getNewContext(\n props: JazzContextManagerProps<S>,\n authProps?: JazzContextManagerAuthProps,\n ) {\n if (props.guestMode) {\n return createJazzBrowserGuestContext({\n sync: props.sync,\n storage: props.storage,\n authSecretStorage: this.authSecretStorage,\n });\n } else {\n return createJazzBrowserContext<S>({\n sync: props.sync,\n storage: props.storage,\n AccountSchema: props.AccountSchema,\n credentials: authProps?.credentials,\n newAccountProps: authProps?.newAccountProps,\n defaultProfileName: props.defaultProfileName,\n authSecretStorage: this.authSecretStorage,\n });\n }\n }\n\n propsChanged(props: JazzContextManagerProps<S>) {\n if (!this.props) {\n return true;\n }\n\n return (\n this.props.sync.when !== props.sync.when ||\n this.props.sync.peer !== props.sync.peer ||\n this.props.guestMode !== props.guestMode\n );\n }\n}\n","import { KvStore } from \"jazz-tools\";\n\nexport class LocalStorageKVStore implements KvStore {\n constructor() {}\n\n async get(key: string) {\n return localStorage.getItem(key);\n }\n\n async set(key: string, value: string) {\n localStorage.setItem(key, value);\n }\n\n async delete(key: string) {\n localStorage.removeItem(key);\n }\n\n async clearAll() {\n localStorage.clear();\n }\n}\n"],"mappings":"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","names":["cojsonInternals","handleAuthUpdate"]}
1
+ {"version":3,"sources":["../../src/browser/index.ts","../../src/browser/utils/export-account-inspector.ts","../../src/browser/auth/PasskeyAuth.ts","../../src/browser/createBrowserContext.ts","../../src/browser/storageOptions.ts","../../src/browser/provideBrowserLockSession/index.ts","../../src/browser/provideBrowserLockSession/SessionIDStorage.ts","../../src/browser/provideBrowserLockSession/BrowserSessionProvider.ts","../../src/browser/BrowserContextManager.ts","../../src/browser/auth/LocalStorageKVStore.ts"],"sourcesContent":["import { AccountRole } from \"cojson\";\nimport {\n Account,\n CoValue,\n CoValueClassOrSchema,\n InviteSecret,\n createInviteLink as baseCreateInviteLink,\n consumeInviteLink,\n} from \"jazz-tools\";\nimport { setupInspector } from \"./utils/export-account-inspector.js\";\nexport { BrowserPasskeyAuth } from \"./auth/PasskeyAuth.js\";\n\nsetupInspector();\n\nexport * from \"./createBrowserContext.js\";\nexport * from \"./BrowserContextManager.js\";\n\nexport { LocalStorageKVStore } from \"./auth/LocalStorageKVStore.js\";\n\n/** @category Invite Links */\nexport function createInviteLink<C extends CoValue>(\n value: C,\n role: AccountRole,\n // default to same address as window.location, but without hash\n {\n baseURL = window.location.href.replace(/#.*$/, \"\"),\n valueHint,\n }: { baseURL?: string; valueHint?: string } = {},\n): string {\n return baseCreateInviteLink(value, role, baseURL, valueHint);\n}\n\n/** @category Invite Links */\nexport { parseInviteLink } from \"jazz-tools\";\n\n/** @category Invite Links */\nexport async function consumeInviteLinkFromWindowLocation<\n S extends CoValueClassOrSchema,\n>({\n as,\n forValueHint,\n invitedObjectSchema,\n}: {\n as?: Account;\n forValueHint?: string;\n invitedObjectSchema: S;\n}): Promise<\n | {\n valueID: string;\n valueHint?: string;\n inviteSecret: InviteSecret;\n }\n | undefined\n> {\n const result = await consumeInviteLink({\n inviteURL: window.location.href,\n as,\n forValueHint,\n invitedObjectSchema,\n });\n\n if (result) {\n window.history.replaceState(\n {},\n \"\",\n window.location.href.replace(/#.*$/, \"\"),\n );\n }\n\n return result;\n}\n","import { AuthSecretStorage } from \"jazz-tools\";\n\nasync function exportAccountToInspector() {\n const authSecretStorage = new AuthSecretStorage();\n const localStorageData = await authSecretStorage.get();\n\n if (!localStorageData) {\n console.error(\"No account data found in localStorage\");\n return;\n }\n\n const encodedAccountSecret = btoa(localStorageData.accountSecret);\n window.open(\n new URL(\n `#/import/${localStorageData?.accountID}/${encodedAccountSecret}`,\n \"https://inspector.jazz.tools\",\n ).toString(),\n \"_blank\",\n );\n}\n\nfunction listenForCmdJ() {\n if (typeof window === \"undefined\") return;\n\n const cb = (e: any) => {\n if (e.metaKey && e.key === \"j\") {\n if (\n confirm(\n \"Are you sure you want to inspect your account using inspector.jazz.tools? This lets anyone with the secret inspector URL read your data and impersonate you.\",\n )\n ) {\n exportAccountToInspector();\n }\n }\n };\n\n window.addEventListener(\"keydown\", cb);\n\n return () => {\n window.removeEventListener(\"keydown\", cb);\n };\n}\n\n/**\n * Automatically sets up the Cmd+J listener if 'allowJazzInspector' is present in the URL\n * @returns A cleanup function if the listener was set up, undefined otherwise\n */\nexport function setupInspector() {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n if (\n url.hash.includes(\"allowJazzInspector\") ||\n process.env.NODE_ENV === \"development\"\n ) {\n return listenForCmdJ();\n }\n}\n","import { CryptoProvider, RawAccountID, cojsonInternals } from \"cojson\";\nimport {\n Account,\n AuthSecretStorage,\n AuthenticateAccountFunction,\n ID,\n} from \"jazz-tools\";\n\n/**\n * `BrowserPasskeyAuth` provides a `JazzAuth` object for passkey authentication.\n *\n * ```ts\n * import { BrowserPasskeyAuth } from \"jazz-tools/browser\";\n *\n * const auth = new BrowserPasskeyAuth(driver, appName);\n * ```\n *\n * @category Auth Providers\n */\nexport class BrowserPasskeyAuth {\n constructor(\n protected crypto: CryptoProvider,\n protected authenticate: AuthenticateAccountFunction,\n protected authSecretStorage: AuthSecretStorage,\n public appName: string,\n public appHostname: string = window.location.hostname,\n ) {}\n\n static readonly id = \"passkey\";\n\n logIn = async () => {\n const { crypto, authenticate } = this;\n\n const webAuthNCredential = await this.getPasskeyCredentials();\n\n if (!webAuthNCredential) {\n return;\n }\n\n const webAuthNCredentialPayload = new Uint8Array(\n webAuthNCredential.response.userHandle,\n );\n const accountSecretSeed = webAuthNCredentialPayload.slice(\n 0,\n cojsonInternals.secretSeedLength,\n );\n\n const secret = crypto.agentSecretFromSecretSeed(accountSecretSeed);\n\n const accountID = cojsonInternals.rawCoIDfromBytes(\n webAuthNCredentialPayload.slice(\n cojsonInternals.secretSeedLength,\n cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength,\n ),\n ) as ID<Account>;\n\n await authenticate({\n accountID,\n accountSecret: secret,\n });\n\n await this.authSecretStorage.set({\n accountID,\n secretSeed: accountSecretSeed,\n accountSecret: secret,\n provider: \"passkey\",\n });\n };\n\n signUp = async (username: string) => {\n const credentials = await this.authSecretStorage.get();\n\n if (!credentials?.secretSeed) {\n throw new Error(\n \"Not enough credentials to register the account with passkey\",\n );\n }\n\n await this.createPasskeyCredentials({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n username,\n });\n\n const currentAccount = await Account.getMe().$jazz.ensureLoaded({\n resolve: {\n profile: true,\n },\n });\n\n if (username.trim().length !== 0) {\n currentAccount.profile.$jazz.set(\"name\", username);\n }\n\n await this.authSecretStorage.set({\n accountID: credentials.accountID,\n secretSeed: credentials.secretSeed,\n accountSecret: credentials.accountSecret,\n provider: \"passkey\",\n });\n };\n\n private async createPasskeyCredentials({\n accountID,\n secretSeed,\n username,\n }: {\n accountID: ID<Account>;\n secretSeed: Uint8Array;\n username: string;\n }) {\n const webAuthNCredentialPayload = new Uint8Array(\n cojsonInternals.secretSeedLength + cojsonInternals.shortHashLength,\n );\n\n webAuthNCredentialPayload.set(secretSeed);\n webAuthNCredentialPayload.set(\n cojsonInternals.rawCoIDtoBytes(accountID as unknown as RawAccountID),\n cojsonInternals.secretSeedLength,\n );\n\n try {\n await navigator.credentials.create({\n publicKey: {\n challenge: new Uint8Array(this.crypto.randomBytes(20)),\n rp: {\n name: this.appName,\n id: this.appHostname,\n },\n user: {\n id: webAuthNCredentialPayload,\n name: username + ` (${new Date().toLocaleString()})`,\n displayName: username,\n },\n pubKeyCredParams: [\n { alg: -7, type: \"public-key\" },\n { alg: -8, type: \"public-key\" },\n { alg: -37, type: \"public-key\" },\n { alg: -257, type: \"public-key\" },\n ],\n authenticatorSelection: {\n requireResidentKey: true,\n residentKey: \"required\",\n userVerification: \"preferred\",\n },\n timeout: 60000,\n attestation: \"direct\",\n },\n });\n } catch (error) {\n throw new Error(\"Passkey creation aborted\", { cause: error });\n }\n }\n\n private async getPasskeyCredentials() {\n try {\n const value = await navigator.credentials.get({\n publicKey: {\n challenge: new Uint8Array(this.crypto.randomBytes(20)),\n rpId: this.appHostname,\n allowCredentials: [],\n timeout: 60000,\n userVerification: \"preferred\",\n },\n mediation: \"optional\",\n });\n\n return value as\n | (Credential & { response: { userHandle: ArrayBuffer } })\n | null;\n } catch (error) {\n throw new Error(\"Passkey creation aborted\", { cause: error });\n }\n }\n}\n","import { LocalNode, Peer } from \"cojson\";\nimport { getIndexedDBStorage } from \"cojson-storage-indexeddb\";\nimport { WebSocketPeerWithReconnection } from \"cojson-transport-ws\";\nimport { WasmCrypto } from \"cojson/crypto/WasmCrypto\";\nimport {\n Account,\n AccountClass,\n AgentID,\n AnyAccountSchema,\n AuthCredentials,\n AuthSecretStorage,\n CoValue,\n CoValueFromRaw,\n CryptoProvider,\n ID,\n InviteSecret,\n NewAccountProps,\n SessionID,\n SyncConfig,\n cojsonInternals,\n createAnonymousJazzContext,\n} from \"jazz-tools\";\nimport { createJazzContext } from \"jazz-tools\";\nimport { StorageConfig, getStorageOptions } from \"./storageOptions.js\";\nimport { setupInspector } from \"./utils/export-account-inspector.js\";\nimport { getBrowserLockSessionProvider } from \"./provideBrowserLockSession/index.js\";\n\nsetupInspector();\n\nexport type BaseBrowserContextOptions = {\n sync: SyncConfig;\n reconnectionTimeout?: number;\n storage?: StorageConfig;\n crypto?: CryptoProvider;\n authSecretStorage: AuthSecretStorage;\n};\n\nclass BrowserWebSocketPeerWithReconnection extends WebSocketPeerWithReconnection {\n onNetworkChange(callback: (connected: boolean) => void): () => void {\n const handler = () => callback(navigator.onLine);\n window.addEventListener(\"online\", handler);\n window.addEventListener(\"offline\", handler);\n\n return () => {\n window.removeEventListener(\"online\", handler);\n window.removeEventListener(\"offline\", handler);\n };\n }\n}\n\nasync function setupPeers(options: BaseBrowserContextOptions) {\n const crypto = options.crypto || (await WasmCrypto.create());\n let node: LocalNode | undefined = undefined;\n\n const { useIndexedDB } = getStorageOptions(options.storage);\n\n const peers: Peer[] = [];\n\n const storage = useIndexedDB ? await getIndexedDBStorage() : undefined;\n\n if (options.sync.when === \"never\") {\n return {\n addConnectionListener: () => () => {},\n connected: () => false,\n toggleNetwork: () => {},\n peers,\n storage,\n setNode: () => {},\n crypto,\n };\n }\n\n const wsPeer = new BrowserWebSocketPeerWithReconnection({\n peer: options.sync.peer,\n reconnectionTimeout: options.reconnectionTimeout,\n addPeer: (peer) => {\n if (node) {\n node.syncManager.addPeer(peer);\n } else {\n peers.push(peer);\n }\n },\n removePeer: (peer) => {\n peers.splice(peers.indexOf(peer), 1);\n },\n });\n\n function toggleNetwork(enabled: boolean) {\n if (enabled) {\n wsPeer.enable();\n } else {\n wsPeer.disable();\n }\n }\n\n function setNode(value: LocalNode) {\n node = value;\n }\n\n if (options.sync.when === \"always\" || !options.sync.when) {\n toggleNetwork(true);\n }\n\n return {\n toggleNetwork,\n addConnectionListener(listener: (connected: boolean) => void) {\n wsPeer.subscribe(listener);\n\n return () => {\n wsPeer.unsubscribe(listener);\n };\n },\n connected() {\n return wsPeer.connected;\n },\n peers,\n storage,\n setNode,\n crypto,\n };\n}\n\nexport async function createJazzBrowserGuestContext(\n options: BaseBrowserContextOptions,\n) {\n const {\n toggleNetwork,\n peers,\n setNode,\n crypto,\n storage,\n addConnectionListener,\n connected,\n } = await setupPeers(options);\n\n const context = await createAnonymousJazzContext({\n crypto,\n peers,\n storage,\n });\n\n setNode(context.agent.node);\n\n options.authSecretStorage.emitUpdate(null);\n\n return {\n guest: context.agent,\n node: context.agent.node,\n done: () => {\n // TODO: Sync all the covalues before closing the connection & context\n toggleNetwork(false);\n context.done();\n },\n logOut: () => {\n return context.logOut();\n },\n addConnectionListener,\n connected,\n };\n}\n\nexport type BrowserContextOptions<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> = {\n credentials?: AuthCredentials;\n AccountSchema?: S;\n newAccountProps?: NewAccountProps;\n defaultProfileName?: string;\n} & BaseBrowserContextOptions;\n\nexport async function createJazzBrowserContext<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n>(options: BrowserContextOptions<S>) {\n const {\n toggleNetwork,\n peers,\n setNode,\n crypto,\n storage,\n addConnectionListener,\n connected,\n } = await setupPeers(options);\n\n let unsubscribeAuthUpdate = () => {};\n\n if (options.sync.when === \"signedUp\") {\n const authSecretStorage = options.authSecretStorage;\n const credentials = options.credentials ?? (await authSecretStorage.get());\n\n function handleAuthUpdate(isAuthenticated: boolean) {\n if (isAuthenticated) {\n toggleNetwork(true);\n } else {\n toggleNetwork(false);\n }\n }\n\n unsubscribeAuthUpdate = authSecretStorage.onUpdate(handleAuthUpdate);\n handleAuthUpdate(authSecretStorage.getIsAuthenticated(credentials));\n }\n\n const context = await createJazzContext({\n credentials: options.credentials,\n newAccountProps: options.newAccountProps,\n peers,\n storage,\n crypto,\n defaultProfileName: options.defaultProfileName,\n AccountSchema: options.AccountSchema,\n sessionProvider: getBrowserLockSessionProvider(),\n authSecretStorage: options.authSecretStorage,\n });\n\n setNode(context.node);\n\n return {\n me: context.account,\n node: context.node,\n authSecretStorage: context.authSecretStorage,\n done: () => {\n // TODO: Sync all the covalues before closing the connection & context\n toggleNetwork(false);\n unsubscribeAuthUpdate();\n context.done();\n },\n logOut: () => {\n unsubscribeAuthUpdate();\n return context.logOut();\n },\n addConnectionListener,\n connected,\n };\n}\n\n/** @category Auth Providers */\nexport type SessionProvider = (\n accountID: ID<Account> | AgentID,\n) => Promise<SessionID>;\n\n/** @category Invite Links */\nexport function createInviteLink<C extends CoValue>(\n value: C,\n role: \"reader\" | \"writer\" | \"admin\" | \"writeOnly\",\n // default to same address as window.location, but without hash\n {\n baseURL = window.location.href.replace(/#.*$/, \"\"),\n valueHint,\n }: { baseURL?: string; valueHint?: string } = {},\n): string {\n const coValueCore = value.$jazz.raw.core;\n let currentCoValue = coValueCore;\n\n while (currentCoValue.verified.header.ruleset.type === \"ownedByGroup\") {\n currentCoValue = currentCoValue.getGroup().core;\n }\n\n const { ruleset, meta } = currentCoValue.verified.header;\n\n if (ruleset.type !== \"group\" || meta?.type === \"account\") {\n throw new Error(\"Can't create invite link for object without group\");\n }\n\n const group = cojsonInternals.expectGroup(currentCoValue.getCurrentContent());\n const inviteSecret = group.createInvite(role);\n\n return `${baseURL}#/invite/${valueHint ? valueHint + \"/\" : \"\"}${\n value.$jazz.id\n }/${inviteSecret}`;\n}\n\n/** @category Invite Links */\nexport function parseInviteLink<C extends CoValue>(\n inviteURL: string,\n):\n | {\n valueID: ID<C>;\n valueHint?: string;\n inviteSecret: InviteSecret;\n }\n | undefined {\n const url = new URL(inviteURL);\n const parts = url.hash.split(\"/\");\n\n let valueHint: string | undefined;\n let valueID: ID<C> | undefined;\n let inviteSecret: InviteSecret | undefined;\n\n if (parts[0] === \"#\" && parts[1] === \"invite\") {\n if (parts.length === 5) {\n valueHint = parts[2];\n valueID = parts[3] as ID<C>;\n inviteSecret = parts[4] as InviteSecret;\n } else if (parts.length === 4) {\n valueID = parts[2] as ID<C>;\n inviteSecret = parts[3] as InviteSecret;\n }\n\n if (!valueID || !inviteSecret) {\n return undefined;\n }\n return { valueID, inviteSecret, valueHint };\n }\n}\n","type StorageOption = \"indexedDB\";\ntype CombinedStorageOption = [\"indexedDB\"];\nexport type StorageConfig =\n | StorageOption\n | CombinedStorageOption\n | [StorageOption];\n\nexport function getStorageOptions(storage?: StorageConfig): {\n useIndexedDB: boolean;\n} {\n const useIndexedDB =\n !storage ||\n (Array.isArray(storage) && storage.includes(\"indexedDB\")) ||\n storage === \"indexedDB\";\n\n return { useIndexedDB };\n}\n","import { MockSessionProvider } from \"jazz-tools\";\nimport { BrowserSessionProvider } from \"./BrowserSessionProvider\";\n\nexport function getBrowserLockSessionProvider() {\n if (typeof navigator === \"undefined\" || !navigator.locks?.request) {\n // Fallback to random session ID for each tab session\n return new MockSessionProvider();\n }\n\n return new BrowserSessionProvider();\n}\n","import { SessionID } from \"cojson\";\n\nfunction getSessionKey(accountID: string, index: number) {\n return accountID + \"_\" + index;\n}\n\nexport class SessionIDStorage {\n static getSessionsList(accountID: string) {\n let sessionsList: SessionID[] = [];\n let i = 0;\n let lastSessionID: SessionID | null;\n\n do {\n lastSessionID = localStorage.getItem(\n getSessionKey(accountID, i),\n ) as SessionID | null;\n if (lastSessionID) {\n sessionsList.push(lastSessionID);\n }\n i++;\n } while (lastSessionID);\n\n return sessionsList;\n }\n\n static storeSessionID(\n accountID: string,\n sessionID: SessionID,\n index: number,\n ) {\n localStorage.setItem(getSessionKey(accountID, index), sessionID);\n }\n}\n","import { AgentID, CryptoProvider, RawAccountID, SessionID } from \"cojson\";\nimport { ID, Account, SessionProvider } from \"jazz-tools\";\nimport { SessionIDStorage } from \"./SessionIDStorage\";\n\nexport class BrowserSessionProvider implements SessionProvider {\n async acquireSession(\n accountID: ID<Account> | AgentID,\n crypto: CryptoProvider,\n ): Promise<{ sessionID: SessionID; sessionDone: () => void }> {\n const { sessionPromise, resolveSession } = createSessionLockPromise();\n\n // Get the list of sessions for the account, to try to acquire an existing session\n const sessionsList = SessionIDStorage.getSessionsList(accountID);\n\n for (const [index, sessionID] of sessionsList.entries()) {\n const sessionAcquired = await tryToAcquireSession(\n sessionID,\n sessionPromise,\n );\n\n if (sessionAcquired) {\n console.log(\"Using existing session\", sessionID, \"at index\", index); // This log is used in the e2e tests to verify the correctness of the feature\n return {\n sessionID,\n sessionDone: resolveSession,\n };\n }\n }\n\n const newSessionID = crypto.newRandomSessionID(\n accountID as RawAccountID | AgentID,\n );\n\n // Acquire exclusively the session to store the new session ID for reuse in future sessions\n await lockAndStoreSession(accountID, newSessionID, sessionPromise);\n\n console.log(\"Created new session\", newSessionID); // This log is used in the e2e tests to verify the correctness of the feature\n\n return {\n sessionID: newSessionID,\n sessionDone: resolveSession,\n };\n }\n\n async persistSession(\n accountID: ID<Account> | AgentID,\n sessionID: SessionID,\n ): Promise<{ sessionDone: () => void }> {\n const { sessionPromise, resolveSession } = createSessionLockPromise();\n\n // Store the session id for future use and lock it until the session is done\n await lockAndStoreSession(accountID, sessionID, sessionPromise);\n\n console.log(\"Stored new session\", sessionID);\n\n return { sessionDone: resolveSession };\n }\n}\n\nasync function lockAndStoreSession(\n accountID: ID<Account> | AgentID,\n sessionID: SessionID,\n sessionPromise: Promise<void>,\n) {\n const sessionAcquired = await tryToAcquireSession(sessionID, sessionPromise);\n\n if (!sessionAcquired) {\n // This should never happen because the session has been randomly generated\n throw new Error(\"Couldn't get lock on new session\");\n }\n\n // We don't need to wait for this to finish, we only need to acquire the lock on the new session\n storeSessionID(accountID, sessionID);\n}\n\nfunction tryToAcquireSession(\n sessionID: SessionID,\n sessionDonePromise: Promise<void>,\n) {\n return new Promise<boolean>((resolve) => {\n // Acquire exclusively the session if available\n navigator.locks.request(\n `load_session_${sessionID}`,\n { mode: \"exclusive\", ifAvailable: true },\n async (lock) => {\n if (!lock) {\n resolve(false); // Session already in use\n return;\n }\n\n resolve(true); // Session is available\n\n // Return the promise to lock the session until sessionDone is called\n return sessionDonePromise;\n },\n );\n });\n}\n\nfunction storeSessionID(\n accountID: ID<Account> | AgentID,\n sessionID: SessionID,\n) {\n return navigator.locks.request(\n `store_session_${accountID}`,\n { mode: \"exclusive\" },\n async (lock) => {\n if (!lock) {\n console.error(\"Couldn't get lock to store session ID\", accountID);\n }\n\n const sessionsList = SessionIDStorage.getSessionsList(accountID);\n SessionIDStorage.storeSessionID(\n accountID,\n sessionID,\n sessionsList.length,\n );\n },\n );\n}\n\nfunction createSessionLockPromise() {\n let resolveSession: () => void;\n const sessionPromise = new Promise<void>((resolve) => {\n resolveSession = resolve;\n });\n\n return {\n sessionPromise,\n resolveSession: resolveSession!,\n };\n}\n","import {\n Account,\n AccountClass,\n AnyAccountSchema,\n CoValueFromRaw,\n InMemoryKVStore,\n InstanceOfSchema,\n JazzContextManager,\n SyncConfig,\n} from \"jazz-tools\";\nimport { JazzContextManagerAuthProps } from \"jazz-tools\";\nimport { LocalStorageKVStore } from \"./auth/LocalStorageKVStore.js\";\nimport {\n BaseBrowserContextOptions,\n createJazzBrowserContext,\n createJazzBrowserGuestContext,\n} from \"./createBrowserContext.js\";\n\nexport type JazzContextManagerProps<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> = {\n guestMode?: boolean;\n sync: SyncConfig;\n onLogOut?: () => void;\n logOutReplacement?: () => void;\n onAnonymousAccountDiscarded?: (\n anonymousAccount: InstanceOfSchema<S>,\n ) => Promise<void>;\n storage?: BaseBrowserContextOptions[\"storage\"];\n AccountSchema?: S;\n defaultProfileName?: string;\n};\n\nexport class JazzBrowserContextManager<\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n> extends JazzContextManager<InstanceOfSchema<S>, JazzContextManagerProps<S>> {\n // TODO: When the storage changes, if the user is changed, update the context\n getKvStore() {\n if (typeof window === \"undefined\") {\n // To handle running in SSR\n return new InMemoryKVStore();\n } else {\n return new LocalStorageKVStore();\n }\n }\n\n async getNewContext(\n props: JazzContextManagerProps<S>,\n authProps?: JazzContextManagerAuthProps,\n ) {\n if (props.guestMode) {\n return createJazzBrowserGuestContext({\n sync: props.sync,\n storage: props.storage,\n authSecretStorage: this.authSecretStorage,\n });\n } else {\n return createJazzBrowserContext<S>({\n sync: props.sync,\n storage: props.storage,\n AccountSchema: props.AccountSchema,\n credentials: authProps?.credentials,\n newAccountProps: authProps?.newAccountProps,\n defaultProfileName: props.defaultProfileName,\n authSecretStorage: this.authSecretStorage,\n });\n }\n }\n\n propsChanged(props: JazzContextManagerProps<S>) {\n if (!this.props) {\n return true;\n }\n\n return (\n this.props.sync.when !== props.sync.when ||\n this.props.sync.peer !== props.sync.peer ||\n this.props.guestMode !== props.guestMode\n );\n }\n}\n","import { KvStore } from \"jazz-tools\";\n\nexport class LocalStorageKVStore implements KvStore {\n constructor() {}\n\n async get(key: string) {\n return localStorage.getItem(key);\n }\n\n async set(key: string, value: string) {\n localStorage.setItem(key, value);\n }\n\n async delete(key: string) {\n localStorage.removeItem(key);\n }\n\n async clearAll() {\n localStorage.clear();\n }\n}\n"],"mappings":"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","names":["cojsonInternals","handleAuthUpdate"]}
@@ -0,0 +1,12 @@
1
+ import { AgentID, CryptoProvider, SessionID } from "cojson";
2
+ import { ID, Account, SessionProvider } from "jazz-tools";
3
+ export declare class BrowserSessionProvider implements SessionProvider {
4
+ acquireSession(accountID: ID<Account> | AgentID, crypto: CryptoProvider): Promise<{
5
+ sessionID: SessionID;
6
+ sessionDone: () => void;
7
+ }>;
8
+ persistSession(accountID: ID<Account> | AgentID, sessionID: SessionID): Promise<{
9
+ sessionDone: () => void;
10
+ }>;
11
+ }
12
+ //# sourceMappingURL=BrowserSessionProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserSessionProvider.d.ts","sourceRoot":"","sources":["../../../src/browser/provideBrowserLockSession/BrowserSessionProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAgB,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC1E,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG1D,qBAAa,sBAAuB,YAAW,eAAe;IACtD,cAAc,CAClB,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,EAChC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IAoCvD,cAAc,CAClB,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,EAChC,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAUxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=BrowserSessionProvider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserSessionProvider.test.d.ts","sourceRoot":"","sources":["../../../src/browser/provideBrowserLockSession/BrowserSessionProvider.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { SessionID } from "cojson";
2
+ export declare class SessionIDStorage {
3
+ static getSessionsList(accountID: string): (`${import("cojson").RawAccountID}_session_z${string}` | `sealer_z${string}/signer_z${string}_session_z${string}`)[];
4
+ static storeSessionID(accountID: string, sessionID: SessionID, index: number): void;
5
+ }
6
+ //# sourceMappingURL=SessionIDStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionIDStorage.d.ts","sourceRoot":"","sources":["../../../src/browser/provideBrowserLockSession/SessionIDStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAMnC,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM;IAkBxC,MAAM,CAAC,cAAc,CACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM;CAIhB"}
@@ -0,0 +1,4 @@
1
+ import { MockSessionProvider } from "jazz-tools";
2
+ import { BrowserSessionProvider } from "./BrowserSessionProvider";
3
+ export declare function getBrowserLockSessionProvider(): MockSessionProvider | BrowserSessionProvider;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/browser/provideBrowserLockSession/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,6BAA6B,iDAO5C"}