jazz-tools 0.19.22 → 0.20.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__/react.d.ts.map +1 -1
- package/.svelte-kit/__package__/react.tsx +5 -2
- package/.turbo/turbo-build.log +71 -83
- package/CHANGELOG.md +69 -0
- package/dist/better-auth/auth/react.d.ts.map +1 -1
- package/dist/better-auth/auth/react.js +5 -2
- package/dist/better-auth/auth/react.js.map +1 -1
- package/dist/browser/createBrowserContext.d.ts +1 -2
- package/dist/browser/createBrowserContext.d.ts.map +1 -1
- package/dist/browser/index.js +1 -8
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/provideBrowserLockSession/SessionIDStorage.d.ts +1 -1
- package/dist/{chunk-QCTQH5RS.js → chunk-3CAPPS2F.js} +234 -101
- package/dist/chunk-3CAPPS2F.js.map +1 -0
- package/dist/{chunk-M2HGBOXS.js → chunk-K4D7IMFM.js} +3 -3
- package/dist/chunk-K4D7IMFM.js.map +1 -0
- package/dist/expo/auth/clerk/index.d.ts.map +1 -1
- package/dist/expo/index.js +5 -2
- package/dist/expo/index.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/inspector/{chunk-YQNK5Y7B.js → chunk-MCTB5ZJC.js} +1 -1
- package/dist/inspector/chunk-MCTB5ZJC.js.map +1 -0
- package/dist/inspector/contexts/node.d.ts.map +1 -1
- package/dist/inspector/{custom-element-KYV64IOC.js → custom-element-5YWVZBWA.js} +1 -1
- package/dist/inspector/{custom-element-KYV64IOC.js.map → custom-element-5YWVZBWA.js.map} +1 -1
- package/dist/inspector/index.js +3 -3
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/standalone.js +1 -1
- package/dist/react/auth/Clerk.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.js +61 -47
- package/dist/react/index.js.map +1 -1
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/ssr.js +2 -2
- package/dist/react/ssr.js.map +1 -1
- package/dist/react-core/chunk-UOYH6JFJ.js +10 -0
- package/dist/react-core/chunk-UOYH6JFJ.js.map +1 -0
- package/dist/react-core/hooks.d.ts +3 -3
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +27 -25
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/provider.d.ts +2 -3
- package/dist/react-core/provider.d.ts.map +1 -1
- package/dist/react-core/testing.d.ts.map +1 -1
- package/dist/react-core/testing.js +4 -10
- package/dist/react-core/testing.js.map +1 -1
- package/dist/react-native/index.js +61 -53
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native-core/ReactNativeContextManager.d.ts +0 -1
- package/dist/react-native-core/ReactNativeContextManager.d.ts.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 +58 -50
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/platform.d.ts +0 -4
- package/dist/react-native-core/platform.d.ts.map +1 -1
- package/dist/react-native-core/provider.d.ts +2 -1
- package/dist/react-native-core/provider.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +2 -8
- package/dist/svelte/tests/AccountCoState.svelte.test.d.ts +2 -0
- package/dist/svelte/tests/AccountCoState.svelte.test.d.ts.map +1 -0
- package/dist/svelte/tests/AccountCoState.svelte.test.js +59 -0
- package/dist/svelte/tests/CoState.svelte.test.js +23 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts +11 -0
- package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts.map +1 -0
- package/dist/testing.js +6 -6
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/coList.d.ts +2 -2
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +2 -2
- package/dist/tools/coValues/deepLoading.d.ts +2 -2
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +32 -0
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
- package/dist/tools/implementation/createContext.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +3 -3
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +3 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +5 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/ssr.js +1 -1
- package/dist/tools/subscribe/JazzError.d.ts +3 -3
- package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/types.d.ts +5 -1
- package/dist/tools/subscribe/types.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +3 -3
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/deleteCoValues.test.d.ts +2 -0
- package/dist/tools/tests/deleteCoValues.test.d.ts.map +1 -0
- package/dist/tools/tests/deletedState.test.d.ts +2 -0
- package/dist/tools/tests/deletedState.test.d.ts.map +1 -0
- package/dist/worker/edge-wasm.js +2 -1
- package/dist/worker/edge-wasm.js.map +1 -1
- package/dist/worker/wasm.d.ts +2 -0
- package/dist/worker/wasm.d.ts.map +1 -0
- package/package.json +9 -28
- package/src/better-auth/auth/react.tsx +5 -2
- package/src/browser/createBrowserContext.ts +2 -5
- package/src/expo/auth/clerk/index.tsx +5 -2
- package/src/inspector/contexts/node.tsx +1 -2
- package/src/inspector/index.tsx +2 -2
- package/src/react/auth/Clerk.tsx +5 -2
- package/src/react/auth/PasskeyAuth.tsx +2 -2
- package/src/react/hooks.tsx +3 -2
- package/src/react/provider.tsx +45 -41
- package/src/react-core/auth/DemoAuth.tsx +2 -2
- package/src/react-core/auth/PassphraseAuth.tsx +2 -2
- package/src/react-core/hooks.ts +26 -27
- package/src/react-core/provider.tsx +1 -5
- package/src/react-core/testing.tsx +3 -11
- package/src/react-core/tests/useAccount.selector.test.ts +2 -3
- package/src/react-core/tests/useAccount.test.ts +57 -7
- package/src/react-core/tests/useCoState.test.ts +37 -0
- package/src/react-core/tests/useInboxSender.test.ts +2 -5
- package/src/react-core/tests/useSuspenseAccount.test.tsx +68 -0
- package/src/react-core/tests/useSuspenseCoState.test.tsx +44 -0
- package/src/react-native-core/ReactNativeContextManager.ts +0 -3
- package/src/react-native-core/auth/usePasskeyAuth.tsx +2 -2
- package/src/react-native-core/hooks.tsx +3 -3
- package/src/react-native-core/platform.ts +2 -6
- package/src/react-native-core/provider.tsx +47 -43
- package/src/svelte/jazz.class.svelte.ts +2 -8
- package/src/svelte/tests/AccountCoState.svelte.test.ts +79 -0
- package/src/svelte/tests/CoState.svelte.test.ts +36 -0
- package/src/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
- package/src/tools/coValues/deepLoading.ts +2 -0
- package/src/tools/coValues/interfaces.ts +170 -32
- package/src/tools/exports.ts +1 -0
- package/src/tools/implementation/ContextManager.ts +2 -2
- package/src/tools/implementation/createContext.ts +4 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +30 -6
- package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +55 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +33 -14
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +35 -6
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +35 -14
- package/src/tools/ssr/ssr.ts +2 -2
- package/src/tools/subscribe/CoValueCoreSubscription.ts +1 -0
- package/src/tools/subscribe/JazzError.ts +4 -1
- package/src/tools/subscribe/SubscriptionScope.ts +23 -0
- package/src/tools/subscribe/types.ts +5 -0
- package/src/tools/testing.ts +5 -5
- package/src/tools/tests/PassphraseAuth.test.ts +5 -5
- package/src/tools/tests/deleteCoValues.test.ts +231 -0
- package/src/tools/tests/deletedState.test.ts +110 -0
- package/src/tools/tests/request.test.ts +15 -2
- package/src/worker/edge-wasm.ts +2 -1
- package/src/worker/wasm.ts +1 -0
- package/tsup.config.ts +0 -4
- package/dist/browser/storageOptions.d.ts +0 -8
- package/dist/browser/storageOptions.d.ts.map +0 -1
- package/dist/browser/tests/storageOptions.test.d.ts +0 -2
- package/dist/browser/tests/storageOptions.test.d.ts.map +0 -1
- package/dist/chunk-M2HGBOXS.js.map +0 -1
- package/dist/chunk-QCTQH5RS.js.map +0 -1
- package/dist/expo/crypto.d.ts +0 -2
- package/dist/expo/crypto.d.ts.map +0 -1
- package/dist/expo/crypto.js +0 -6
- package/dist/expo/crypto.js.map +0 -1
- package/dist/inspector/chunk-YQNK5Y7B.js.map +0 -1
- package/dist/react-core/chunk-7DYMJ74I.js +0 -12
- package/dist/react-core/chunk-7DYMJ74I.js.map +0 -1
- package/dist/react-native/chunk-DGUM43GV.js +0 -11
- package/dist/react-native/chunk-DGUM43GV.js.map +0 -1
- package/dist/react-native/crypto.d.ts +0 -2
- package/dist/react-native/crypto.d.ts.map +0 -1
- package/dist/react-native/crypto.js +0 -8
- package/dist/react-native/crypto.js.map +0 -1
- package/dist/react-native-core/chunk-DGUM43GV.js +0 -11
- package/dist/react-native-core/chunk-DGUM43GV.js.map +0 -1
- package/dist/react-native-core/crypto/RNCrypto.d.ts +0 -2
- package/dist/react-native-core/crypto/RNCrypto.d.ts.map +0 -1
- package/dist/react-native-core/crypto/RNCrypto.js +0 -3
- package/dist/react-native-core/crypto/RNCrypto.js.map +0 -1
- package/dist/react-native-core/crypto/RNQuickCrypto.d.ts +0 -17
- package/dist/react-native-core/crypto/RNQuickCrypto.d.ts.map +0 -1
- package/dist/react-native-core/crypto/index.d.ts +0 -2
- package/dist/react-native-core/crypto/index.d.ts.map +0 -1
- package/dist/react-native-core/crypto.js +0 -89
- package/dist/react-native-core/crypto.js.map +0 -1
- package/src/browser/storageOptions.ts +0 -17
- package/src/browser/tests/storageOptions.test.ts +0 -33
- package/src/expo/crypto.ts +0 -1
- package/src/react-native/crypto.ts +0 -1
- package/src/react-native-core/crypto/RNCrypto.ts +0 -1
- package/src/react-native-core/crypto/RNQuickCrypto.ts +0 -122
- package/src/react-native-core/crypto/index.ts +0 -1
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from "../internal.js";
|
|
33
33
|
import type { BranchDefinition } from "../subscribe/types.js";
|
|
34
34
|
import { CoValueHeader } from "cojson";
|
|
35
|
+
import { JazzError } from "../subscribe/JazzError.js";
|
|
35
36
|
|
|
36
37
|
/** @category Abstract interfaces */
|
|
37
38
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -177,8 +178,7 @@ export function loadCoValue<
|
|
|
177
178
|
loadAs: options.loadAs,
|
|
178
179
|
syncResolution: true,
|
|
179
180
|
skipRetry: options.skipRetry,
|
|
180
|
-
|
|
181
|
-
onUnauthorized: resolve,
|
|
181
|
+
onError: resolve,
|
|
182
182
|
unstable_branch: options.unstable_branch,
|
|
183
183
|
},
|
|
184
184
|
(value, unsubscribe) => {
|
|
@@ -223,13 +223,22 @@ type SubscribeListener<V extends CoValue, R extends RefsToResolve<V>> = (
|
|
|
223
223
|
unsubscribe: () => void,
|
|
224
224
|
) => void;
|
|
225
225
|
|
|
226
|
+
export type SubscribeCallback<V> = (value: V, unsubscribe: () => void) => void;
|
|
227
|
+
|
|
226
228
|
export type SubscribeListenerOptions<
|
|
227
229
|
V extends CoValue,
|
|
228
230
|
R extends RefsToResolve<V>,
|
|
229
231
|
> = {
|
|
230
232
|
resolve?: RefsToResolveStrict<V, R>;
|
|
231
233
|
loadAs?: Account | AnonymousJazzAgent;
|
|
234
|
+
onError?: (value: NotLoaded<V>) => void;
|
|
235
|
+
/**
|
|
236
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
237
|
+
*/
|
|
232
238
|
onUnauthorized?: (value: NotLoaded<V>) => void;
|
|
239
|
+
/**
|
|
240
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
241
|
+
*/
|
|
233
242
|
onUnavailable?: (value: NotLoaded<V>) => void;
|
|
234
243
|
unstable_branch?: BranchDefinition;
|
|
235
244
|
};
|
|
@@ -257,6 +266,7 @@ export function parseSubscribeRestArgs<
|
|
|
257
266
|
options: {
|
|
258
267
|
resolve: args[0].resolve,
|
|
259
268
|
loadAs: args[0].loadAs,
|
|
269
|
+
onError: args[0].onError,
|
|
260
270
|
onUnauthorized: args[0].onUnauthorized,
|
|
261
271
|
onUnavailable: args[0].onUnavailable,
|
|
262
272
|
unstable_branch: args[0].unstable_branch,
|
|
@@ -304,7 +314,14 @@ export function subscribeToCoValue<
|
|
|
304
314
|
options: {
|
|
305
315
|
resolve?: RefsToResolveStrict<V, R>;
|
|
306
316
|
loadAs: Account | AnonymousJazzAgent;
|
|
317
|
+
onError?: (value: Inaccessible<V>) => void;
|
|
318
|
+
/**
|
|
319
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
320
|
+
*/
|
|
307
321
|
onUnavailable?: (value: Inaccessible<V>) => void;
|
|
322
|
+
/**
|
|
323
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
324
|
+
*/
|
|
308
325
|
onUnauthorized?: (value: Inaccessible<V>) => void;
|
|
309
326
|
syncResolution?: boolean;
|
|
310
327
|
skipRetry?: boolean;
|
|
@@ -342,6 +359,9 @@ export function subscribeToCoValue<
|
|
|
342
359
|
return;
|
|
343
360
|
}
|
|
344
361
|
|
|
362
|
+
options.onError?.(value as Inaccessible<V>);
|
|
363
|
+
|
|
364
|
+
// Backward compatibility, going to remove this in the next minor release
|
|
345
365
|
switch (value.$jazz.loadingState) {
|
|
346
366
|
case CoValueLoadingState.UNAVAILABLE:
|
|
347
367
|
options.onUnavailable?.(value as Inaccessible<V>);
|
|
@@ -381,7 +401,14 @@ export function subscribeToExistingCoValue<
|
|
|
381
401
|
options:
|
|
382
402
|
| {
|
|
383
403
|
resolve?: RefsToResolveStrict<V, R>;
|
|
404
|
+
onError?: (value: NotLoaded<V>) => void;
|
|
405
|
+
/**
|
|
406
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
407
|
+
*/
|
|
384
408
|
onUnavailable?: (value: NotLoaded<V>) => void;
|
|
409
|
+
/**
|
|
410
|
+
* @deprecated Use `onError` instead. This callback will be removed in a future version.
|
|
411
|
+
*/
|
|
385
412
|
onUnauthorized?: (value: NotLoaded<V>) => void;
|
|
386
413
|
unstable_branch?: BranchDefinition;
|
|
387
414
|
}
|
|
@@ -394,6 +421,7 @@ export function subscribeToExistingCoValue<
|
|
|
394
421
|
{
|
|
395
422
|
loadAs: existing.$jazz.loadedAs,
|
|
396
423
|
resolve: options?.resolve,
|
|
424
|
+
onError: options?.onError,
|
|
397
425
|
onUnavailable: options?.onUnavailable,
|
|
398
426
|
onUnauthorized: options?.onUnauthorized,
|
|
399
427
|
unstable_branch: options?.unstable_branch,
|
|
@@ -688,23 +716,11 @@ export async function exportCoValue<
|
|
|
688
716
|
options.unstable_branch,
|
|
689
717
|
);
|
|
690
718
|
|
|
691
|
-
|
|
692
|
-
rootNode.
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
resolve(value as Loaded<S, R>);
|
|
697
|
-
} else if (
|
|
698
|
-
value.$jazz.loadingState === CoValueLoadingState.UNAVAILABLE ||
|
|
699
|
-
value.$jazz.loadingState === CoValueLoadingState.UNAUTHORIZED
|
|
700
|
-
) {
|
|
701
|
-
resolve(null);
|
|
702
|
-
rootNode.destroy();
|
|
703
|
-
}
|
|
704
|
-
});
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
if (!value) {
|
|
719
|
+
try {
|
|
720
|
+
await rootNode.getPromise();
|
|
721
|
+
rootNode.destroy();
|
|
722
|
+
} catch (error) {
|
|
723
|
+
rootNode.destroy();
|
|
708
724
|
return null;
|
|
709
725
|
}
|
|
710
726
|
|
|
@@ -857,19 +873,141 @@ export async function unstable_mergeBranchWithResolve<
|
|
|
857
873
|
options.branch,
|
|
858
874
|
);
|
|
859
875
|
|
|
860
|
-
|
|
861
|
-
rootNode.
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
resolve();
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
rootNode.destroy();
|
|
871
|
-
});
|
|
872
|
-
});
|
|
876
|
+
try {
|
|
877
|
+
await rootNode.getPromise();
|
|
878
|
+
rootNode.destroy();
|
|
879
|
+
} catch (error) {
|
|
880
|
+
rootNode.destroy();
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
873
883
|
|
|
874
884
|
unstable_mergeBranch(rootNode);
|
|
875
885
|
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Permanently delete a group of coValues
|
|
889
|
+
*
|
|
890
|
+
* This operation is irreversible and will permanently delete the coValues from the local machine and the sync servers.
|
|
891
|
+
*
|
|
892
|
+
*/
|
|
893
|
+
export async function deleteCoValues<
|
|
894
|
+
S extends CoValueClassOrSchema,
|
|
895
|
+
const R extends ResolveQuery<S>,
|
|
896
|
+
>(
|
|
897
|
+
cls: S,
|
|
898
|
+
id: ID<CoValue>,
|
|
899
|
+
options: {
|
|
900
|
+
resolve?: ResolveQueryStrict<S, R>;
|
|
901
|
+
loadAs?: Account | AnonymousJazzAgent;
|
|
902
|
+
} = {},
|
|
903
|
+
) {
|
|
904
|
+
const loadAs = options.loadAs ?? activeAccountContext.get();
|
|
905
|
+
const node = "node" in loadAs ? loadAs.node : loadAs.$jazz.localNode;
|
|
906
|
+
|
|
907
|
+
const resolve = options.resolve ?? true;
|
|
908
|
+
|
|
909
|
+
const rootNode = new SubscriptionScope<CoValue>(
|
|
910
|
+
node,
|
|
911
|
+
resolve as any,
|
|
912
|
+
id,
|
|
913
|
+
{
|
|
914
|
+
ref: coValueClassFromCoValueClassOrSchema(cls),
|
|
915
|
+
optional: false,
|
|
916
|
+
},
|
|
917
|
+
false,
|
|
918
|
+
false,
|
|
919
|
+
undefined,
|
|
920
|
+
);
|
|
921
|
+
|
|
922
|
+
try {
|
|
923
|
+
await rootNode.getPromise();
|
|
924
|
+
rootNode.destroy();
|
|
925
|
+
} catch (error) {
|
|
926
|
+
rootNode.destroy();
|
|
927
|
+
throw error;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// We validate permissions to fail early if one of the loaded coValues is not deletable
|
|
931
|
+
const errors = validateDeletePermissions(rootNode);
|
|
932
|
+
|
|
933
|
+
if (errors.length > 0) {
|
|
934
|
+
const combined = new JazzError(
|
|
935
|
+
id,
|
|
936
|
+
CoValueLoadingState.DELETED,
|
|
937
|
+
errors.flatMap((e) => e.issues),
|
|
938
|
+
);
|
|
939
|
+
throw new Error(combined.toString());
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
const deletedValues = deleteCoValueFromSubscription(rootNode);
|
|
943
|
+
|
|
944
|
+
await Promise.allSettled(
|
|
945
|
+
Array.from(deletedValues, (value) => value.waitForSync()),
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
function validateDeletePermissions(
|
|
950
|
+
rootNode: SubscriptionScope<CoValue>,
|
|
951
|
+
path: string[] = [],
|
|
952
|
+
errors: JazzError[] = [],
|
|
953
|
+
): JazzError[] {
|
|
954
|
+
for (const [key, childNode] of rootNode.childNodes.entries()) {
|
|
955
|
+
validateDeletePermissions(childNode, [...path, key], errors);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
if (rootNode.value.type !== CoValueLoadingState.LOADED) {
|
|
959
|
+
return errors;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
const core = rootNode.value.value.$jazz.raw.core;
|
|
963
|
+
|
|
964
|
+
// Account and Group coValues are not deletable, we skip them to make it easier to delete all coValues owned by an account
|
|
965
|
+
if (core.isGroupOrAccount()) {
|
|
966
|
+
return errors;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const result = core.validateDeletePermissions();
|
|
970
|
+
if (!result.ok) {
|
|
971
|
+
errors.push(
|
|
972
|
+
new JazzError(core.id, CoValueLoadingState.DELETED, [
|
|
973
|
+
{
|
|
974
|
+
code: "deleteError",
|
|
975
|
+
message: `Jazz Delete Error: ${result.message}`,
|
|
976
|
+
params: {},
|
|
977
|
+
path,
|
|
978
|
+
},
|
|
979
|
+
]),
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return errors;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
function deleteCoValueFromSubscription(
|
|
987
|
+
rootNode: SubscriptionScope<CoValue>,
|
|
988
|
+
values = new Set<AvailableCoValueCore>(),
|
|
989
|
+
) {
|
|
990
|
+
for (const childNode of rootNode.childNodes.values()) {
|
|
991
|
+
deleteCoValueFromSubscription(childNode, values);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
if (rootNode.value.type !== CoValueLoadingState.LOADED) {
|
|
995
|
+
return values;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
const core = rootNode.value.value.$jazz.raw.core;
|
|
999
|
+
|
|
1000
|
+
// Account and Group coValues are not deletable, we skip them to make it easier to delete all coValues owned by an account
|
|
1001
|
+
if (core.isGroupOrAccount()) {
|
|
1002
|
+
return values;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
try {
|
|
1006
|
+
core.deleteCoValue();
|
|
1007
|
+
values.add(core);
|
|
1008
|
+
} catch (error) {
|
|
1009
|
+
console.error("Failed to delete coValue", error);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
return values;
|
|
1013
|
+
}
|
package/src/tools/exports.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AgentSecret, LocalNode, cojsonInternals } from "cojson";
|
|
2
|
-
import { PureJSCrypto } from "cojson/dist/crypto/PureJSCrypto";
|
|
3
2
|
import { AuthSecretStorage } from "../auth/AuthSecretStorage.js";
|
|
4
3
|
import { InMemoryKVStore } from "../auth/InMemoryKVStore.js";
|
|
5
4
|
import { KvStore, KvStoreContext } from "../auth/KvStoreContext.js";
|
|
@@ -10,6 +9,7 @@ import { AnonymousJazzAgent } from "./anonymousJazzAgent.js";
|
|
|
10
9
|
import { createAnonymousJazzContext } from "./createContext.js";
|
|
11
10
|
import { InstanceOfSchema } from "./zodSchema/typeConverters/InstanceOfSchema.js";
|
|
12
11
|
import { SubscriptionCache } from "../subscribe/SubscriptionCache.js";
|
|
12
|
+
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
|
13
13
|
|
|
14
14
|
export type JazzContextManagerAuthProps = {
|
|
15
15
|
credentials?: AuthCredentials;
|
|
@@ -47,7 +47,7 @@ type PlatformSpecificContext<Acc extends Account> =
|
|
|
47
47
|
function getAnonymousFallback() {
|
|
48
48
|
const context = createAnonymousJazzContext({
|
|
49
49
|
peers: [],
|
|
50
|
-
crypto:
|
|
50
|
+
crypto: WasmCrypto.createSync(),
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
return {
|
|
@@ -272,6 +272,10 @@ export async function createJazzContext<
|
|
|
272
272
|
|
|
273
273
|
const credentials = options.credentials ?? (await authSecretStorage.get());
|
|
274
274
|
|
|
275
|
+
if (options.storage) {
|
|
276
|
+
options.storage.enableDeletedCoValuesErasure();
|
|
277
|
+
}
|
|
278
|
+
|
|
275
279
|
if (credentials && !options.newAccountProps) {
|
|
276
280
|
context = await createJazzContextFromExistingCredentials({
|
|
277
281
|
credentials: {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
RefsToResolve,
|
|
11
11
|
Resolved,
|
|
12
12
|
Simplify,
|
|
13
|
+
SubscribeCallback,
|
|
13
14
|
SubscribeListenerOptions,
|
|
14
15
|
unstable_mergeBranchWithResolve,
|
|
15
16
|
} from "../../../internal.js";
|
|
@@ -161,6 +162,15 @@ export class AccountSchema<
|
|
|
161
162
|
);
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
subscribe<
|
|
166
|
+
const R extends RefsToResolve<
|
|
167
|
+
Simplify<AccountInstance<Shape>>
|
|
168
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
169
|
+
> = DefaultResolveQuery,
|
|
170
|
+
>(
|
|
171
|
+
id: string,
|
|
172
|
+
listener: SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
|
|
173
|
+
): () => void;
|
|
164
174
|
subscribe<
|
|
165
175
|
const R extends RefsToResolve<
|
|
166
176
|
Simplify<AccountInstance<Shape>>
|
|
@@ -169,16 +179,30 @@ export class AccountSchema<
|
|
|
169
179
|
>(
|
|
170
180
|
id: string,
|
|
171
181
|
options: SubscribeListenerOptions<Simplify<AccountInstance<Shape>>, R>,
|
|
172
|
-
listener:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
182
|
+
listener: SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
|
|
183
|
+
): () => void;
|
|
184
|
+
subscribe<const R extends RefsToResolve<Simplify<AccountInstance<Shape>>>>(
|
|
185
|
+
id: string,
|
|
186
|
+
optionsOrListener:
|
|
187
|
+
| SubscribeListenerOptions<Simplify<AccountInstance<Shape>>, R>
|
|
188
|
+
| SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
|
|
189
|
+
maybeListener?: SubscribeCallback<
|
|
190
|
+
Resolved<Simplify<AccountInstance<Shape>>, R>
|
|
191
|
+
>,
|
|
176
192
|
): () => void {
|
|
193
|
+
if (typeof optionsOrListener === "function") {
|
|
194
|
+
return this.coValueClass.subscribe(
|
|
195
|
+
id,
|
|
196
|
+
withSchemaResolveQuery({}, this.resolveQuery),
|
|
197
|
+
// @ts-expect-error
|
|
198
|
+
optionsOrListener,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
177
201
|
return this.coValueClass.subscribe(
|
|
178
202
|
id,
|
|
179
203
|
// @ts-expect-error
|
|
180
|
-
withSchemaResolveQuery(
|
|
181
|
-
|
|
204
|
+
withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
|
|
205
|
+
maybeListener,
|
|
182
206
|
);
|
|
183
207
|
}
|
|
184
208
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
Resolved,
|
|
12
12
|
SchemaUnion,
|
|
13
13
|
SchemaUnionConcreteSubclass,
|
|
14
|
+
SubscribeCallback,
|
|
14
15
|
SubscribeListenerOptions,
|
|
15
16
|
coOptionalDefiner,
|
|
16
17
|
} from "../../../internal.js";
|
|
@@ -101,6 +102,20 @@ export class CoDiscriminatedUnionSchema<
|
|
|
101
102
|
) as any;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
subscribe<
|
|
106
|
+
const R extends RefsToResolve<
|
|
107
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
|
|
108
|
+
// @ts-expect-error
|
|
109
|
+
> = DefaultResolveQuery,
|
|
110
|
+
>(
|
|
111
|
+
id: string,
|
|
112
|
+
listener: SubscribeCallback<
|
|
113
|
+
Resolved<
|
|
114
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
|
|
115
|
+
R
|
|
116
|
+
>
|
|
117
|
+
>,
|
|
118
|
+
): () => void;
|
|
104
119
|
subscribe<
|
|
105
120
|
const R extends RefsToResolve<
|
|
106
121
|
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
|
|
@@ -112,19 +127,52 @@ export class CoDiscriminatedUnionSchema<
|
|
|
112
127
|
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
|
|
113
128
|
R
|
|
114
129
|
>,
|
|
115
|
-
listener:
|
|
116
|
-
|
|
130
|
+
listener: SubscribeCallback<
|
|
131
|
+
Resolved<
|
|
117
132
|
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
|
|
118
133
|
R
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
134
|
+
>
|
|
135
|
+
>,
|
|
136
|
+
): () => void;
|
|
137
|
+
subscribe<
|
|
138
|
+
const R extends RefsToResolve<
|
|
139
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
|
|
140
|
+
>,
|
|
141
|
+
>(
|
|
142
|
+
id: string,
|
|
143
|
+
optionsOrListener:
|
|
144
|
+
| SubscribeListenerOptions<
|
|
145
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> &
|
|
146
|
+
SchemaUnion,
|
|
147
|
+
R
|
|
148
|
+
>
|
|
149
|
+
| SubscribeCallback<
|
|
150
|
+
Resolved<
|
|
151
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> &
|
|
152
|
+
SchemaUnion,
|
|
153
|
+
R
|
|
154
|
+
>
|
|
155
|
+
>,
|
|
156
|
+
maybeListener?: SubscribeCallback<
|
|
157
|
+
Resolved<
|
|
158
|
+
CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
|
|
159
|
+
R
|
|
160
|
+
>
|
|
161
|
+
>,
|
|
122
162
|
): () => void {
|
|
163
|
+
if (typeof optionsOrListener === "function") {
|
|
164
|
+
// @ts-expect-error
|
|
165
|
+
return this.coValueClass.subscribe(
|
|
166
|
+
id,
|
|
167
|
+
withSchemaResolveQuery({}, this.resolveQuery),
|
|
168
|
+
optionsOrListener,
|
|
169
|
+
);
|
|
170
|
+
}
|
|
123
171
|
// @ts-expect-error
|
|
124
172
|
return this.coValueClass.subscribe(
|
|
125
173
|
id,
|
|
126
|
-
withSchemaResolveQuery(
|
|
127
|
-
|
|
174
|
+
withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
|
|
175
|
+
maybeListener,
|
|
128
176
|
);
|
|
129
177
|
}
|
|
130
178
|
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
RefsToResolve,
|
|
10
10
|
RefsToResolveStrict,
|
|
11
11
|
Resolved,
|
|
12
|
+
SubscribeCallback,
|
|
12
13
|
SubscribeListenerOptions,
|
|
13
14
|
coOptionalDefiner,
|
|
14
|
-
parseSubscribeRestArgs,
|
|
15
15
|
unstable_mergeBranchWithResolve,
|
|
16
16
|
withSchemaPermissions,
|
|
17
17
|
} from "../../../internal.js";
|
|
@@ -118,12 +118,16 @@ export class CoFeedSchema<
|
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
subscribe
|
|
121
|
+
subscribe<
|
|
122
|
+
const R extends RefsToResolve<
|
|
123
|
+
CoFeedInstanceCoValuesMaybeLoaded<T>
|
|
124
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
125
|
+
> = DefaultResolveQuery,
|
|
126
|
+
>(
|
|
122
127
|
id: string,
|
|
123
|
-
listener:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
) => void,
|
|
128
|
+
listener: SubscribeCallback<
|
|
129
|
+
Resolved<CoFeedInstanceCoValuesMaybeLoaded<T>, R>
|
|
130
|
+
>,
|
|
127
131
|
): () => void;
|
|
128
132
|
subscribe<
|
|
129
133
|
const R extends RefsToResolve<
|
|
@@ -133,18 +137,33 @@ export class CoFeedSchema<
|
|
|
133
137
|
>(
|
|
134
138
|
id: string,
|
|
135
139
|
options: SubscribeListenerOptions<CoFeedInstanceCoValuesMaybeLoaded<T>, R>,
|
|
136
|
-
listener:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
) => void,
|
|
140
|
+
listener: SubscribeCallback<
|
|
141
|
+
Resolved<CoFeedInstanceCoValuesMaybeLoaded<T>, R>
|
|
142
|
+
>,
|
|
140
143
|
): () => void;
|
|
141
|
-
subscribe
|
|
142
|
-
const
|
|
144
|
+
subscribe<
|
|
145
|
+
const R extends RefsToResolve<CoFeedInstanceCoValuesMaybeLoaded<T>>,
|
|
146
|
+
>(
|
|
147
|
+
id: string,
|
|
148
|
+
optionsOrListener:
|
|
149
|
+
| SubscribeListenerOptions<CoFeedInstanceCoValuesMaybeLoaded<T>, R>
|
|
150
|
+
| SubscribeCallback<Resolved<CoFeedInstanceCoValuesMaybeLoaded<T>, R>>,
|
|
151
|
+
maybeListener?: SubscribeCallback<
|
|
152
|
+
Resolved<CoFeedInstanceCoValuesMaybeLoaded<T>, R>
|
|
153
|
+
>,
|
|
154
|
+
): () => void {
|
|
155
|
+
if (typeof optionsOrListener === "function") {
|
|
156
|
+
return this.coValueClass.subscribe(
|
|
157
|
+
id,
|
|
158
|
+
withSchemaResolveQuery({}, this.resolveQuery),
|
|
159
|
+
optionsOrListener,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
143
162
|
return this.coValueClass.subscribe(
|
|
144
163
|
id,
|
|
164
|
+
withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
|
|
145
165
|
// @ts-expect-error
|
|
146
|
-
|
|
147
|
-
listener,
|
|
166
|
+
maybeListener,
|
|
148
167
|
);
|
|
149
168
|
}
|
|
150
169
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
RefsToResolve,
|
|
10
10
|
RefsToResolveStrict,
|
|
11
11
|
Resolved,
|
|
12
|
+
SubscribeCallback,
|
|
12
13
|
SubscribeListenerOptions,
|
|
13
14
|
coOptionalDefiner,
|
|
14
15
|
unstable_mergeBranchWithResolve,
|
|
@@ -125,6 +126,16 @@ export class CoListSchema<
|
|
|
125
126
|
);
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
subscribe<
|
|
130
|
+
const R extends RefsToResolve<
|
|
131
|
+
CoListInstanceCoValuesMaybeLoaded<T>
|
|
132
|
+
> = DefaultResolveQuery,
|
|
133
|
+
>(
|
|
134
|
+
id: string,
|
|
135
|
+
listener: SubscribeCallback<
|
|
136
|
+
Resolved<CoListInstanceCoValuesMaybeLoaded<T>, R>
|
|
137
|
+
>,
|
|
138
|
+
): () => void;
|
|
128
139
|
subscribe<
|
|
129
140
|
const R extends RefsToResolve<
|
|
130
141
|
CoListInstanceCoValuesMaybeLoaded<T>
|
|
@@ -132,15 +143,33 @@ export class CoListSchema<
|
|
|
132
143
|
>(
|
|
133
144
|
id: string,
|
|
134
145
|
options: SubscribeListenerOptions<CoListInstanceCoValuesMaybeLoaded<T>, R>,
|
|
135
|
-
listener:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
listener: SubscribeCallback<
|
|
147
|
+
Resolved<CoListInstanceCoValuesMaybeLoaded<T>, R>
|
|
148
|
+
>,
|
|
149
|
+
): () => void;
|
|
150
|
+
subscribe<
|
|
151
|
+
const R extends RefsToResolve<CoListInstanceCoValuesMaybeLoaded<T>>,
|
|
152
|
+
>(
|
|
153
|
+
id: string,
|
|
154
|
+
optionsOrListener:
|
|
155
|
+
| SubscribeListenerOptions<CoListInstanceCoValuesMaybeLoaded<T>, R>
|
|
156
|
+
| SubscribeCallback<Resolved<CoListInstanceCoValuesMaybeLoaded<T>, R>>,
|
|
157
|
+
maybeListener?: SubscribeCallback<
|
|
158
|
+
Resolved<CoListInstanceCoValuesMaybeLoaded<T>, R>
|
|
159
|
+
>,
|
|
139
160
|
): () => void {
|
|
161
|
+
if (typeof optionsOrListener === "function") {
|
|
162
|
+
return this.coValueClass.subscribe(
|
|
163
|
+
id,
|
|
164
|
+
withSchemaResolveQuery({}, this.resolveQuery),
|
|
165
|
+
optionsOrListener,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
140
168
|
return this.coValueClass.subscribe(
|
|
141
169
|
id,
|
|
142
|
-
withSchemaResolveQuery(
|
|
143
|
-
|
|
170
|
+
withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
|
|
171
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
172
|
+
maybeListener,
|
|
144
173
|
);
|
|
145
174
|
}
|
|
146
175
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
RefsToResolveStrict,
|
|
12
12
|
Resolved,
|
|
13
13
|
Simplify,
|
|
14
|
+
SubscribeCallback,
|
|
14
15
|
SubscribeListenerOptions,
|
|
15
16
|
coMapDefiner,
|
|
16
17
|
coOptionalDefiner,
|
|
@@ -33,6 +34,11 @@ import {
|
|
|
33
34
|
SchemaPermissions,
|
|
34
35
|
} from "../schemaPermissions.js";
|
|
35
36
|
|
|
37
|
+
type CoMapSchemaInstance<Shape extends z.core.$ZodLooseShape> = Simplify<
|
|
38
|
+
CoMapInstanceCoValuesMaybeLoaded<Shape>
|
|
39
|
+
> &
|
|
40
|
+
CoMap;
|
|
41
|
+
|
|
36
42
|
export class CoMapSchema<
|
|
37
43
|
Shape extends z.core.$ZodLooseShape,
|
|
38
44
|
CatchAll extends AnyZodOrCoValueSchema | unknown = unknown,
|
|
@@ -150,28 +156,43 @@ export class CoMapSchema<
|
|
|
150
156
|
|
|
151
157
|
subscribe<
|
|
152
158
|
const R extends RefsToResolve<
|
|
153
|
-
|
|
159
|
+
CoMapSchemaInstance<Shape>
|
|
154
160
|
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
155
161
|
> = DefaultResolveQuery,
|
|
156
162
|
>(
|
|
157
163
|
id: string,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
listener: SubscribeCallback<Resolved<CoMapSchemaInstance<Shape>, R>>,
|
|
165
|
+
): () => void;
|
|
166
|
+
subscribe<
|
|
167
|
+
const R extends RefsToResolve<
|
|
168
|
+
CoMapSchemaInstance<Shape>
|
|
169
|
+
// @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
|
|
170
|
+
> = DefaultResolveQuery,
|
|
171
|
+
>(
|
|
172
|
+
id: string,
|
|
173
|
+
options: SubscribeListenerOptions<CoMapSchemaInstance<Shape>, R>,
|
|
174
|
+
listener: SubscribeCallback<Resolved<CoMapSchemaInstance<Shape>, R>>,
|
|
175
|
+
): () => void;
|
|
176
|
+
subscribe<const R extends RefsToResolve<CoMapSchemaInstance<Shape>>>(
|
|
177
|
+
id: string,
|
|
178
|
+
optionsOrListener:
|
|
179
|
+
| SubscribeListenerOptions<CoMapSchemaInstance<Shape>, R>
|
|
180
|
+
| SubscribeCallback<Resolved<CoMapSchemaInstance<Shape>, R>>,
|
|
181
|
+
maybeListener?: SubscribeCallback<Resolved<CoMapSchemaInstance<Shape>, R>>,
|
|
169
182
|
): () => void {
|
|
183
|
+
if (typeof optionsOrListener === "function") {
|
|
184
|
+
// @ts-expect-error
|
|
185
|
+
return this.coValueClass.subscribe(
|
|
186
|
+
id,
|
|
187
|
+
withSchemaResolveQuery({}, this.resolveQuery),
|
|
188
|
+
optionsOrListener,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
170
191
|
// @ts-expect-error
|
|
171
192
|
return this.coValueClass.subscribe(
|
|
172
193
|
id,
|
|
173
|
-
withSchemaResolveQuery(
|
|
174
|
-
|
|
194
|
+
withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
|
|
195
|
+
maybeListener,
|
|
175
196
|
);
|
|
176
197
|
}
|
|
177
198
|
|