jazz-tools 0.19.20 → 0.19.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.svelte-kit/__package__/server.d.ts.map +1 -1
- package/.svelte-kit/__package__/server.js +9 -7
- package/.turbo/turbo-build.log +52 -52
- package/dist/better-auth/auth/server.d.ts.map +1 -1
- package/dist/better-auth/auth/server.js +4 -4
- package/dist/better-auth/auth/server.js.map +1 -1
- package/dist/better-auth/database-adapter/index.js.map +1 -1
- package/dist/better-auth/database-adapter/repository/generic.d.ts +3 -3
- package/dist/better-auth/database-adapter/repository/session.d.ts +2 -2
- package/dist/better-auth/database-adapter/schema.d.ts +3 -3
- package/dist/better-auth/database-adapter/schema.d.ts.map +1 -1
- package/dist/{chunk-MI24YFCY.js → chunk-QCTQH5RS.js} +1 -1
- package/dist/chunk-QCTQH5RS.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/hooks.d.ts +1 -2
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/index.js +7 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react-core/hooks.d.ts +92 -1
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +126 -57
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/tests/useCoStates.test.d.ts +2 -0
- package/dist/react-core/tests/useCoStates.test.d.ts.map +1 -0
- package/dist/react-native/index.js +4 -0
- package/dist/react-native/index.js.map +1 -1
- 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 +4 -0
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/svelte/auth/ClerkAuth.svelte.d.ts +38 -0
- package/dist/svelte/auth/ClerkAuth.svelte.d.ts.map +1 -0
- package/dist/svelte/auth/ClerkAuth.svelte.js +47 -0
- package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte +156 -0
- package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte.d.ts +67 -0
- package/dist/svelte/auth/JazzSvelteProviderWithClerk.svelte.d.ts.map +1 -0
- package/dist/svelte/auth/RegisterClerkAuth.svelte +27 -0
- package/dist/svelte/auth/RegisterClerkAuth.svelte.d.ts +17 -0
- package/dist/svelte/auth/RegisterClerkAuth.svelte.d.ts.map +1 -0
- package/dist/svelte/auth/index.d.ts +2 -0
- package/dist/svelte/auth/index.d.ts.map +1 -1
- package/dist/svelte/auth/index.js +2 -0
- package/dist/svelte/tests/ClerkAuth.svelte.test.d.ts +2 -0
- package/dist/svelte/tests/ClerkAuth.svelte.test.d.ts.map +1 -0
- package/dist/svelte/tests/ClerkAuth.svelte.test.js +202 -0
- package/dist/svelte/tests/TestClerkAuthWrapper.svelte +16 -0
- package/dist/svelte/tests/TestClerkAuthWrapper.svelte.d.ts +8 -0
- package/dist/svelte/tests/TestClerkAuthWrapper.svelte.d.ts.map +1 -0
- package/dist/svelte/tests/testUtils.d.ts +1 -0
- package/dist/svelte/tests/testUtils.d.ts.map +1 -1
- package/dist/svelte/tests/testUtils.js +3 -1
- package/dist/testing.js +1 -1
- package/dist/tools/auth/clerk/index.d.ts +1 -1
- package/dist/tools/auth/clerk/types.d.ts +1 -1
- package/dist/tools/auth/clerk/types.d.ts.map +1 -1
- package/dist/tools/subscribe/types.d.ts +1 -1
- package/dist/tools/subscribe/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/better-auth/auth/server.ts +9 -7
- package/src/better-auth/database-adapter/repository/generic.ts +3 -3
- package/src/better-auth/database-adapter/repository/session.ts +2 -2
- package/src/better-auth/database-adapter/schema.ts +5 -5
- package/src/react/hooks.tsx +4 -2
- package/src/react-core/hooks.ts +321 -76
- package/src/react-core/tests/useCoState.selector.test.ts +309 -22
- package/src/react-core/tests/useCoStates.test.tsx +414 -0
- package/src/react-native-core/hooks.tsx +2 -0
- package/src/svelte/auth/ClerkAuth.svelte.ts +67 -0
- package/src/svelte/auth/JazzSvelteProviderWithClerk.svelte +156 -0
- package/src/svelte/auth/RegisterClerkAuth.svelte +27 -0
- package/src/svelte/auth/index.ts +2 -0
- package/src/svelte/tests/ClerkAuth.svelte.test.ts +305 -0
- package/src/svelte/tests/TestClerkAuthWrapper.svelte +16 -0
- package/src/svelte/tests/testUtils.ts +4 -1
- package/src/tools/auth/clerk/types.ts +1 -1
- package/src/tools/subscribe/types.ts +1 -1
- package/src/tools/tests/inbox.test.ts +7 -7
- package/dist/chunk-MI24YFCY.js.map +0 -1
package/src/react-core/hooks.ts
CHANGED
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
Loaded,
|
|
24
24
|
MaybeLoaded,
|
|
25
25
|
NotLoaded,
|
|
26
|
-
RefsToResolve,
|
|
27
26
|
ResolveQuery,
|
|
28
27
|
ResolveQueryStrict,
|
|
29
28
|
SchemaResolveQuery,
|
|
@@ -103,94 +102,107 @@ export function useCoValueSubscription<
|
|
|
103
102
|
resolve?: ResolveQueryStrict<S, R>;
|
|
104
103
|
unstable_branch?: BranchDefinition;
|
|
105
104
|
},
|
|
106
|
-
) {
|
|
105
|
+
): CoValueSubscription<S, R> | null {
|
|
106
|
+
const resolve = getResolveQuery(Schema, options?.resolve);
|
|
107
|
+
const subscriptions = useCoValueSubscriptions(
|
|
108
|
+
Schema,
|
|
109
|
+
[id],
|
|
110
|
+
resolve,
|
|
111
|
+
options?.unstable_branch,
|
|
112
|
+
);
|
|
113
|
+
return (subscriptions[0] ?? null) as CoValueSubscription<S, R> | null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Tracked state for the entire subscriptions array.
|
|
118
|
+
* If any of the dependencies change, the subscriptions are recreated.
|
|
119
|
+
*/
|
|
120
|
+
interface SubscriptionsState {
|
|
121
|
+
subscriptions: (SubscriptionScope<CoValue> | null)[];
|
|
122
|
+
schema: CoValueClassOrSchema;
|
|
123
|
+
ids: readonly (string | undefined | null)[];
|
|
124
|
+
resolve: ResolveQuery<any>;
|
|
125
|
+
contextManager: ReturnType<typeof useJazzContextManager>;
|
|
126
|
+
agent: AnonymousJazzAgent | Loaded<any, true>;
|
|
127
|
+
branchName?: string;
|
|
128
|
+
branchOwnerId?: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Internal hook that manages an array of SubscriptionScope instances.
|
|
133
|
+
*
|
|
134
|
+
* - Uses a ref to track subscriptions by index
|
|
135
|
+
* - Detects changes by comparing schema/ids/resolve/branch
|
|
136
|
+
* - Creates new subscriptions via SubscriptionScopeCache.getOrCreate()
|
|
137
|
+
* - Returns null for entries with undefined/null IDs or invalid branches
|
|
138
|
+
*/
|
|
139
|
+
function useCoValueSubscriptions(
|
|
140
|
+
schema: CoValueClassOrSchema,
|
|
141
|
+
ids: readonly (string | undefined | null)[],
|
|
142
|
+
resolve: ResolveQuery<any>,
|
|
143
|
+
branch?: BranchDefinition,
|
|
144
|
+
): (SubscriptionScope<CoValue> | null)[] {
|
|
107
145
|
const contextManager = useJazzContextManager();
|
|
108
146
|
const agent = useAgent();
|
|
109
147
|
|
|
110
|
-
const callerStack =
|
|
148
|
+
const callerStack = useMemo(() => captureStack(), []);
|
|
111
149
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
150
|
+
const createAllSubscriptions = (): SubscriptionsState => {
|
|
151
|
+
const node = contextManager.getCurrentValue()!.node;
|
|
152
|
+
const cache = contextManager.getSubscriptionScopeCache();
|
|
115
153
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
contextManager,
|
|
121
|
-
id,
|
|
122
|
-
Schema,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
154
|
+
const subscriptions = ids.map((id) => {
|
|
155
|
+
if (id === undefined || id === null) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
125
158
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
contextManager,
|
|
159
|
+
const subscription = cache.getOrCreate(
|
|
160
|
+
node,
|
|
161
|
+
schema,
|
|
130
162
|
id,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
node,
|
|
141
|
-
Schema,
|
|
142
|
-
id,
|
|
143
|
-
resolve,
|
|
144
|
-
false,
|
|
145
|
-
false,
|
|
146
|
-
options?.unstable_branch,
|
|
147
|
-
);
|
|
163
|
+
resolve,
|
|
164
|
+
false,
|
|
165
|
+
false,
|
|
166
|
+
branch,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
if (callerStack) {
|
|
170
|
+
subscription.callerStack = callerStack;
|
|
171
|
+
}
|
|
148
172
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
subscription.callerStack = callerStack.current;
|
|
152
|
-
}
|
|
173
|
+
return subscription;
|
|
174
|
+
});
|
|
153
175
|
|
|
154
176
|
return {
|
|
155
|
-
|
|
177
|
+
subscriptions,
|
|
178
|
+
schema,
|
|
179
|
+
ids,
|
|
180
|
+
resolve,
|
|
156
181
|
contextManager,
|
|
157
|
-
id,
|
|
158
|
-
Schema,
|
|
159
|
-
branchName: options?.unstable_branch?.name,
|
|
160
|
-
branchOwnerId: options?.unstable_branch?.owner?.$jazz.id,
|
|
161
182
|
agent,
|
|
183
|
+
branchName: branch?.name,
|
|
184
|
+
branchOwnerId: branch?.owner?.$jazz.id,
|
|
162
185
|
};
|
|
163
186
|
};
|
|
164
187
|
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
>>(null);
|
|
188
|
+
const stateRef = React.useRef<SubscriptionsState | null>(null);
|
|
189
|
+
const newSubscriptions = createAllSubscriptions();
|
|
168
190
|
|
|
169
|
-
|
|
170
|
-
subscriptionRef.current = createSubscription();
|
|
171
|
-
}
|
|
191
|
+
const state = stateRef.current;
|
|
172
192
|
|
|
173
|
-
|
|
174
|
-
const
|
|
193
|
+
// Avoid recreating the subscriptions array if all subscriptions are already cached
|
|
194
|
+
const anySubscriptionChanged =
|
|
195
|
+
newSubscriptions.subscriptions.length !== state?.subscriptions.length ||
|
|
196
|
+
newSubscriptions.subscriptions.some(
|
|
197
|
+
(newSubscriptions, index) =>
|
|
198
|
+
newSubscriptions !== state.subscriptions[index],
|
|
199
|
+
);
|
|
175
200
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// Check if the subscription needs to be updated
|
|
179
|
-
// because one of the dependencies has changed
|
|
180
|
-
if (
|
|
181
|
-
subscription.contextManager !== contextManager ||
|
|
182
|
-
subscription.id !== id ||
|
|
183
|
-
subscription.Schema !== Schema ||
|
|
184
|
-
subscription.branchName !== branchName ||
|
|
185
|
-
subscription.branchOwnerId !== branchOwnerId ||
|
|
186
|
-
subscription.agent !== agent
|
|
187
|
-
) {
|
|
188
|
-
subscriptionRef.current = createSubscription();
|
|
189
|
-
subscription = subscriptionRef.current;
|
|
201
|
+
if (anySubscriptionChanged) {
|
|
202
|
+
stateRef.current = newSubscriptions;
|
|
190
203
|
}
|
|
191
204
|
|
|
192
|
-
|
|
193
|
-
return subscription.value as CoValueSubscription<S, R>;
|
|
205
|
+
return stateRef.current!.subscriptions;
|
|
194
206
|
}
|
|
195
207
|
|
|
196
208
|
function useImportCoValueContent<V>(
|
|
@@ -471,6 +483,13 @@ export function useSuspenseCoState<
|
|
|
471
483
|
return useSubscriptionSelector(subscription, options);
|
|
472
484
|
}
|
|
473
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Returns a subscription's current value.
|
|
488
|
+
* Allows to optionally select a subset of the subscription's value.
|
|
489
|
+
*
|
|
490
|
+
* This is the single-value counterpart to {@link useSubscriptionsSelector}.
|
|
491
|
+
* Keeping it separate for performance reasons.
|
|
492
|
+
*/
|
|
474
493
|
export function useSubscriptionSelector<
|
|
475
494
|
S extends CoValueClassOrSchema,
|
|
476
495
|
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
@@ -488,7 +507,7 @@ export function useSubscriptionSelector<
|
|
|
488
507
|
): TSelectorReturn {
|
|
489
508
|
const getCurrentValue = useGetCurrentValue(subscription);
|
|
490
509
|
|
|
491
|
-
return useSyncExternalStoreWithSelector
|
|
510
|
+
return useSyncExternalStoreWithSelector(
|
|
492
511
|
React.useCallback(
|
|
493
512
|
(callback) => {
|
|
494
513
|
if (!subscription) {
|
|
@@ -520,10 +539,7 @@ export function useAccountSubscription<
|
|
|
520
539
|
const contextManager = useJazzContextManager();
|
|
521
540
|
|
|
522
541
|
// Capture stack trace at hook call time
|
|
523
|
-
const callerStack =
|
|
524
|
-
if (!callerStack.current) {
|
|
525
|
-
callerStack.current = captureStack();
|
|
526
|
-
}
|
|
542
|
+
const callerStack = useMemo(() => captureStack(), []);
|
|
527
543
|
|
|
528
544
|
const createSubscription = () => {
|
|
529
545
|
const agent = getCurrentAccountFromContextManager(contextManager);
|
|
@@ -551,8 +567,8 @@ export function useAccountSubscription<
|
|
|
551
567
|
);
|
|
552
568
|
|
|
553
569
|
// Set callerStack on returned subscription after retrieval
|
|
554
|
-
if (callerStack
|
|
555
|
-
subscription.callerStack = callerStack
|
|
570
|
+
if (callerStack) {
|
|
571
|
+
subscription.callerStack = callerStack;
|
|
556
572
|
}
|
|
557
573
|
|
|
558
574
|
return {
|
|
@@ -882,3 +898,232 @@ function getResolveQuery(
|
|
|
882
898
|
}
|
|
883
899
|
return true;
|
|
884
900
|
}
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* Internal hook that suspends until all values are loaded.
|
|
904
|
+
*
|
|
905
|
+
* - Creates a Promise.all from individual getCachedPromise() calls
|
|
906
|
+
* - Returns Promise.resolve(null) for null subscriptions (undefined/null IDs)
|
|
907
|
+
* - Suspends via the use() hook until all values are loaded
|
|
908
|
+
*/
|
|
909
|
+
function useSuspendUntilLoaded(
|
|
910
|
+
subscriptions: (SubscriptionScope<CoValue> | null)[],
|
|
911
|
+
): void {
|
|
912
|
+
const combinedPromise = useMemo(() => {
|
|
913
|
+
const promises = subscriptions.map((sub) => {
|
|
914
|
+
if (!sub) {
|
|
915
|
+
// For null subscriptions (undefined/null IDs), resolve immediately with null
|
|
916
|
+
return Promise.resolve(null);
|
|
917
|
+
}
|
|
918
|
+
return sub.getCachedPromise();
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
return Promise.all(promises);
|
|
922
|
+
}, [subscriptions]);
|
|
923
|
+
|
|
924
|
+
use(combinedPromise);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Internal hook that uses useSyncExternalStore to subscribe to multiple SubscriptionScopes.
|
|
929
|
+
*
|
|
930
|
+
* - Creates a combined subscribe function that subscribes to all scopes
|
|
931
|
+
* - Returns an array of current values from each scope
|
|
932
|
+
* - Maintains stable references for unchanged values
|
|
933
|
+
*
|
|
934
|
+
* @param subscriptions - Array of SubscriptionScope instances (or null for skipped entries)
|
|
935
|
+
* @returns Array of loaded CoValues (or null for skipped entries)
|
|
936
|
+
*/
|
|
937
|
+
function useSubscriptionsSelector<
|
|
938
|
+
T extends CoValue[] | MaybeLoaded<CoValue>[],
|
|
939
|
+
// Selector input can be an already loaded or a maybe-loaded value,
|
|
940
|
+
// depending on whether a suspense hook is used or not, respectively.
|
|
941
|
+
TSelectorInput = T[number],
|
|
942
|
+
TSelectorReturn = TSelectorInput,
|
|
943
|
+
>(
|
|
944
|
+
subscriptions: SubscriptionScope<CoValue>[],
|
|
945
|
+
options?: {
|
|
946
|
+
select?: (value: TSelectorInput) => TSelectorReturn;
|
|
947
|
+
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
948
|
+
},
|
|
949
|
+
): TSelectorReturn[] {
|
|
950
|
+
// Combined subscribe function that subscribes to all scopes
|
|
951
|
+
const subscribe = useCallback(
|
|
952
|
+
(callback: () => void) => {
|
|
953
|
+
const unsubscribes = subscriptions.map((sub) => sub.subscribe(callback));
|
|
954
|
+
|
|
955
|
+
return () => {
|
|
956
|
+
unsubscribes.forEach((unsub) => unsub());
|
|
957
|
+
};
|
|
958
|
+
},
|
|
959
|
+
[subscriptions],
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
// Cache current values to avoid infinite loops
|
|
963
|
+
const cachedCurrentValuesRef = useRef<T>([] as unknown as T);
|
|
964
|
+
const getCurrentValues = useCallback(() => {
|
|
965
|
+
const newValues = subscriptions.map((sub) => sub.getCurrentValue());
|
|
966
|
+
|
|
967
|
+
// Check if values have changed by comparing each element
|
|
968
|
+
const cached = cachedCurrentValuesRef.current;
|
|
969
|
+
const hasChanged =
|
|
970
|
+
cached.length !== newValues.length ||
|
|
971
|
+
newValues.some((value, index) => value !== cached[index]);
|
|
972
|
+
|
|
973
|
+
if (hasChanged) {
|
|
974
|
+
cachedCurrentValuesRef.current = newValues as T;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
return cachedCurrentValuesRef.current as unknown as TSelectorInput[];
|
|
978
|
+
}, [subscriptions]);
|
|
979
|
+
|
|
980
|
+
const selectFn = useMemo(() => {
|
|
981
|
+
if (!options?.select) {
|
|
982
|
+
return (values: TSelectorInput[]) =>
|
|
983
|
+
values as unknown as TSelectorReturn[];
|
|
984
|
+
}
|
|
985
|
+
return (values: TSelectorInput[]) =>
|
|
986
|
+
values.map((value) => options.select!(value));
|
|
987
|
+
}, [options?.select]);
|
|
988
|
+
|
|
989
|
+
const elementEqualityFn = useMemo(
|
|
990
|
+
() => options?.equalityFn ?? Object.is,
|
|
991
|
+
[options?.equalityFn],
|
|
992
|
+
);
|
|
993
|
+
const equalityFn = useMemo(() => {
|
|
994
|
+
return (a: TSelectorReturn[], b: TSelectorReturn[]) =>
|
|
995
|
+
a.length === b.length &&
|
|
996
|
+
a.every((value, index) => elementEqualityFn(value, b[index]));
|
|
997
|
+
}, [elementEqualityFn]);
|
|
998
|
+
|
|
999
|
+
return useSyncExternalStoreWithSelector(
|
|
1000
|
+
subscribe,
|
|
1001
|
+
getCurrentValues,
|
|
1002
|
+
getCurrentValues,
|
|
1003
|
+
selectFn,
|
|
1004
|
+
equalityFn,
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Subscribe to multiple CoValues with unified Suspense handling.
|
|
1010
|
+
*
|
|
1011
|
+
* This hook accepts a list of CoValue IDs and returns an array of loaded values,
|
|
1012
|
+
* suspending until all values are available.
|
|
1013
|
+
*
|
|
1014
|
+
* @param Schema - The CoValue schema or class constructor
|
|
1015
|
+
* @param ids - Array of CoValue IDs to subscribe to
|
|
1016
|
+
* @param options - Optional configuration, including resolve query
|
|
1017
|
+
* @returns An array of loaded CoValues in the same order as the input IDs
|
|
1018
|
+
*/
|
|
1019
|
+
export function useSuspenseCoStates<
|
|
1020
|
+
S extends CoValueClassOrSchema,
|
|
1021
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
1022
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
1023
|
+
TSelectorReturn = Loaded<S, R>,
|
|
1024
|
+
>(
|
|
1025
|
+
Schema: S,
|
|
1026
|
+
ids: readonly string[],
|
|
1027
|
+
options?: {
|
|
1028
|
+
/** Resolve query to specify which nested CoValues to load */
|
|
1029
|
+
resolve?: ResolveQueryStrict<S, R>;
|
|
1030
|
+
/** Select which value to return. Applies to each element individually. */
|
|
1031
|
+
select?: (value: Loaded<S, R>) => TSelectorReturn;
|
|
1032
|
+
/** Equality function to determine if a selected value has changed, defaults to `Object.is` */
|
|
1033
|
+
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
1034
|
+
/**
|
|
1035
|
+
* Create or load a branch for isolated editing.
|
|
1036
|
+
*
|
|
1037
|
+
* Branching lets you take a snapshot of the current state and start modifying it without affecting the canonical/shared version.
|
|
1038
|
+
* It's a fork of your data graph: the same schema, but with diverging values.
|
|
1039
|
+
*
|
|
1040
|
+
* The checkout of the branch is applied on all the resolved values.
|
|
1041
|
+
*
|
|
1042
|
+
* @param name - A unique name for the branch. This identifies the branch
|
|
1043
|
+
* and can be used to switch between different branches of the same CoValue.
|
|
1044
|
+
* @param owner - The owner of the branch. Determines who can access and modify
|
|
1045
|
+
* the branch. If not provided, the branch is owned by the current user.
|
|
1046
|
+
*
|
|
1047
|
+
* For more info see the [branching](https://jazz.tools/docs/react/using-covalues/version-control) documentation.
|
|
1048
|
+
*/
|
|
1049
|
+
unstable_branch?: BranchDefinition;
|
|
1050
|
+
},
|
|
1051
|
+
): TSelectorReturn[] {
|
|
1052
|
+
const resolve = getResolveQuery(Schema, options?.resolve);
|
|
1053
|
+
const subscriptionScopes = useCoValueSubscriptions(
|
|
1054
|
+
Schema,
|
|
1055
|
+
ids,
|
|
1056
|
+
resolve,
|
|
1057
|
+
options?.unstable_branch,
|
|
1058
|
+
) as SubscriptionScope<CoValue>[];
|
|
1059
|
+
useSuspendUntilLoaded(subscriptionScopes);
|
|
1060
|
+
return useSubscriptionsSelector(subscriptionScopes, options);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Subscribe to multiple CoValues without Suspense.
|
|
1065
|
+
*
|
|
1066
|
+
* This hook accepts a list of CoValue IDs and returns an array of maybe-loaded values.
|
|
1067
|
+
* Unlike `useSuspenseCoStates`, this hook does not suspend and returns loading/unavailable
|
|
1068
|
+
* states that can be checked via the `$isLoaded` property.
|
|
1069
|
+
*
|
|
1070
|
+
* @param Schema - The CoValue schema or class constructor
|
|
1071
|
+
* @param ids - Array of CoValue IDs to subscribe to
|
|
1072
|
+
* @param options - Optional configuration, including resolve query
|
|
1073
|
+
* @returns An array of MaybeLoaded CoValues in the same order as the input IDs
|
|
1074
|
+
*
|
|
1075
|
+
* @example
|
|
1076
|
+
* ```typescript
|
|
1077
|
+
* const [project1, project2] = useCoStates(
|
|
1078
|
+
* ProjectSchema,
|
|
1079
|
+
* [projectId1, projectId2],
|
|
1080
|
+
* { resolve: { assignee: true } }
|
|
1081
|
+
* );
|
|
1082
|
+
*
|
|
1083
|
+
* if (!project1.$isLoaded || !project2.$isLoaded) {
|
|
1084
|
+
* return <Loading />;
|
|
1085
|
+
* }
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
export function useCoStates<
|
|
1089
|
+
S extends CoValueClassOrSchema,
|
|
1090
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
1091
|
+
const R extends ResolveQuery<S> = SchemaResolveQuery<S>,
|
|
1092
|
+
TSelectorReturn = MaybeLoaded<Loaded<S, R>>,
|
|
1093
|
+
>(
|
|
1094
|
+
Schema: S,
|
|
1095
|
+
ids: readonly string[],
|
|
1096
|
+
options?: {
|
|
1097
|
+
/** Resolve query to specify which nested CoValues to load */
|
|
1098
|
+
resolve?: ResolveQueryStrict<S, R>;
|
|
1099
|
+
/** Select which value to return. Applies to each element individually. */
|
|
1100
|
+
select?: (value: MaybeLoaded<Loaded<S, R>>) => TSelectorReturn;
|
|
1101
|
+
/** Equality function to determine if a selected value has changed, defaults to `Object.is` */
|
|
1102
|
+
equalityFn?: (a: TSelectorReturn, b: TSelectorReturn) => boolean;
|
|
1103
|
+
/**
|
|
1104
|
+
* Create or load a branch for isolated editing.
|
|
1105
|
+
*
|
|
1106
|
+
* Branching lets you take a snapshot of the current state and start modifying it without affecting the canonical/shared version.
|
|
1107
|
+
* It's a fork of your data graph: the same schema, but with diverging values.
|
|
1108
|
+
*
|
|
1109
|
+
* The checkout of the branch is applied on all the resolved values.
|
|
1110
|
+
*
|
|
1111
|
+
* @param name - A unique name for the branch. This identifies the branch
|
|
1112
|
+
* and can be used to switch between different branches of the same CoValue.
|
|
1113
|
+
* @param owner - The owner of the branch. Determines who can access and modify
|
|
1114
|
+
* the branch. If not provided, the branch is owned by the current user.
|
|
1115
|
+
*
|
|
1116
|
+
* For more info see the [branching](https://jazz.tools/docs/react/using-covalues/version-control) documentation.
|
|
1117
|
+
*/
|
|
1118
|
+
unstable_branch?: BranchDefinition;
|
|
1119
|
+
},
|
|
1120
|
+
): TSelectorReturn[] {
|
|
1121
|
+
const resolve = getResolveQuery(Schema, options?.resolve);
|
|
1122
|
+
const subscriptionScopes = useCoValueSubscriptions(
|
|
1123
|
+
Schema,
|
|
1124
|
+
ids,
|
|
1125
|
+
resolve,
|
|
1126
|
+
options?.unstable_branch,
|
|
1127
|
+
) as SubscriptionScope<CoValue>[];
|
|
1128
|
+
return useSubscriptionsSelector(subscriptionScopes, options);
|
|
1129
|
+
}
|