jazz-tools 0.18.37 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.svelte-kit/__package__/jazz.class.svelte.d.ts +8 -8
- package/.svelte-kit/__package__/jazz.class.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/jazz.class.svelte.js +39 -14
- package/.svelte-kit/__package__/media/image.svelte +6 -5
- package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.d.ts +2 -0
- package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.d.ts.map +1 -0
- package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.js +19 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test-d.d.ts +2 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test-d.d.ts.map +1 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test-d.js +16 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test.d.ts +2 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test.d.ts.map +1 -0
- package/.svelte-kit/__package__/tests/CoState.svelte.test.js +42 -0
- package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte +23 -0
- package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte.d.ts +12 -0
- package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte.d.ts.map +1 -0
- package/.turbo/turbo-build.log +53 -53
- package/CHANGELOG.md +33 -0
- package/dist/better-auth/database-adapter/index.js +14 -11
- package/dist/better-auth/database-adapter/index.js.map +1 -1
- package/dist/better-auth/database-adapter/repository/generic.d.ts +1 -1
- package/dist/better-auth/database-adapter/repository/generic.d.ts.map +1 -1
- package/dist/better-auth/database-adapter/repository/user.d.ts.map +1 -1
- package/dist/{chunk-OSQ7S47Q.js → chunk-P3YLNFN4.js} +504 -232
- package/dist/chunk-P3YLNFN4.js.map +1 -0
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/inspector/{custom-element-SUVJ7CPN.js → custom-element-QESCMFY7.js} +13 -3
- package/dist/inspector/{custom-element-SUVJ7CPN.js.map → custom-element-QESCMFY7.js.map} +1 -1
- package/dist/inspector/index.js +12 -2
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/viewer/history-view.d.ts.map +1 -1
- package/dist/media/{chunk-K6GCHLQU.js → chunk-3LKBM3G3.js} +23 -15
- package/dist/media/chunk-3LKBM3G3.js.map +1 -0
- package/dist/media/create-image/browser.d.ts +2 -2
- package/dist/media/create-image/react-native.d.ts +2 -2
- package/dist/media/create-image/server.d.ts +2 -2
- package/dist/media/create-image-factory.d.ts +2 -2
- package/dist/media/index.browser.js +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.native.js +1 -1
- package/dist/media/index.server.js +1 -1
- package/dist/media/utils.d.ts.map +1 -1
- package/dist/react/hooks.d.ts +1 -1
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +31 -15
- package/dist/react/index.js.map +1 -1
- package/dist/react/media/image.d.ts.map +1 -1
- package/dist/react-core/hooks.d.ts +126 -224
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +65 -63
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/subscription-provider.d.ts.map +1 -1
- package/dist/react-core/tests/createCoValueSubscriptionContext.test.d.ts +2 -0
- package/dist/react-core/tests/createCoValueSubscriptionContext.test.d.ts.map +1 -0
- package/dist/react-core/tests/useAccount.selector.test.d.ts +2 -0
- package/dist/react-core/tests/useAccount.selector.test.d.ts.map +1 -0
- package/dist/react-core/tests/useCoState.selector.test.d.ts +2 -0
- package/dist/react-core/tests/useCoState.selector.test.d.ts.map +1 -0
- package/dist/react-native-core/hooks.d.ts +1 -1
- package/dist/react-native-core/hooks.d.ts.map +1 -1
- package/dist/react-native-core/index.js +7 -5
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/media/image.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.d.ts +8 -8
- package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +39 -14
- package/dist/svelte/media/image.svelte +6 -5
- package/dist/svelte/media/image.svelte.d.ts.map +1 -1
- package/dist/svelte/tests/AccountCoState.svelte.test-d.d.ts +2 -0
- package/dist/svelte/tests/AccountCoState.svelte.test-d.d.ts.map +1 -0
- package/dist/svelte/tests/AccountCoState.svelte.test-d.js +19 -0
- package/dist/svelte/tests/CoState.svelte.test-d.d.ts +2 -0
- package/dist/svelte/tests/CoState.svelte.test-d.d.ts.map +1 -0
- package/dist/svelte/tests/CoState.svelte.test-d.js +16 -0
- package/dist/svelte/tests/CoState.svelte.test.d.ts +2 -0
- package/dist/svelte/tests/CoState.svelte.test.d.ts.map +1 -0
- package/dist/svelte/tests/CoState.svelte.test.js +42 -0
- package/dist/svelte/tests/TestCoStateWrapper.svelte +23 -0
- package/dist/svelte/tests/TestCoStateWrapper.svelte.d.ts +12 -0
- package/dist/svelte/tests/TestCoStateWrapper.svelte.d.ts.map +1 -0
- package/dist/testing.js +3 -1
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/CoValueBase.d.ts +4 -1
- package/dist/tools/coValues/CoValueBase.d.ts.map +1 -1
- package/dist/tools/coValues/account.d.ts +6 -6
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/coFeed.d.ts +5 -5
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/coList.d.ts +9 -8
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +17 -17
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/coPlainText.d.ts +3 -3
- package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
- package/dist/tools/coValues/coVector.d.ts +3 -3
- package/dist/tools/coValues/coVector.d.ts.map +1 -1
- package/dist/tools/coValues/deepLoading.d.ts +66 -36
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/extensions/imageDef.d.ts +1 -1
- package/dist/tools/coValues/extensions/imageDef.d.ts.map +1 -1
- package/dist/tools/coValues/group.d.ts +2 -2
- package/dist/tools/coValues/group.d.ts.map +1 -1
- package/dist/tools/coValues/inbox.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +14 -6
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/coValues/request.d.ts.map +1 -1
- package/dist/tools/coValues/schemaUnion.d.ts +2 -2
- package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +3 -3
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/refs.d.ts +3 -3
- package/dist/tools/implementation/refs.d.ts.map +1 -1
- package/dist/tools/implementation/schema.d.ts +2 -2
- package/dist/tools/implementation/schema.d.ts.map +1 -1
- package/dist/tools/implementation/schemaUtils.d.ts +8 -0
- package/dist/tools/implementation/schemaUtils.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +33 -18
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +5 -4
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +23 -12
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +29 -18
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +39 -22
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts +1 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +30 -19
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts +5 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts +6 -5
- package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +3 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts +22 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts.map +1 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts +4 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.d.ts +9 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.d.ts.map +1 -0
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodSchema.d.ts +7 -6
- package/dist/tools/implementation/zodSchema/zodSchema.d.ts.map +1 -1
- package/dist/tools/internal.d.ts +3 -3
- package/dist/tools/internal.d.ts.map +1 -1
- package/dist/tools/lib/utils.d.ts +14 -0
- package/dist/tools/lib/utils.d.ts.map +1 -0
- package/dist/tools/lib/utils.test.d.ts +2 -0
- package/dist/tools/lib/utils.test.d.ts.map +1 -0
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts +3 -2
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/JazzError.d.ts +4 -3
- package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts +6 -5
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/index.d.ts.map +1 -1
- package/dist/tools/subscribe/types.d.ts +23 -3
- package/dist/tools/subscribe/types.d.ts.map +1 -1
- package/dist/tools/subscribe/utils.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +3 -2
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/schema.resolved.test.d.ts +2 -0
- package/dist/tools/tests/schema.resolved.test.d.ts.map +1 -0
- package/dist/tools/tests/utils.d.ts +2 -1
- package/dist/tools/tests/utils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/better-auth/database-adapter/index.ts +2 -2
- package/src/better-auth/database-adapter/repository/account.ts +3 -3
- package/src/better-auth/database-adapter/repository/generic.ts +9 -6
- package/src/better-auth/database-adapter/repository/user.ts +6 -2
- package/src/better-auth/database-adapter/schema.ts +1 -1
- package/src/better-auth/database-adapter/tests/index.test.ts +3 -4
- package/src/inspector/tests/viewer/history-view.test.tsx +74 -10
- package/src/inspector/viewer/history-view.tsx +14 -5
- package/src/media/utils.test.ts +5 -0
- package/src/media/utils.ts +25 -16
- package/src/react/hooks.tsx +2 -2
- package/src/react/index.ts +2 -2
- package/src/react/media/image.tsx +10 -2
- package/src/react/tests/useAcceptInvite.test.ts +3 -1
- package/src/react-core/hooks.ts +226 -304
- package/src/react-core/subscription-provider.tsx +14 -7
- package/src/react-core/tests/createCoValueSubscriptionContext.test.tsx +233 -0
- package/src/react-core/tests/subscription.bench.tsx +32 -15
- package/src/react-core/tests/{useAccountWithSelector.test.ts → useAccount.selector.test.ts} +72 -24
- package/src/react-core/tests/useAccount.test.ts +92 -106
- package/src/react-core/tests/{useCoStateWithSelector.test.ts → useCoState.selector.test.ts} +23 -8
- package/src/react-core/tests/useCoState.test.ts +173 -49
- package/src/react-core/tests/useInboxSender.test.ts +3 -1
- package/src/react-core/tests/usePassPhraseAuth.test.ts +11 -82
- package/src/react-core/tests/useSubscriptionSelector.test.ts +48 -14
- package/src/react-native-core/hooks.tsx +2 -2
- package/src/react-native-core/media/image.tsx +3 -1
- package/src/svelte/jazz.class.svelte.ts +103 -27
- package/src/svelte/media/image.svelte +6 -5
- package/src/svelte/tests/AccountCoState.svelte.test-d.ts +23 -0
- package/src/svelte/tests/CoState.svelte.test-d.ts +20 -0
- package/src/svelte/tests/CoState.svelte.test.ts +57 -0
- package/src/svelte/tests/TestCoStateWrapper.svelte +23 -0
- package/src/tools/coValues/CoValueBase.ts +12 -0
- package/src/tools/coValues/account.ts +17 -12
- package/src/tools/coValues/coFeed.ts +38 -15
- package/src/tools/coValues/coList.ts +16 -11
- package/src/tools/coValues/coMap.ts +15 -14
- package/src/tools/coValues/coPlainText.ts +6 -3
- package/src/tools/coValues/coVector.ts +6 -5
- package/src/tools/coValues/deepLoading.ts +98 -51
- package/src/tools/coValues/group.ts +3 -2
- package/src/tools/coValues/inbox.ts +11 -10
- package/src/tools/coValues/interfaces.ts +49 -27
- package/src/tools/coValues/request.ts +8 -6
- package/src/tools/coValues/schemaUnion.ts +2 -1
- package/src/tools/exports.ts +11 -1
- package/src/tools/implementation/refs.ts +19 -13
- package/src/tools/implementation/schema.ts +5 -4
- package/src/tools/implementation/schemaUtils.ts +15 -0
- package/src/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.ts +4 -4
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +131 -95
- package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +19 -9
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +73 -22
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +86 -28
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +204 -148
- package/src/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.ts +1 -0
- package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +71 -27
- package/src/tools/implementation/zodSchema/schemaTypes/CoValueSchema.ts +7 -0
- package/src/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.ts +8 -6
- package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +4 -1
- package/src/tools/implementation/zodSchema/schemaTypes/GroupSchema.ts +4 -1
- package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +4 -1
- package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +4 -1
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +3 -0
- package/src/tools/implementation/zodSchema/typeConverters/{InstanceOfSchemaCoValuesNullable.ts → InstanceOfSchemaCoValuesMaybeLoaded.ts} +47 -39
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.ts +4 -0
- package/src/tools/implementation/zodSchema/typeConverters/{InstanceOrPrimitiveOfSchemaCoValuesNullable.ts → InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.ts} +7 -3
- package/src/tools/implementation/zodSchema/zodSchema.ts +15 -7
- package/src/tools/internal.ts +3 -3
- package/src/tools/lib/utils.test.ts +56 -0
- package/src/tools/lib/utils.ts +32 -0
- package/src/tools/subscribe/CoValueCoreSubscription.ts +13 -8
- package/src/tools/subscribe/JazzError.ts +8 -2
- package/src/tools/subscribe/SubscriptionScope.ts +55 -44
- package/src/tools/subscribe/index.ts +12 -4
- package/src/tools/subscribe/types.ts +36 -2
- package/src/tools/subscribe/utils.ts +2 -1
- package/src/tools/testing.ts +5 -0
- package/src/tools/tests/CoValueCoreSubscription.test.ts +10 -4
- package/src/tools/tests/ContextManager.test.ts +12 -5
- package/src/tools/tests/account.test.ts +22 -12
- package/src/tools/tests/coDiscriminatedUnion.test.ts +8 -4
- package/src/tools/tests/coFeed.branch.test.ts +48 -32
- package/src/tools/tests/coFeed.test-d.ts +17 -10
- package/src/tools/tests/coFeed.test.ts +52 -30
- package/src/tools/tests/coList.branch.test.ts +21 -21
- package/src/tools/tests/coList.test-d.ts +39 -23
- package/src/tools/tests/coList.test.ts +51 -25
- package/src/tools/tests/coList.unique.test.ts +34 -29
- package/src/tools/tests/coMap.branch.test.ts +20 -21
- package/src/tools/tests/coMap.record.test-d.ts +28 -26
- package/src/tools/tests/coMap.record.test.ts +30 -20
- package/src/tools/tests/coMap.test-d.ts +31 -29
- package/src/tools/tests/coMap.test.ts +67 -40
- package/src/tools/tests/coMap.unique.test.ts +25 -24
- package/src/tools/tests/coVector.test.ts +29 -15
- package/src/tools/tests/createContext.test.ts +5 -3
- package/src/tools/tests/deepLoading.test.ts +314 -117
- package/src/tools/tests/exportImport.test.ts +16 -15
- package/src/tools/tests/groupsAndAccounts.test.ts +39 -16
- package/src/tools/tests/inbox.test.ts +3 -1
- package/src/tools/tests/load.test.ts +29 -23
- package/src/tools/tests/patterns/quest.test.ts +3 -2
- package/src/tools/tests/patterns/requestToJoin.test.ts +17 -17
- package/src/tools/tests/request.test.ts +12 -2
- package/src/tools/tests/schema.resolved.test.ts +723 -0
- package/src/tools/tests/schemaUnion.test.ts +7 -3
- package/src/tools/tests/subscribe.test.ts +39 -21
- package/src/tools/tests/testing.test.ts +3 -2
- package/src/tools/tests/utils.ts +15 -2
- package/dist/chunk-OSQ7S47Q.js.map +0 -1
- package/dist/media/chunk-K6GCHLQU.js.map +0 -1
- package/dist/react-core/tests/useAccountWithSelector.test.d.ts +0 -2
- package/dist/react-core/tests/useAccountWithSelector.test.d.ts.map +0 -1
- package/dist/react-core/tests/useCoStateWithSelector.test.d.ts +0 -2
- package/dist/react-core/tests/useCoStateWithSelector.test.d.ts.map +0 -1
- package/dist/tools/implementation/errors.d.ts +0 -2
- package/dist/tools/implementation/errors.d.ts.map +0 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +0 -19
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +0 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts +0 -5
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts.map +0 -1
- package/dist/tools/lib/id.d.ts +0 -2
- package/dist/tools/lib/id.d.ts.map +0 -1
- package/src/tools/implementation/errors.ts +0 -1
- package/src/tools/lib/id.ts +0 -3
package/src/react-core/hooks.ts
CHANGED
|
@@ -13,15 +13,20 @@ import {
|
|
|
13
13
|
AnyAccountSchema,
|
|
14
14
|
CoValue,
|
|
15
15
|
CoValueClassOrSchema,
|
|
16
|
+
CoValueLoadingState,
|
|
16
17
|
InboxSender,
|
|
17
18
|
InstanceOfSchema,
|
|
18
19
|
JazzContextManager,
|
|
19
20
|
JazzContextType,
|
|
20
21
|
Loaded,
|
|
22
|
+
MaybeLoaded,
|
|
23
|
+
NotLoaded,
|
|
21
24
|
ResolveQuery,
|
|
22
25
|
ResolveQueryStrict,
|
|
26
|
+
SchemaResolveQuery,
|
|
23
27
|
SubscriptionScope,
|
|
24
28
|
coValueClassFromCoValueClassOrSchema,
|
|
29
|
+
createUnloadedCoValue,
|
|
25
30
|
type BranchDefinition,
|
|
26
31
|
} from "jazz-tools";
|
|
27
32
|
import { JazzContext, JazzContextManagerContext } from "./provider.js";
|
|
@@ -84,7 +89,8 @@ export function useIsAuthenticated() {
|
|
|
84
89
|
|
|
85
90
|
export function useCoValueSubscription<
|
|
86
91
|
S extends CoValueClassOrSchema,
|
|
87
|
-
|
|
92
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
93
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
88
94
|
>(
|
|
89
95
|
Schema: S,
|
|
90
96
|
id: string | undefined | null,
|
|
@@ -114,10 +120,12 @@ export function useCoValueSubscription<
|
|
|
114
120
|
};
|
|
115
121
|
}
|
|
116
122
|
|
|
123
|
+
const resolve = getResolveQuery(Schema, options?.resolve);
|
|
124
|
+
|
|
117
125
|
const node = contextManager.getCurrentValue()!.node;
|
|
118
126
|
const subscription = new SubscriptionScope<any>(
|
|
119
127
|
node,
|
|
120
|
-
|
|
128
|
+
resolve,
|
|
121
129
|
id,
|
|
122
130
|
{
|
|
123
131
|
ref: coValueClassFromCoValueClassOrSchema(Schema),
|
|
@@ -164,6 +172,42 @@ export function useCoValueSubscription<
|
|
|
164
172
|
return subscription.subscription as CoValueSubscription<S, R>;
|
|
165
173
|
}
|
|
166
174
|
|
|
175
|
+
function getSubscriptionValue<C extends CoValue>(
|
|
176
|
+
subscription: SubscriptionScope<C> | null,
|
|
177
|
+
): MaybeLoaded<C> {
|
|
178
|
+
if (!subscription) {
|
|
179
|
+
return createUnloadedCoValue("", CoValueLoadingState.UNAVAILABLE);
|
|
180
|
+
}
|
|
181
|
+
const value = subscription.getCurrentValue();
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
return createUnloadedCoValue(subscription.id, value);
|
|
184
|
+
}
|
|
185
|
+
return value;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function useGetCurrentValue<C extends CoValue>(
|
|
189
|
+
subscription: SubscriptionScope<C> | null,
|
|
190
|
+
) {
|
|
191
|
+
const previousValue = useRef<MaybeLoaded<CoValue> | undefined>(undefined);
|
|
192
|
+
|
|
193
|
+
return useCallback(() => {
|
|
194
|
+
const currentValue = getSubscriptionValue(subscription);
|
|
195
|
+
// Avoid re-renders if the value is not loaded and didn't change
|
|
196
|
+
if (
|
|
197
|
+
previousValue.current !== undefined &&
|
|
198
|
+
previousValue.current.$jazz.id === currentValue.$jazz.id &&
|
|
199
|
+
!previousValue.current.$isLoaded &&
|
|
200
|
+
!currentValue.$isLoaded &&
|
|
201
|
+
previousValue.current.$jazz.loadingState ===
|
|
202
|
+
currentValue.$jazz.loadingState
|
|
203
|
+
) {
|
|
204
|
+
return previousValue.current as MaybeLoaded<C>;
|
|
205
|
+
}
|
|
206
|
+
previousValue.current = currentValue;
|
|
207
|
+
return currentValue;
|
|
208
|
+
}, [subscription]);
|
|
209
|
+
}
|
|
210
|
+
|
|
167
211
|
/**
|
|
168
212
|
* React hook for subscribing to CoValues and handling loading states.
|
|
169
213
|
*
|
|
@@ -171,7 +215,38 @@ export function useCoValueSubscription<
|
|
|
171
215
|
* handles the subscription lifecycle (subscribe on mount, unsubscribe on unmount).
|
|
172
216
|
* It also supports deep loading of nested CoValues through resolve queries.
|
|
173
217
|
*
|
|
174
|
-
*
|
|
218
|
+
* The {@param options.select} function allows returning only specific parts of the CoValue data,
|
|
219
|
+
* which helps reduce unnecessary re-renders by narrowing down the returned data.
|
|
220
|
+
* Additionally, you can provide a custom {@param options.equalityFn} to further optimize
|
|
221
|
+
* performance by controlling when the component should re-render based on the selected data.
|
|
222
|
+
*
|
|
223
|
+
* @returns The loaded CoValue, or an {@link NotLoaded} value. Use `$isLoaded` to check whether the
|
|
224
|
+
* CoValue is loaded, or use {@link MaybeLoaded.$jazz.loadingState} to get the detailed loading state.
|
|
225
|
+
* If a selector function is provided, returns the result of the selector function.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```tsx
|
|
229
|
+
* // Select only specific fields to reduce re-renders
|
|
230
|
+
* const Project = co.map({
|
|
231
|
+
* name: z.string(),
|
|
232
|
+
* description: z.string(),
|
|
233
|
+
* tasks: co.list(Task),
|
|
234
|
+
* lastModified: z.date(),
|
|
235
|
+
* });
|
|
236
|
+
*
|
|
237
|
+
* function ProjectTitle({ projectId }: { projectId: string }) {
|
|
238
|
+
* // Only re-render when the project name changes, not other fields
|
|
239
|
+
* const projectName = useCoState(
|
|
240
|
+
* Project,
|
|
241
|
+
* projectId,
|
|
242
|
+
* {
|
|
243
|
+
* select: (project) => !project.$isLoading ? project.name : "Loading...",
|
|
244
|
+
* }
|
|
245
|
+
* );
|
|
246
|
+
*
|
|
247
|
+
* return <h1>{projectName}</h1>;
|
|
248
|
+
* }
|
|
249
|
+
* ```
|
|
175
250
|
*
|
|
176
251
|
* @example
|
|
177
252
|
* ```tsx
|
|
@@ -190,10 +265,15 @@ export function useCoValueSubscription<
|
|
|
190
265
|
* },
|
|
191
266
|
* });
|
|
192
267
|
*
|
|
193
|
-
* if (!project) {
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
268
|
+
* if (!project.$isLoaded) {
|
|
269
|
+
* switch (project.$jazz.loadingState) {
|
|
270
|
+
* case "unauthorized":
|
|
271
|
+
* return "Project not accessible";
|
|
272
|
+
* case "unavailable":
|
|
273
|
+
* return "Project not found";
|
|
274
|
+
* case "loading":
|
|
275
|
+
* return "Loading project...";
|
|
276
|
+
* }
|
|
197
277
|
* }
|
|
198
278
|
*
|
|
199
279
|
* return (
|
|
@@ -223,14 +303,19 @@ export function useCoValueSubscription<
|
|
|
223
303
|
* const task = useCoState(Task, taskId, {
|
|
224
304
|
* resolve: {
|
|
225
305
|
* assignee: true,
|
|
226
|
-
* subtasks: { $each: { $onError:
|
|
306
|
+
* subtasks: { $each: { $onError: 'catch' } },
|
|
227
307
|
* },
|
|
228
308
|
* });
|
|
229
309
|
*
|
|
230
|
-
* if (!task) {
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
310
|
+
* if (!task.$isLoaded) {
|
|
311
|
+
* switch (task.$jazz.loadingState) {
|
|
312
|
+
* case "unauthorized":
|
|
313
|
+
* return "Task not accessible";
|
|
314
|
+
* case "unavailable":
|
|
315
|
+
* return "Task not found";
|
|
316
|
+
* case "loading":
|
|
317
|
+
* return "Loading task...";
|
|
318
|
+
* }
|
|
234
319
|
* }
|
|
235
320
|
*
|
|
236
321
|
* return (
|
|
@@ -239,7 +324,7 @@ export function useCoValueSubscription<
|
|
|
239
324
|
* {task.assignee && <p>Assigned to: {task.assignee.name}</p>}
|
|
240
325
|
* <ul>
|
|
241
326
|
* {task.subtasks.map((subtask, index) => (
|
|
242
|
-
* subtask ? <li key={subtask.id}>{subtask.title}</li> : <li key={index}>Inaccessible subtask</li>
|
|
327
|
+
* subtask.$isLoaded ? <li key={subtask.id}>{subtask.title}</li> : <li key={index}>Inaccessible subtask</li>
|
|
243
328
|
* ))}
|
|
244
329
|
* </ul>
|
|
245
330
|
* </div>
|
|
@@ -247,108 +332,19 @@ export function useCoValueSubscription<
|
|
|
247
332
|
* }
|
|
248
333
|
* ```
|
|
249
334
|
*
|
|
250
|
-
* For more examples, see the [subscription and deep loading](https://jazz.tools/docs/react/using-covalues/subscription-and-loading) documentation.
|
|
251
|
-
*/
|
|
252
|
-
export function useCoState<
|
|
253
|
-
S extends CoValueClassOrSchema,
|
|
254
|
-
const R extends ResolveQuery<S> = true,
|
|
255
|
-
>(
|
|
256
|
-
/** The CoValue schema or class constructor */
|
|
257
|
-
Schema: S,
|
|
258
|
-
/** The ID of the CoValue to subscribe to. If `undefined`, returns `null` */
|
|
259
|
-
id: string | undefined,
|
|
260
|
-
/** Optional configuration for the subscription */
|
|
261
|
-
options?: {
|
|
262
|
-
/** Resolve query to specify which nested CoValues to load */
|
|
263
|
-
resolve?: ResolveQueryStrict<S, R>;
|
|
264
|
-
/**
|
|
265
|
-
* Create or load a branch for isolated editing.
|
|
266
|
-
*
|
|
267
|
-
* Branching lets you take a snapshot of the current state and start modifying it without affecting the canonical/shared version.
|
|
268
|
-
* It's a fork of your data graph: the same schema, but with diverging values.
|
|
269
|
-
*
|
|
270
|
-
* The checkout of the branch is applied on all the resolved values.
|
|
271
|
-
*
|
|
272
|
-
* @param name - A unique name for the branch. This identifies the branch
|
|
273
|
-
* and can be used to switch between different branches of the same CoValue.
|
|
274
|
-
* @param owner - The owner of the branch. Determines who can access and modify
|
|
275
|
-
* the branch. If not provided, the branch is owned by the current user.
|
|
276
|
-
*
|
|
277
|
-
* For more info see the [branching](https://jazz.tools/docs/react/using-covalues/version-control) documentation.
|
|
278
|
-
*/
|
|
279
|
-
unstable_branch?: BranchDefinition;
|
|
280
|
-
},
|
|
281
|
-
): Loaded<S, R> | undefined | null {
|
|
282
|
-
const subscription = useCoValueSubscription(Schema, id, options);
|
|
283
|
-
|
|
284
|
-
const value = React.useSyncExternalStore<Loaded<S, R> | undefined | null>(
|
|
285
|
-
React.useCallback(
|
|
286
|
-
(callback) => {
|
|
287
|
-
if (!subscription) {
|
|
288
|
-
return () => {};
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return subscription.subscribe(callback);
|
|
292
|
-
},
|
|
293
|
-
[subscription],
|
|
294
|
-
),
|
|
295
|
-
() => (subscription ? subscription.getCurrentValue() : null),
|
|
296
|
-
() => (subscription ? subscription.getCurrentValue() : null),
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
return value;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* React hook for subscribing to CoValues with selective data extraction and custom equality checking.
|
|
304
|
-
*
|
|
305
|
-
* This hook extends `useCoState` by allowing you to select only specific parts of the CoValue data
|
|
306
|
-
* through a selector function, which helps reduce unnecessary re-renders by narrowing down the
|
|
307
|
-
* returned data. Additionally, you can provide a custom equality function to further optimize
|
|
308
|
-
* performance by controlling when the component should re-render based on the selected data.
|
|
309
|
-
*
|
|
310
|
-
* The hook automatically handles the subscription lifecycle and supports deep loading of nested
|
|
311
|
-
* CoValues through resolve queries, just like `useCoState`.
|
|
312
|
-
*
|
|
313
|
-
* @returns The result of the selector function applied to the loaded CoValue data
|
|
314
|
-
*
|
|
315
|
-
* @example
|
|
316
|
-
* ```tsx
|
|
317
|
-
* // Select only specific fields to reduce re-renders
|
|
318
|
-
* const Project = co.map({
|
|
319
|
-
* name: z.string(),
|
|
320
|
-
* description: z.string(),
|
|
321
|
-
* tasks: co.list(Task),
|
|
322
|
-
* lastModified: z.date(),
|
|
323
|
-
* });
|
|
324
|
-
*
|
|
325
|
-
* function ProjectTitle({ projectId }: { projectId: string }) {
|
|
326
|
-
* // Only re-render when the project name changes, not other fields
|
|
327
|
-
* const projectName = useCoStateWithSelector(
|
|
328
|
-
* Project,
|
|
329
|
-
* projectId,
|
|
330
|
-
* {
|
|
331
|
-
* select: (project) => project?.name ?? "Loading...",
|
|
332
|
-
* }
|
|
333
|
-
* );
|
|
334
|
-
*
|
|
335
|
-
* return <h1>{projectName}</h1>;
|
|
336
|
-
* }
|
|
337
|
-
* ```
|
|
338
|
-
*
|
|
339
335
|
* @example
|
|
340
336
|
* ```tsx
|
|
341
337
|
* // Use custom equality function for complex data structures
|
|
342
338
|
* const TaskList = co.list(Task);
|
|
343
339
|
*
|
|
344
340
|
* function TaskCount({ listId }: { listId: string }) {
|
|
345
|
-
* const taskStats =
|
|
341
|
+
* const taskStats = useCoState(
|
|
346
342
|
* TaskList,
|
|
347
343
|
* listId,
|
|
348
344
|
* {
|
|
349
345
|
* resolve: { $each: true },
|
|
350
346
|
* select: (tasks) => {
|
|
351
|
-
* if (!tasks) return { total: 0, completed: 0 };
|
|
347
|
+
* if (!tasks.$isLoaded) return { total: 0, completed: 0 };
|
|
352
348
|
* return {
|
|
353
349
|
* total: tasks.length,
|
|
354
350
|
* completed: tasks.filter(task => task.completed).length,
|
|
@@ -367,72 +363,24 @@ export function useCoState<
|
|
|
367
363
|
* }
|
|
368
364
|
* ```
|
|
369
365
|
*
|
|
370
|
-
* @example
|
|
371
|
-
* ```tsx
|
|
372
|
-
* // Combine with deep loading and complex selectors
|
|
373
|
-
* const Team = co.map({
|
|
374
|
-
* name: z.string(),
|
|
375
|
-
* members: co.list(TeamMember),
|
|
376
|
-
* projects: co.list(Project),
|
|
377
|
-
* });
|
|
378
|
-
*
|
|
379
|
-
* function TeamSummary({ teamId }: { teamId: string }) {
|
|
380
|
-
* const summary = useCoStateWithSelector(
|
|
381
|
-
* Team,
|
|
382
|
-
* teamId,
|
|
383
|
-
* {
|
|
384
|
-
* resolve: {
|
|
385
|
-
* members: { $each: true },
|
|
386
|
-
* projects: { $each: { tasks: { $each: true } } },
|
|
387
|
-
* },
|
|
388
|
-
* select: (team) => {
|
|
389
|
-
* if (!team) return null;
|
|
390
|
-
*
|
|
391
|
-
* const totalTasks = team.projects.reduce(
|
|
392
|
-
* (sum, project) => sum + project.tasks.length,
|
|
393
|
-
* 0
|
|
394
|
-
* );
|
|
395
|
-
*
|
|
396
|
-
* return {
|
|
397
|
-
* teamName: team.name,
|
|
398
|
-
* memberCount: team.members.length,
|
|
399
|
-
* projectCount: team.projects.length,
|
|
400
|
-
* totalTasks,
|
|
401
|
-
* };
|
|
402
|
-
* },
|
|
403
|
-
* }
|
|
404
|
-
* );
|
|
405
|
-
*
|
|
406
|
-
* if (!summary) return <div>Loading team summary...</div>;
|
|
407
|
-
*
|
|
408
|
-
* return (
|
|
409
|
-
* <div>
|
|
410
|
-
* <h2>{summary.teamName}</h2>
|
|
411
|
-
* <p>{summary.memberCount} members</p>
|
|
412
|
-
* <p>{summary.projectCount} projects</p>
|
|
413
|
-
* <p>{summary.totalTasks} total tasks</p>
|
|
414
|
-
* </div>
|
|
415
|
-
* );
|
|
416
|
-
* }
|
|
417
|
-
* ```
|
|
418
|
-
*
|
|
419
366
|
* For more examples, see the [subscription and deep loading](https://jazz.tools/docs/react/using-covalues/subscription-and-loading) documentation.
|
|
420
367
|
*/
|
|
421
|
-
export function
|
|
368
|
+
export function useCoState<
|
|
422
369
|
S extends CoValueClassOrSchema,
|
|
423
|
-
|
|
424
|
-
const R extends ResolveQuery<S> =
|
|
370
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
371
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
372
|
+
TSelectorReturn = MaybeLoaded<Loaded<S, R>>,
|
|
425
373
|
>(
|
|
426
374
|
/** The CoValue schema or class constructor */
|
|
427
375
|
Schema: S,
|
|
428
|
-
/** The ID of the CoValue to subscribe to. If `undefined`, returns
|
|
376
|
+
/** The ID of the CoValue to subscribe to. If `undefined`, returns an `unavailable` value */
|
|
429
377
|
id: string | undefined,
|
|
430
378
|
/** Optional configuration for the subscription */
|
|
431
|
-
options
|
|
379
|
+
options?: {
|
|
432
380
|
/** Resolve query to specify which nested CoValues to load */
|
|
433
381
|
resolve?: ResolveQueryStrict<S, R>;
|
|
434
382
|
/** Select which value to return */
|
|
435
|
-
select
|
|
383
|
+
select?: (value: MaybeLoaded<Loaded<S, R>>) => TSelectorReturn;
|
|
436
384
|
/** Equality function to determine if the selected value has changed, defaults to `Object.is` */
|
|
437
385
|
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
438
386
|
/**
|
|
@@ -454,9 +402,10 @@ export function useCoStateWithSelector<
|
|
|
454
402
|
},
|
|
455
403
|
): TSelectorReturn {
|
|
456
404
|
const subscription = useCoValueSubscription(Schema, id, options);
|
|
405
|
+
const getCurrentValue = useGetCurrentValue(subscription);
|
|
457
406
|
|
|
458
|
-
|
|
459
|
-
Loaded<S, R
|
|
407
|
+
const value = useSyncExternalStoreWithSelector<
|
|
408
|
+
MaybeLoaded<Loaded<S, R>>,
|
|
460
409
|
TSelectorReturn
|
|
461
410
|
>(
|
|
462
411
|
React.useCallback(
|
|
@@ -469,26 +418,31 @@ export function useCoStateWithSelector<
|
|
|
469
418
|
},
|
|
470
419
|
[subscription],
|
|
471
420
|
),
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
options
|
|
475
|
-
options
|
|
421
|
+
getCurrentValue,
|
|
422
|
+
getCurrentValue,
|
|
423
|
+
options?.select ?? ((value) => value as TSelectorReturn),
|
|
424
|
+
options?.equalityFn ?? Object.is,
|
|
476
425
|
);
|
|
426
|
+
|
|
427
|
+
return value;
|
|
477
428
|
}
|
|
478
429
|
|
|
479
430
|
export function useSubscriptionSelector<
|
|
480
431
|
S extends CoValueClassOrSchema,
|
|
481
|
-
|
|
482
|
-
|
|
432
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
433
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
434
|
+
TSelectorReturn = MaybeLoaded<Loaded<S, R>>,
|
|
483
435
|
>(
|
|
484
436
|
subscription: CoValueSubscription<S, R>,
|
|
485
437
|
options?: {
|
|
486
|
-
select?: (value: Loaded<S, R
|
|
438
|
+
select?: (value: MaybeLoaded<Loaded<S, R>>) => TSelectorReturn;
|
|
487
439
|
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
488
440
|
},
|
|
489
441
|
) {
|
|
442
|
+
const getCurrentValue = useGetCurrentValue(subscription);
|
|
443
|
+
|
|
490
444
|
return useSyncExternalStoreWithSelector<
|
|
491
|
-
Loaded<S, R
|
|
445
|
+
MaybeLoaded<Loaded<S, R>>,
|
|
492
446
|
TSelectorReturn
|
|
493
447
|
>(
|
|
494
448
|
React.useCallback(
|
|
@@ -501,8 +455,8 @@ export function useSubscriptionSelector<
|
|
|
501
455
|
},
|
|
502
456
|
[subscription],
|
|
503
457
|
),
|
|
504
|
-
|
|
505
|
-
|
|
458
|
+
getCurrentValue,
|
|
459
|
+
getCurrentValue,
|
|
506
460
|
options?.select ?? ((value) => value as TSelectorReturn),
|
|
507
461
|
options?.equalityFn ?? Object.is,
|
|
508
462
|
);
|
|
@@ -510,7 +464,8 @@ export function useSubscriptionSelector<
|
|
|
510
464
|
|
|
511
465
|
export function useAccountSubscription<
|
|
512
466
|
S extends AccountClass<Account> | AnyAccountSchema,
|
|
513
|
-
|
|
467
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
468
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
514
469
|
>(
|
|
515
470
|
Schema: S,
|
|
516
471
|
options?: {
|
|
@@ -531,8 +486,7 @@ export function useAccountSubscription<
|
|
|
531
486
|
};
|
|
532
487
|
}
|
|
533
488
|
|
|
534
|
-
|
|
535
|
-
const resolve: any = options?.resolve ?? true;
|
|
489
|
+
const resolve = getResolveQuery(Schema, options?.resolve);
|
|
536
490
|
|
|
537
491
|
const node = contextManager.getCurrentValue()!.node;
|
|
538
492
|
const subscription = new SubscriptionScope<any>(
|
|
@@ -583,22 +537,55 @@ export function useAccountSubscription<
|
|
|
583
537
|
}
|
|
584
538
|
|
|
585
539
|
/**
|
|
586
|
-
* React hook for accessing the current user's account
|
|
587
|
-
*
|
|
588
|
-
* This hook provides access to the current user's account profile and root data
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
* @
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
|
|
540
|
+
* React hook for accessing the current user's account.
|
|
541
|
+
*
|
|
542
|
+
* This hook provides access to the current user's account profile and root data.
|
|
543
|
+
* It automatically handles the subscription lifecycle and supports deep loading of nested
|
|
544
|
+
* CoValues through resolve queries.
|
|
545
|
+
*
|
|
546
|
+
* The {@param options.select} function allows returning only specific parts of the account data,
|
|
547
|
+
* which helps reduce unnecessary re-renders by narrowing down the returned data.
|
|
548
|
+
* Additionally, you can provide a custom {@param options.equalityFn} to further optimize
|
|
549
|
+
* performance by controlling when the component should re-render based on the selected data.
|
|
550
|
+
*
|
|
551
|
+
* @returns The account data, or an {@link NotLoaded} value. Use `$isLoaded` to check whether the
|
|
552
|
+
* CoValue is loaded, or use {@link MaybeLoaded.$jazz.loadingState} to get the detailed loading state.
|
|
553
|
+
* If a selector function is provided, returns the result of the selector function.
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```tsx
|
|
557
|
+
* // Select only specific fields to reduce re-renders
|
|
558
|
+
* const MyAppAccount = co.account({
|
|
559
|
+
* profile: co.profile(),
|
|
560
|
+
* root: co.map({
|
|
561
|
+
* name: z.string(),
|
|
562
|
+
* email: z.string(),
|
|
563
|
+
* lastLogin: z.date(),
|
|
564
|
+
* }),
|
|
565
|
+
* });
|
|
566
|
+
*
|
|
567
|
+
* function UserProfile({ accountId }: { accountId: string }) {
|
|
568
|
+
* // Only re-render when the profile name changes, not other fields
|
|
569
|
+
* const profileName = useAccount(
|
|
570
|
+
* MyAppAccount,
|
|
571
|
+
* {
|
|
572
|
+
* resolve: {
|
|
573
|
+
* profile: true,
|
|
574
|
+
* root: true,
|
|
575
|
+
* },
|
|
576
|
+
* select: (account) => account.$isLoaded ? account.profile.name : "Loading...",
|
|
577
|
+
* }
|
|
578
|
+
* );
|
|
579
|
+
*
|
|
580
|
+
* return <h1>{profileName}</h1>;
|
|
581
|
+
* }
|
|
582
|
+
* ```
|
|
583
|
+
*
|
|
597
584
|
* @example
|
|
598
585
|
* ```tsx
|
|
599
586
|
* // Deep loading with resolve queries
|
|
600
587
|
* function ProjectListWithDetails() {
|
|
601
|
-
* const
|
|
588
|
+
* const me = useAccount(MyAppAccount, {
|
|
602
589
|
* resolve: {
|
|
603
590
|
* profile: true,
|
|
604
591
|
* root: {
|
|
@@ -610,13 +597,18 @@ export function useAccountSubscription<
|
|
|
610
597
|
* },
|
|
611
598
|
* },
|
|
612
599
|
* });
|
|
613
|
-
*
|
|
614
|
-
* if (!me) {
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
600
|
+
*
|
|
601
|
+
* if (!me.$isLoaded) {
|
|
602
|
+
* switch (me.$jazz.loadingState) {
|
|
603
|
+
* case "unauthorized":
|
|
604
|
+
* return "Account not accessible";
|
|
605
|
+
* case "unavailable":
|
|
606
|
+
* return "Account not found";
|
|
607
|
+
* case "loading":
|
|
608
|
+
* return "Loading account...";
|
|
609
|
+
* }
|
|
618
610
|
* }
|
|
619
|
-
*
|
|
611
|
+
*
|
|
620
612
|
* return (
|
|
621
613
|
* <div>
|
|
622
614
|
* <h1>{me.profile.name}'s projects</h1>
|
|
@@ -631,124 +623,22 @@ export function useAccountSubscription<
|
|
|
631
623
|
* );
|
|
632
624
|
* }
|
|
633
625
|
* ```
|
|
634
|
-
*
|
|
626
|
+
*
|
|
635
627
|
*/
|
|
636
628
|
export function useAccount<
|
|
637
629
|
A extends AccountClass<Account> | AnyAccountSchema,
|
|
638
|
-
|
|
630
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
631
|
+
const R extends ResolveQuery<A> = SchemaResolveQuery<A>,
|
|
632
|
+
TSelectorReturn = MaybeLoaded<Loaded<A, R>>,
|
|
639
633
|
>(
|
|
640
634
|
/** The account schema to use. Defaults to the base Account schema */
|
|
641
635
|
AccountSchema: A = Account as unknown as A,
|
|
642
636
|
/** Optional configuration for the subscription */
|
|
643
637
|
options?: {
|
|
644
|
-
/** Resolve query to specify which nested CoValues to load from the account */
|
|
645
|
-
resolve?: ResolveQueryStrict<A, R>;
|
|
646
|
-
/**
|
|
647
|
-
* Create or load a branch for isolated editing.
|
|
648
|
-
*
|
|
649
|
-
* Branching lets you take a snapshot of the current state and start modifying it without affecting the canonical/shared version.
|
|
650
|
-
* It's a fork of your data graph: the same schema, but with diverging values.
|
|
651
|
-
*
|
|
652
|
-
* The checkout of the branch is applied on all the resolved values.
|
|
653
|
-
*
|
|
654
|
-
* @param name - A unique name for the branch. This identifies the branch
|
|
655
|
-
* and can be used to switch between different branches of the same CoValue.
|
|
656
|
-
* @param owner - The owner of the branch. Determines who can access and modify
|
|
657
|
-
* the branch. If not provided, the branch is owned by the current user.
|
|
658
|
-
*
|
|
659
|
-
* For more info see the [branching](https://jazz.tools/docs/react/using-covalues/version-control) documentation.
|
|
660
|
-
*/
|
|
661
|
-
unstable_branch?: BranchDefinition;
|
|
662
|
-
},
|
|
663
|
-
): {
|
|
664
|
-
me: Loaded<A, R> | undefined | null;
|
|
665
|
-
agent: AnonymousJazzAgent | Loaded<A, true>;
|
|
666
|
-
logOut: () => void;
|
|
667
|
-
} {
|
|
668
|
-
const contextManager = useJazzContextManager<InstanceOfSchema<A>>();
|
|
669
|
-
const subscription = useAccountSubscription(AccountSchema, options);
|
|
670
|
-
|
|
671
|
-
const agent = getCurrentAccountFromContextManager(contextManager);
|
|
672
|
-
|
|
673
|
-
const value = React.useSyncExternalStore<Loaded<A, R> | undefined | null>(
|
|
674
|
-
React.useCallback(
|
|
675
|
-
(callback) => {
|
|
676
|
-
if (!subscription) {
|
|
677
|
-
return () => {};
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
return subscription.subscribe(callback);
|
|
681
|
-
},
|
|
682
|
-
[subscription],
|
|
683
|
-
),
|
|
684
|
-
() => (subscription ? subscription.getCurrentValue() : null),
|
|
685
|
-
() => (subscription ? subscription.getCurrentValue() : null),
|
|
686
|
-
);
|
|
687
|
-
|
|
688
|
-
return {
|
|
689
|
-
me: value,
|
|
690
|
-
agent,
|
|
691
|
-
logOut: contextManager.logOut,
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* React hook for accessing the current user's account with selective data extraction and custom equality checking.
|
|
697
|
-
*
|
|
698
|
-
* This hook extends `useAccount` by allowing you to select only specific parts of the account data
|
|
699
|
-
* through a selector function, which helps reduce unnecessary re-renders by narrowing down the
|
|
700
|
-
* returned data. Additionally, you can provide a custom equality function to further optimize
|
|
701
|
-
* performance by controlling when the component should re-render based on the selected data.
|
|
702
|
-
*
|
|
703
|
-
* The hook automatically handles the subscription lifecycle and supports deep loading of nested
|
|
704
|
-
* CoValues through resolve queries, just like `useAccount`.
|
|
705
|
-
*
|
|
706
|
-
* @returns The result of the selector function applied to the loaded account data
|
|
707
|
-
*
|
|
708
|
-
* @example
|
|
709
|
-
* ```tsx
|
|
710
|
-
* // Select only specific fields to reduce re-renders
|
|
711
|
-
* const MyAppAccount = co.account({
|
|
712
|
-
* profile: co.profile(),
|
|
713
|
-
* root: co.map({
|
|
714
|
-
* name: z.string(),
|
|
715
|
-
* email: z.string(),
|
|
716
|
-
* lastLogin: z.date(),
|
|
717
|
-
* }),
|
|
718
|
-
* });
|
|
719
|
-
*
|
|
720
|
-
* function UserProfile({ accountId }: { accountId: string }) {
|
|
721
|
-
* // Only re-render when the profile name changes, not other fields
|
|
722
|
-
* const profileName = useAccountWithSelector(
|
|
723
|
-
* MyAppAccount,
|
|
724
|
-
* {
|
|
725
|
-
* resolve: {
|
|
726
|
-
* profile: true,
|
|
727
|
-
* root: true,
|
|
728
|
-
* },
|
|
729
|
-
* select: (account) => account?.profile?.name ?? "Loading...",
|
|
730
|
-
* }
|
|
731
|
-
* );
|
|
732
|
-
*
|
|
733
|
-
* return <h1>{profileName}</h1>;
|
|
734
|
-
* }
|
|
735
|
-
* ```
|
|
736
|
-
*
|
|
737
|
-
* For more examples, see the [subscription and deep loading](https://jazz.tools/docs/react/using-covalues/subscription-and-loading) documentation.
|
|
738
|
-
*/
|
|
739
|
-
export function useAccountWithSelector<
|
|
740
|
-
A extends AccountClass<Account> | AnyAccountSchema,
|
|
741
|
-
TSelectorReturn,
|
|
742
|
-
R extends ResolveQuery<A> = true,
|
|
743
|
-
>(
|
|
744
|
-
/** The account schema to use. Defaults to the base Account schema */
|
|
745
|
-
AccountSchema: A = Account as unknown as A,
|
|
746
|
-
/** Configuration for the subscription and selection */
|
|
747
|
-
options: {
|
|
748
638
|
/** Resolve query to specify which nested CoValues to load from the account */
|
|
749
639
|
resolve?: ResolveQueryStrict<A, R>;
|
|
750
640
|
/** Select which value to return from the account data */
|
|
751
|
-
select
|
|
641
|
+
select?: (account: MaybeLoaded<Loaded<A, R>>) => TSelectorReturn;
|
|
752
642
|
/** Equality function to determine if the selected value has changed, defaults to `Object.is` */
|
|
753
643
|
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
754
644
|
/**
|
|
@@ -770,9 +660,10 @@ export function useAccountWithSelector<
|
|
|
770
660
|
},
|
|
771
661
|
): TSelectorReturn {
|
|
772
662
|
const subscription = useAccountSubscription(AccountSchema, options);
|
|
663
|
+
const getCurrentValue = useGetCurrentValue(subscription);
|
|
773
664
|
|
|
774
665
|
return useSyncExternalStoreWithSelector<
|
|
775
|
-
Loaded<A, R
|
|
666
|
+
MaybeLoaded<Loaded<A, R>>,
|
|
776
667
|
TSelectorReturn
|
|
777
668
|
>(
|
|
778
669
|
React.useCallback(
|
|
@@ -785,10 +676,10 @@ export function useAccountWithSelector<
|
|
|
785
676
|
},
|
|
786
677
|
[subscription],
|
|
787
678
|
),
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
options
|
|
791
|
-
options
|
|
679
|
+
getCurrentValue,
|
|
680
|
+
getCurrentValue,
|
|
681
|
+
options?.select ?? ((value) => value as TSelectorReturn),
|
|
682
|
+
options?.equalityFn ?? Object.is,
|
|
792
683
|
);
|
|
793
684
|
}
|
|
794
685
|
|
|
@@ -800,6 +691,22 @@ export function useLogOut(): () => void {
|
|
|
800
691
|
return contextManager.logOut;
|
|
801
692
|
}
|
|
802
693
|
|
|
694
|
+
/**
|
|
695
|
+
* React hook for accessing the current agent. An agent can either be:
|
|
696
|
+
* - an Authenticated Account, if the user is logged in
|
|
697
|
+
* - an Anonymous Account, if the user didn't log in
|
|
698
|
+
* - or an anonymous agent, if in guest mode
|
|
699
|
+
*
|
|
700
|
+
* The agent can be used as the `loadAs` parameter for load and subscribe methods.
|
|
701
|
+
*/
|
|
702
|
+
export function useAgent<
|
|
703
|
+
A extends AccountClass<Account> | AnyAccountSchema = typeof Account,
|
|
704
|
+
>(): AnonymousJazzAgent | Loaded<A, true> {
|
|
705
|
+
const contextManager = useJazzContextManager<InstanceOfSchema<A>>();
|
|
706
|
+
const agent = getCurrentAccountFromContextManager(contextManager);
|
|
707
|
+
return agent as AnonymousJazzAgent | Loaded<A, true>;
|
|
708
|
+
}
|
|
709
|
+
|
|
803
710
|
export function experimental_useInboxSender<
|
|
804
711
|
I extends CoValue,
|
|
805
712
|
O extends CoValue | undefined,
|
|
@@ -866,3 +773,18 @@ export function useSyncConnectionStatus() {
|
|
|
866
773
|
|
|
867
774
|
return connected;
|
|
868
775
|
}
|
|
776
|
+
|
|
777
|
+
function getResolveQuery(
|
|
778
|
+
Schema: CoValueClassOrSchema,
|
|
779
|
+
// We don't need type validation here, since this is an internal API
|
|
780
|
+
resolveQuery?: ResolveQuery<any>,
|
|
781
|
+
): ResolveQuery<any> {
|
|
782
|
+
if (resolveQuery) {
|
|
783
|
+
return resolveQuery;
|
|
784
|
+
}
|
|
785
|
+
// Check the schema is a CoValue schema (and not a CoValue class)
|
|
786
|
+
if ("resolveQuery" in Schema) {
|
|
787
|
+
return Schema.resolveQuery;
|
|
788
|
+
}
|
|
789
|
+
return true;
|
|
790
|
+
}
|