jazz-tools 0.19.7 → 0.19.10
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/.turbo/turbo-build.log +65 -59
- package/CHANGELOG.md +34 -3
- package/dist/{chunk-CUS6O5NE.js → chunk-FFEEPZEG.js} +454 -122
- package/dist/chunk-FFEEPZEG.js.map +1 -0
- package/dist/expo/polyfills.js +22 -0
- package/dist/expo/polyfills.js.map +1 -0
- package/dist/index.js +26 -6
- package/dist/index.js.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 +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-core/hooks.d.ts +59 -0
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +133 -34
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-core/tests/testUtils.d.ts +1 -0
- package/dist/react-core/tests/testUtils.d.ts.map +1 -1
- package/dist/react-core/tests/useSuspenseAccount.test.d.ts +2 -0
- package/dist/react-core/tests/useSuspenseAccount.test.d.ts.map +1 -0
- package/dist/react-core/tests/useSuspenseCoState.test.d.ts +2 -0
- package/dist/react-core/tests/useSuspenseCoState.test.d.ts.map +1 -0
- package/dist/react-core/use.d.ts +3 -0
- package/dist/react-core/use.d.ts.map +1 -0
- package/dist/react-native/index.d.ts +1 -1
- package/dist/react-native/index.d.ts.map +1 -1
- package/dist/react-native/index.js +717 -9
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native/polyfills.js +22 -0
- package/dist/react-native/polyfills.js.map +1 -0
- package/dist/react-native-core/crypto/RNCrypto.d.ts +2 -0
- package/dist/react-native-core/crypto/RNCrypto.d.ts.map +1 -0
- package/dist/react-native-core/crypto/RNCrypto.js +3 -0
- package/dist/react-native-core/crypto/RNCrypto.js.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.d.ts.map +1 -1
- package/dist/react-native-core/index.js +5 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/platform.d.ts +2 -1
- package/dist/react-native-core/platform.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/account.d.ts +3 -3
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/coFeed.d.ts +3 -3
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/coList.d.ts +4 -4
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +7 -7
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/coPlainText.d.ts +2 -2
- package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
- package/dist/tools/coValues/coVector.d.ts +2 -2
- package/dist/tools/coValues/coVector.d.ts.map +1 -1
- package/dist/tools/coValues/deepLoading.d.ts +24 -0
- package/dist/tools/coValues/deepLoading.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/interfaces.d.ts +7 -7
- package/dist/tools/coValues/interfaces.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/config.d.ts +3 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/exports.d.ts +2 -0
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/ContextManager.d.ts +3 -0
- package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts +8 -22
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionCache.d.ts +51 -0
- package/dist/tools/subscribe/SubscriptionCache.d.ts.map +1 -0
- package/dist/tools/subscribe/SubscriptionScope.d.ts +27 -2
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/errorReporting.d.ts +31 -0
- package/dist/tools/subscribe/errorReporting.d.ts.map +1 -0
- package/dist/tools/subscribe/utils.d.ts +9 -1
- package/dist/tools/subscribe/utils.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +2 -2
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/SubscriptionCache.test.d.ts +2 -0
- package/dist/tools/tests/SubscriptionCache.test.d.ts.map +1 -0
- package/dist/tools/tests/errorReporting.test.d.ts +2 -0
- package/dist/tools/tests/errorReporting.test.d.ts.map +1 -0
- package/package.json +22 -7
- package/src/react/hooks.tsx +2 -0
- package/src/react/index.ts +1 -14
- package/src/react-core/hooks.ts +181 -16
- package/src/react-core/tests/createCoValueSubscriptionContext.test.tsx +18 -8
- package/src/react-core/tests/testUtils.tsx +67 -5
- package/src/react-core/tests/useCoState.test.ts +3 -7
- package/src/react-core/tests/useSubscriptionSelector.test.ts +3 -7
- package/src/react-core/tests/useSuspenseAccount.test.tsx +343 -0
- package/src/react-core/tests/useSuspenseCoState.test.tsx +1182 -0
- package/src/react-core/use.ts +46 -0
- package/src/react-native/index.ts +1 -1
- package/src/react-native-core/crypto/RNCrypto.ts +1 -0
- package/src/react-native-core/hooks.tsx +2 -0
- package/src/react-native-core/index.ts +2 -0
- package/src/react-native-core/platform.ts +2 -1
- package/src/react-native-core/polyfills/index.js +28 -0
- package/src/tools/coValues/account.ts +3 -4
- package/src/tools/coValues/coFeed.ts +3 -2
- package/src/tools/coValues/coList.ts +4 -4
- package/src/tools/coValues/coMap.ts +4 -4
- package/src/tools/coValues/coPlainText.ts +2 -2
- package/src/tools/coValues/coVector.ts +2 -2
- package/src/tools/coValues/deepLoading.ts +31 -0
- package/src/tools/coValues/group.ts +2 -2
- package/src/tools/coValues/interfaces.ts +21 -26
- package/src/tools/coValues/schemaUnion.ts +2 -2
- package/src/tools/config.ts +9 -0
- package/src/tools/exports.ts +4 -0
- package/src/tools/implementation/ContextManager.ts +13 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +4 -4
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +4 -4
- package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +4 -10
- package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/GroupSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +2 -2
- package/src/tools/subscribe/CoValueCoreSubscription.ts +71 -100
- package/src/tools/subscribe/JazzError.ts +9 -6
- package/src/tools/subscribe/SubscriptionCache.ts +272 -0
- package/src/tools/subscribe/SubscriptionScope.ts +218 -29
- package/src/tools/subscribe/errorReporting.ts +67 -0
- package/src/tools/subscribe/utils.ts +77 -0
- package/src/tools/testing.ts +0 -3
- package/src/tools/tests/CoValueCoreSubscription.test.ts +46 -12
- package/src/tools/tests/ContextManager.test.ts +85 -0
- package/src/tools/tests/SubscriptionCache.test.ts +237 -0
- package/src/tools/tests/coMap.test.ts +5 -7
- package/src/tools/tests/deepLoading.test.ts +47 -47
- package/src/tools/tests/errorReporting.test.ts +103 -0
- package/src/tools/tests/load.test.ts +21 -1
- package/src/tools/tests/request.test.ts +2 -1
- package/src/tools/tests/subscribe.test.ts +44 -0
- package/tsup.config.ts +17 -0
- package/dist/chunk-CUS6O5NE.js.map +0 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { cojsonInternals } from "cojson";
|
|
2
2
|
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
assert,
|
|
5
|
+
beforeEach,
|
|
6
|
+
describe,
|
|
7
|
+
expect,
|
|
8
|
+
expectTypeOf,
|
|
9
|
+
test,
|
|
10
|
+
vi,
|
|
11
|
+
} from "vitest";
|
|
4
12
|
import {
|
|
5
13
|
Group,
|
|
6
14
|
ID,
|
|
@@ -11,17 +19,17 @@ import {
|
|
|
11
19
|
} from "../index.js";
|
|
12
20
|
import {
|
|
13
21
|
Account,
|
|
14
|
-
CoList,
|
|
15
22
|
Loaded,
|
|
16
23
|
MaybeLoaded,
|
|
17
|
-
|
|
24
|
+
Settled,
|
|
18
25
|
co,
|
|
19
26
|
randomSessionProvider,
|
|
20
27
|
CoValueLoadingState,
|
|
21
|
-
|
|
28
|
+
CoValueErrorState,
|
|
22
29
|
} from "../internal.js";
|
|
23
30
|
import { createJazzTestAccount, linkAccounts } from "../testing.js";
|
|
24
31
|
import { assertLoaded, waitFor } from "./utils.js";
|
|
32
|
+
import { setCustomErrorReporter } from "../config.js";
|
|
25
33
|
|
|
26
34
|
const Crypto = await WasmCrypto.create();
|
|
27
35
|
const { connectedPeers } = cojsonInternals;
|
|
@@ -43,6 +51,15 @@ const TestMap = co.map({
|
|
|
43
51
|
optionalRef: co.optional(InnermostMap),
|
|
44
52
|
});
|
|
45
53
|
|
|
54
|
+
let lastError: Error | undefined;
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
lastError = undefined;
|
|
58
|
+
setCustomErrorReporter((error) => {
|
|
59
|
+
lastError = error;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
46
63
|
describe("Deep loading with depth arg", async () => {
|
|
47
64
|
const me = await Account.create({
|
|
48
65
|
creationProps: { name: "Hermes Puggington" },
|
|
@@ -345,7 +362,7 @@ test("Deep loading a record-like coMap", async () => {
|
|
|
345
362
|
},
|
|
346
363
|
});
|
|
347
364
|
expectTypeOf(recordLoaded).branded.toEqualTypeOf<
|
|
348
|
-
|
|
365
|
+
Settled<
|
|
349
366
|
Loaded<typeof RecordLike> & {
|
|
350
367
|
readonly [key: string]: Loaded<typeof TestMap> & {
|
|
351
368
|
readonly list: Loaded<typeof TestList> &
|
|
@@ -494,17 +511,14 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
494
511
|
CoValueLoadingState.UNAUTHORIZED,
|
|
495
512
|
);
|
|
496
513
|
|
|
497
|
-
expect(
|
|
498
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
514
|
+
expect(lastError?.message).toBe(
|
|
515
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${map.$jazz.id}`,
|
|
499
516
|
);
|
|
500
|
-
|
|
501
|
-
errorSpy.mockReset();
|
|
502
517
|
});
|
|
503
518
|
|
|
504
519
|
test("unaccessible list", async () => {
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
const map = TestMap.create({ list: TestList.create([], onlyBob) }, group);
|
|
520
|
+
const innerList = TestList.create([], onlyBob);
|
|
521
|
+
const map = TestMap.create({ list: innerList }, group);
|
|
508
522
|
|
|
509
523
|
const mapOnAlice = await TestMap.load(map.$jazz.id, { loadAs: alice });
|
|
510
524
|
expect(mapOnAlice).toBeTruthy();
|
|
@@ -518,16 +532,12 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
518
532
|
CoValueLoadingState.UNAUTHORIZED,
|
|
519
533
|
);
|
|
520
534
|
|
|
521
|
-
expect(
|
|
522
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
535
|
+
expect(lastError?.message).toBe(
|
|
536
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${innerList.$jazz.id}. Subscription starts from ${map.$jazz.id} and the value is on path list`,
|
|
523
537
|
);
|
|
524
|
-
|
|
525
|
-
errorSpy.mockReset();
|
|
526
538
|
});
|
|
527
539
|
|
|
528
540
|
test("unaccessible list element", async () => {
|
|
529
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
530
|
-
|
|
531
541
|
const map = TestMap.create(
|
|
532
542
|
{
|
|
533
543
|
list: TestList.create(
|
|
@@ -554,16 +564,12 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
554
564
|
CoValueLoadingState.UNAUTHORIZED,
|
|
555
565
|
);
|
|
556
566
|
|
|
557
|
-
expect(
|
|
558
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
567
|
+
expect(lastError?.message).toBe(
|
|
568
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${map.list[0]!.$jazz.id}. Subscription starts from ${map.$jazz.id} and the value is on path list.0`,
|
|
559
569
|
);
|
|
560
|
-
|
|
561
|
-
errorSpy.mockReset();
|
|
562
570
|
});
|
|
563
571
|
|
|
564
572
|
test("unaccessible optional element", async () => {
|
|
565
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
566
|
-
|
|
567
573
|
const map = TestMap.create(
|
|
568
574
|
{
|
|
569
575
|
list: TestList.create([], group),
|
|
@@ -579,11 +585,9 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
579
585
|
expect(mapOnAlice.$jazz.loadingState).toBe(
|
|
580
586
|
CoValueLoadingState.UNAUTHORIZED,
|
|
581
587
|
);
|
|
582
|
-
expect(
|
|
583
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
588
|
+
expect(lastError?.message).toBe(
|
|
589
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${map.optionalRef!.$jazz.id}. Subscription starts from ${map.$jazz.id} and the value is on path optionalRef`,
|
|
584
590
|
);
|
|
585
|
-
|
|
586
|
-
errorSpy.mockReset();
|
|
587
591
|
});
|
|
588
592
|
|
|
589
593
|
test("unaccessible optional element via autoload", async () => {
|
|
@@ -611,17 +615,20 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
611
615
|
});
|
|
612
616
|
|
|
613
617
|
expect(result?.$jazz.loadingState).toBe(CoValueLoadingState.UNAUTHORIZED);
|
|
618
|
+
expect(lastError?.message).toBe(
|
|
619
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${map.optionalRef!.$jazz.id}`,
|
|
620
|
+
);
|
|
614
621
|
});
|
|
615
622
|
|
|
616
623
|
test("unaccessible stream", async () => {
|
|
617
|
-
const
|
|
624
|
+
const stream = TestFeed.create([], onlyBob);
|
|
618
625
|
const map = TestMap.create(
|
|
619
626
|
{
|
|
620
627
|
list: TestList.create(
|
|
621
628
|
[
|
|
622
629
|
InnerMap.create(
|
|
623
630
|
{
|
|
624
|
-
stream
|
|
631
|
+
stream,
|
|
625
632
|
},
|
|
626
633
|
group,
|
|
627
634
|
),
|
|
@@ -641,16 +648,12 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
641
648
|
CoValueLoadingState.UNAUTHORIZED,
|
|
642
649
|
);
|
|
643
650
|
|
|
644
|
-
expect(
|
|
645
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
651
|
+
expect(lastError?.message).toBe(
|
|
652
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${stream.$jazz.id}. Subscription starts from ${map.$jazz.id} and the value is on path list.0.stream`,
|
|
646
653
|
);
|
|
647
|
-
|
|
648
|
-
errorSpy.mockReset();
|
|
649
654
|
});
|
|
650
655
|
|
|
651
656
|
test("unaccessible stream element", async () => {
|
|
652
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
653
|
-
|
|
654
657
|
const value = InnermostMap.create({ value: "hello" }, onlyBob);
|
|
655
658
|
|
|
656
659
|
const map = TestMap.create(
|
|
@@ -679,11 +682,9 @@ describe("Deep loading with unauthorized account", async () => {
|
|
|
679
682
|
CoValueLoadingState.UNAUTHORIZED,
|
|
680
683
|
);
|
|
681
684
|
|
|
682
|
-
expect(
|
|
683
|
-
`The current user (${alice.$jazz.id}) is not authorized to access
|
|
685
|
+
expect(lastError?.message).toBe(
|
|
686
|
+
`Jazz Authorization Error: The current user (${alice.$jazz.id}) is not authorized to access ${value.$jazz.id}. Subscription starts from ${map.$jazz.id} and the value is on path list.0.stream.${value.$jazz.id}`,
|
|
684
687
|
);
|
|
685
|
-
|
|
686
|
-
errorSpy.mockReset();
|
|
687
688
|
});
|
|
688
689
|
|
|
689
690
|
test("setting undefined via proxy", async () => {
|
|
@@ -1229,7 +1230,7 @@ describe("$isLoaded", async () => {
|
|
|
1229
1230
|
|
|
1230
1231
|
const map = TestMap.create({ list: [] }, { owner: me });
|
|
1231
1232
|
|
|
1232
|
-
test("$isLoaded narrows
|
|
1233
|
+
test("$isLoaded narrows a maybe-loaded CoValue to a loaded CoValue", async () => {
|
|
1233
1234
|
const maybeLoadedMap = await TestMap.load(map.$jazz.id, {
|
|
1234
1235
|
loadAs: me,
|
|
1235
1236
|
});
|
|
@@ -1244,19 +1245,18 @@ describe("$isLoaded", async () => {
|
|
|
1244
1245
|
} else {
|
|
1245
1246
|
expectTypeOf(
|
|
1246
1247
|
maybeLoadedMap.$jazz.loadingState,
|
|
1247
|
-
).toEqualTypeOf<
|
|
1248
|
+
).toEqualTypeOf<CoValueErrorState>();
|
|
1248
1249
|
}
|
|
1249
1250
|
});
|
|
1250
1251
|
|
|
1251
|
-
test("$isLoaded narrows
|
|
1252
|
+
test("$isLoaded narrows a maybe-loaded CoValue to a not loaded CoValue", async () => {
|
|
1252
1253
|
const otherAccount = await Account.create({
|
|
1253
1254
|
creationProps: { name: "Other Account" },
|
|
1254
1255
|
crypto: Crypto,
|
|
1255
1256
|
});
|
|
1256
|
-
const unloadedMap
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
);
|
|
1257
|
+
const unloadedMap = await TestMap.load(map.$jazz.id, {
|
|
1258
|
+
loadAs: otherAccount,
|
|
1259
|
+
});
|
|
1260
1260
|
|
|
1261
1261
|
expect(unloadedMap.$isLoaded).toBe(false);
|
|
1262
1262
|
if (!unloadedMap.$isLoaded) {
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { Group, z } from "../index.js";
|
|
3
|
+
import { setCustomErrorReporter } from "../config.js";
|
|
4
|
+
import { CoValueLoadingState } from "../internal.js";
|
|
5
|
+
import { createJazzTestAccount, linkAccounts } from "../testing.js";
|
|
6
|
+
import { co } from "../exports.js";
|
|
7
|
+
|
|
8
|
+
const TestMap = co.map({
|
|
9
|
+
value: z.string(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("Custom error reporter", () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
// Clean up error reporter before each test
|
|
15
|
+
setCustomErrorReporter(undefined);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("with custom error reporter enabled, console.error is not called", async () => {
|
|
19
|
+
const bob = await createJazzTestAccount({
|
|
20
|
+
creationProps: { name: "Bob" },
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const alice = await createJazzTestAccount({
|
|
24
|
+
creationProps: { name: "Alice" },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
linkAccounts(bob, alice);
|
|
28
|
+
|
|
29
|
+
await alice.$jazz.waitForAllCoValuesSync();
|
|
30
|
+
|
|
31
|
+
const onlyBob = bob;
|
|
32
|
+
const group = Group.create(bob);
|
|
33
|
+
|
|
34
|
+
group.addMember(alice, "reader");
|
|
35
|
+
|
|
36
|
+
let capturedError: Error | undefined;
|
|
37
|
+
let capturedProps: { jazzError: any } | undefined;
|
|
38
|
+
|
|
39
|
+
setCustomErrorReporter((error, props) => {
|
|
40
|
+
capturedError = error;
|
|
41
|
+
capturedProps = props;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const consoleErrorSpy = vi
|
|
45
|
+
.spyOn(console, "error")
|
|
46
|
+
.mockImplementation(() => {});
|
|
47
|
+
|
|
48
|
+
const map = TestMap.create({ value: "hello" }, onlyBob);
|
|
49
|
+
|
|
50
|
+
const mapOnAlice = await TestMap.load(map.$jazz.id, { loadAs: alice });
|
|
51
|
+
|
|
52
|
+
// Access the value to trigger error logging
|
|
53
|
+
expect(mapOnAlice.$jazz.loadingState).toBe(
|
|
54
|
+
CoValueLoadingState.UNAUTHORIZED,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(consoleErrorSpy).not.toHaveBeenCalled();
|
|
58
|
+
expect(capturedError).toBeDefined();
|
|
59
|
+
expect(capturedProps).toBeDefined();
|
|
60
|
+
expect(capturedProps?.jazzError).toBeDefined();
|
|
61
|
+
|
|
62
|
+
consoleErrorSpy.mockRestore();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("without custom error reporter, console.error is called", async () => {
|
|
66
|
+
const bob = await createJazzTestAccount({
|
|
67
|
+
creationProps: { name: "Bob" },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const alice = await createJazzTestAccount({
|
|
71
|
+
creationProps: { name: "Alice" },
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
linkAccounts(bob, alice);
|
|
75
|
+
|
|
76
|
+
await alice.$jazz.waitForAllCoValuesSync();
|
|
77
|
+
|
|
78
|
+
const onlyBob = bob;
|
|
79
|
+
const group = Group.create(bob);
|
|
80
|
+
|
|
81
|
+
group.addMember(alice, "reader");
|
|
82
|
+
|
|
83
|
+
// Ensure no custom error reporter is set
|
|
84
|
+
setCustomErrorReporter(undefined);
|
|
85
|
+
|
|
86
|
+
const consoleErrorSpy = vi
|
|
87
|
+
.spyOn(console, "error")
|
|
88
|
+
.mockImplementation(() => {});
|
|
89
|
+
|
|
90
|
+
const map = TestMap.create({ value: "hello" }, onlyBob);
|
|
91
|
+
|
|
92
|
+
const mapOnAlice = await TestMap.load(map.$jazz.id, { loadAs: alice });
|
|
93
|
+
|
|
94
|
+
// Access the value to trigger error logging
|
|
95
|
+
expect(mapOnAlice.$jazz.loadingState).toBe(
|
|
96
|
+
CoValueLoadingState.UNAUTHORIZED,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
100
|
+
|
|
101
|
+
consoleErrorSpy.mockRestore();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { cojsonInternals, emptyKnownState } from "cojson";
|
|
2
2
|
import { assert, beforeEach, expect, test } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Account,
|
|
5
|
+
Group,
|
|
6
|
+
co,
|
|
7
|
+
exportCoValue,
|
|
8
|
+
jazzConfig,
|
|
9
|
+
z,
|
|
10
|
+
} from "../exports.js";
|
|
4
11
|
import { CoValueLoadingState } from "../internal.js";
|
|
5
12
|
import {
|
|
6
13
|
createJazzTestAccount,
|
|
@@ -12,6 +19,13 @@ import { assertLoaded, waitFor } from "./utils.js";
|
|
|
12
19
|
|
|
13
20
|
cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 10;
|
|
14
21
|
|
|
22
|
+
let lastError: Error | undefined;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
lastError = undefined;
|
|
25
|
+
jazzConfig.setCustomErrorReporter((error) => {
|
|
26
|
+
lastError = error;
|
|
27
|
+
});
|
|
28
|
+
});
|
|
15
29
|
beforeEach(async () => {
|
|
16
30
|
await setupJazzTestSync();
|
|
17
31
|
await createJazzTestAccount({
|
|
@@ -42,6 +56,9 @@ test("return 'unavailable' if id is invalid", async () => {
|
|
|
42
56
|
|
|
43
57
|
const john = await Person.load("test");
|
|
44
58
|
expect(john.$jazz.loadingState).toBe(CoValueLoadingState.UNAVAILABLE);
|
|
59
|
+
expect(lastError?.message).toBe(
|
|
60
|
+
"Jazz Unavailable Error: unable to load test",
|
|
61
|
+
);
|
|
45
62
|
});
|
|
46
63
|
|
|
47
64
|
test("load a missing optional value (co.optional)", async () => {
|
|
@@ -185,6 +202,9 @@ test("returns 'unavailable' if the value is unavailable after retries", async ()
|
|
|
185
202
|
const john = await Person.load(map.$jazz.id, { loadAs: alice });
|
|
186
203
|
|
|
187
204
|
expect(john.$jazz.loadingState).toBe(CoValueLoadingState.UNAVAILABLE);
|
|
205
|
+
expect(lastError?.message).toBe(
|
|
206
|
+
"Jazz Unavailable Error: unable to load " + map.$jazz.id,
|
|
207
|
+
);
|
|
188
208
|
});
|
|
189
209
|
|
|
190
210
|
test("load works even when the coValue access is granted after the creation", async () => {
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
CoValueLoadingState,
|
|
15
15
|
exportCoValue,
|
|
16
16
|
importContentPieces,
|
|
17
|
+
Inaccessible,
|
|
17
18
|
} from "../internal.js";
|
|
18
19
|
import { createJazzTestAccount, linkAccounts } from "../testing.js";
|
|
19
20
|
|
|
@@ -663,7 +664,7 @@ describe("JazzRequestError handling", () => {
|
|
|
663
664
|
createUnloadedCoValue(
|
|
664
665
|
"some-covalue-id",
|
|
665
666
|
CoValueLoadingState.UNAVAILABLE,
|
|
666
|
-
)
|
|
667
|
+
) as Inaccessible<Account>,
|
|
667
668
|
);
|
|
668
669
|
|
|
669
670
|
return userRequest.handle(request, worker, async () => {
|
|
@@ -1297,6 +1297,50 @@ describe("subscribeToCoValue", () => {
|
|
|
1297
1297
|
expect(result.data[chunks]).toBe("new entry");
|
|
1298
1298
|
});
|
|
1299
1299
|
|
|
1300
|
+
it("should emit not emit when the content doesn't bring real changes", async () => {
|
|
1301
|
+
const alice = await createJazzTestAccount();
|
|
1302
|
+
|
|
1303
|
+
const Person = co.map({
|
|
1304
|
+
name: z.string(),
|
|
1305
|
+
});
|
|
1306
|
+
const PersonList = co.list(Person);
|
|
1307
|
+
|
|
1308
|
+
const group = Group.create(alice);
|
|
1309
|
+
|
|
1310
|
+
const person1 = Person.create({ name: "John" }, group);
|
|
1311
|
+
const person2 = Person.create({ name: "Jane" }, group);
|
|
1312
|
+
|
|
1313
|
+
const personList = PersonList.create([person1, person2], group);
|
|
1314
|
+
|
|
1315
|
+
const spy = vi.fn();
|
|
1316
|
+
// Test subscribing to the large coValue
|
|
1317
|
+
const unsubscribe = subscribeToCoValue(
|
|
1318
|
+
coValueClassFromCoValueClassOrSchema(PersonList),
|
|
1319
|
+
personList.$jazz.id,
|
|
1320
|
+
{
|
|
1321
|
+
loadAs: alice,
|
|
1322
|
+
resolve: {
|
|
1323
|
+
$each: true,
|
|
1324
|
+
},
|
|
1325
|
+
syncResolution: true,
|
|
1326
|
+
},
|
|
1327
|
+
spy,
|
|
1328
|
+
);
|
|
1329
|
+
|
|
1330
|
+
onTestFinished(unsubscribe);
|
|
1331
|
+
|
|
1332
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
1333
|
+
|
|
1334
|
+
// Test that updates to the large coValue are properly subscribed
|
|
1335
|
+
spy.mockClear();
|
|
1336
|
+
|
|
1337
|
+
group.addMember("everyone", "reader");
|
|
1338
|
+
|
|
1339
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
1340
|
+
|
|
1341
|
+
expect(spy).not.toHaveBeenCalled();
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1300
1344
|
it.fails(
|
|
1301
1345
|
"should return the latest loaded state when a deeply loaded child becomes not accessible",
|
|
1302
1346
|
async () => {
|
package/tsup.config.ts
CHANGED
|
@@ -43,8 +43,16 @@ export default defineConfig([
|
|
|
43
43
|
index: "src/expo/index.ts",
|
|
44
44
|
testing: "src/expo/testing.ts",
|
|
45
45
|
crypto: "src/expo/crypto.ts",
|
|
46
|
+
polyfills: "src/react-native-core/polyfills/index.js",
|
|
46
47
|
},
|
|
47
48
|
outDir: "dist/expo",
|
|
49
|
+
external: [
|
|
50
|
+
"jazz-tools",
|
|
51
|
+
"readable-stream",
|
|
52
|
+
"@azure/core-asynciterator-polyfill",
|
|
53
|
+
"react-native-get-random-values",
|
|
54
|
+
"react-native-fast-encoder",
|
|
55
|
+
],
|
|
48
56
|
},
|
|
49
57
|
{
|
|
50
58
|
...cfg,
|
|
@@ -107,8 +115,16 @@ export default defineConfig([
|
|
|
107
115
|
index: "src/react-native/index.ts",
|
|
108
116
|
testing: "src/react-native/testing.ts",
|
|
109
117
|
crypto: "src/react-native/crypto.ts",
|
|
118
|
+
polyfills: "src/react-native-core/polyfills/index.js",
|
|
110
119
|
},
|
|
111
120
|
outDir: "dist/react-native",
|
|
121
|
+
external: [
|
|
122
|
+
"jazz-tools",
|
|
123
|
+
"readable-stream",
|
|
124
|
+
"@azure/core-asynciterator-polyfill",
|
|
125
|
+
"react-native-get-random-values",
|
|
126
|
+
"react-native-fast-encoder",
|
|
127
|
+
],
|
|
112
128
|
},
|
|
113
129
|
{
|
|
114
130
|
...cfg,
|
|
@@ -116,6 +132,7 @@ export default defineConfig([
|
|
|
116
132
|
index: "src/react-native-core/index.ts",
|
|
117
133
|
testing: "src/react-native-core/testing.tsx",
|
|
118
134
|
crypto: "src/react-native-core/crypto/index.ts",
|
|
135
|
+
"crypto/RNCrypto": "src/react-native-core/crypto/RNCrypto.ts",
|
|
119
136
|
},
|
|
120
137
|
outDir: "dist/react-native-core",
|
|
121
138
|
},
|