jazz-tools 0.15.8 → 0.15.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.
Files changed (47) hide show
  1. package/.turbo/turbo-build.log +45 -45
  2. package/CHANGELOG.md +21 -0
  3. package/dist/browser/createBrowserContext.d.ts.map +1 -1
  4. package/dist/browser/index.js +9 -7
  5. package/dist/browser/index.js.map +1 -1
  6. package/dist/{chunk-DGFPP22M.js → chunk-V54IPL5M.js} +31 -6
  7. package/dist/chunk-V54IPL5M.js.map +1 -0
  8. package/dist/index.js +1 -1
  9. package/dist/inspector/{custom-element-I7Q6H5E5.js → custom-element-TUXKXSZU.js} +18791 -18806
  10. package/dist/inspector/custom-element-TUXKXSZU.js.map +1 -0
  11. package/dist/inspector/register-custom-element.js +1 -1
  12. package/dist/react-native-core/index.d.ts +1 -1
  13. package/dist/react-native-core/index.d.ts.map +1 -1
  14. package/dist/react-native-core/index.js +15 -31
  15. package/dist/react-native-core/index.js.map +1 -1
  16. package/dist/react-native-core/platform.d.ts +1 -1
  17. package/dist/react-native-core/platform.d.ts.map +1 -1
  18. package/dist/testing.js +22 -3
  19. package/dist/testing.js.map +1 -1
  20. package/dist/tools/implementation/createContext.d.ts +8 -4
  21. package/dist/tools/implementation/createContext.d.ts.map +1 -1
  22. package/dist/tools/implementation/zodSchema/zodReExport.d.ts +1 -1
  23. package/dist/tools/implementation/zodSchema/zodReExport.d.ts.map +1 -1
  24. package/dist/tools/subscribe/SubscriptionScope.d.ts +2 -0
  25. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  26. package/dist/tools/testing.d.ts +3 -1
  27. package/dist/tools/testing.d.ts.map +1 -1
  28. package/package.json +7 -7
  29. package/src/browser/createBrowserContext.ts +8 -6
  30. package/src/react-core/tests/useCoState.test.ts +0 -12
  31. package/src/react-native-core/index.ts +1 -1
  32. package/src/react-native-core/platform.ts +13 -12
  33. package/src/tools/implementation/createContext.ts +16 -0
  34. package/src/tools/implementation/zodSchema/zodReExport.ts +1 -0
  35. package/src/tools/subscribe/SubscriptionScope.ts +21 -2
  36. package/src/tools/testing.ts +25 -2
  37. package/src/tools/tests/coFeed.test.ts +190 -239
  38. package/src/tools/tests/coMap.test.ts +0 -8
  39. package/src/tools/tests/coPlainText.test.ts +2 -1
  40. package/src/tools/tests/deepLoading.test.ts +6 -6
  41. package/src/tools/tests/load.test.ts +65 -30
  42. package/src/tools/tests/subscribe.test.ts +92 -0
  43. package/dist/chunk-DGFPP22M.js.map +0 -1
  44. package/dist/inspector/custom-element-I7Q6H5E5.js.map +0 -1
  45. package/dist/react-native-core/storage/sqlite-react-native.d.ts +0 -9
  46. package/dist/react-native-core/storage/sqlite-react-native.d.ts.map +0 -1
  47. package/src/react-native-core/storage/sqlite-react-native.ts +0 -19
@@ -1,5 +1,6 @@
1
- import { cojsonInternals } from "cojson";
2
- import { beforeEach, expect, test } from "vitest";
1
+ import { waitFor } from "@testing-library/dom";
2
+ import { cojsonInternals, emptyKnownState } from "cojson";
3
+ import { assert, beforeEach, expect, test } from "vitest";
3
4
  import { Account, Group, co, z } from "../exports.js";
4
5
  import {
5
6
  createJazzTestAccount,
@@ -7,6 +8,8 @@ import {
7
8
  setupJazzTestSync,
8
9
  } from "../testing.js";
9
10
 
11
+ cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 10;
12
+
10
13
  beforeEach(async () => {
11
14
  await setupJazzTestSync();
12
15
  await createJazzTestAccount({
@@ -48,20 +51,9 @@ test("retry an unavailable value", async () => {
48
51
 
49
52
  const alice = await createJazzTestAccount();
50
53
 
51
- let resolved = false;
52
54
  const promise = Person.load(map.id, { loadAs: alice });
53
- promise.then(() => {
54
- resolved = true;
55
- });
56
-
57
- await new Promise((resolve) =>
58
- setTimeout(
59
- resolve,
60
- cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY - 100,
61
- ),
62
- );
63
55
 
64
- expect(resolved).toBe(false);
56
+ await new Promise((resolve) => setTimeout(resolve));
65
57
 
66
58
  // Reconnect the current account
67
59
  currentAccount._raw.core.node.syncManager.addPeer(
@@ -69,7 +61,6 @@ test("retry an unavailable value", async () => {
69
61
  );
70
62
 
71
63
  const john = await promise;
72
- expect(resolved).toBe(true);
73
64
  expect(john).not.toBeNull();
74
65
  expect(john?.name).toBe("John");
75
66
  });
@@ -92,26 +83,70 @@ test("returns null if the value is unavailable after retries", async () => {
92
83
 
93
84
  const alice = await createJazzTestAccount();
94
85
 
95
- let resolved = false;
96
- const promise = Person.load(map.id, { loadAs: alice });
97
- promise.then(() => {
98
- resolved = true;
86
+ const john = await Person.load(map.id, { loadAs: alice });
87
+
88
+ expect(john).toBeNull();
89
+ });
90
+
91
+ test("load a large coValue", async () => {
92
+ const syncServer = await setupJazzTestSync({ asyncPeers: true });
93
+
94
+ const LargeDataset = co.map({
95
+ metadata: z.object({
96
+ name: z.string(),
97
+ description: z.string(),
98
+ createdAt: z.number(),
99
+ }),
100
+ data: co.list(z.string()),
99
101
  });
100
102
 
101
- await new Promise((resolve) =>
102
- setTimeout(
103
- resolve,
104
- cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY + 100,
105
- ),
103
+ const group = Group.create(syncServer);
104
+ const largeMap = LargeDataset.create(
105
+ {
106
+ metadata: {
107
+ name: "Large Dataset",
108
+ description:
109
+ "A dataset with many entries for testing large coValue loading",
110
+ createdAt: Date.now(),
111
+ },
112
+ data: LargeDataset.def.shape.data.create([], group),
113
+ },
114
+ group,
106
115
  );
116
+ group.addMember("everyone", "reader");
107
117
 
108
- expect(resolved).toBe(true);
118
+ const dataSize = 100 * 1024;
119
+ const chunkSize = 1024;
120
+ const chunks = dataSize / chunkSize;
109
121
 
110
- // Reconnect the current account
111
- currentAccount._raw.core.node.syncManager.addPeer(
112
- getPeerConnectedToTestSyncServer(),
122
+ const value = "x".repeat(chunkSize);
123
+
124
+ for (let i = 0; i < chunks; i++) {
125
+ largeMap.data.push(value);
126
+ }
127
+
128
+ // Wait for the large coValue to be fully synced
129
+ await largeMap.data._raw.core.waitForSync();
130
+
131
+ const alice = await createJazzTestAccount();
132
+
133
+ // Test loading the large coValue
134
+ const loadedDataset = await LargeDataset.load(largeMap.id, {
135
+ loadAs: alice,
136
+ resolve: {
137
+ data: true,
138
+ },
139
+ });
140
+
141
+ assert(loadedDataset);
142
+
143
+ expect(loadedDataset.metadata.name).toBe("Large Dataset");
144
+ expect(loadedDataset.metadata.description).toBe(
145
+ "A dataset with many entries for testing large coValue loading",
113
146
  );
114
147
 
115
- const john = await promise;
116
- expect(john).toBeNull();
148
+ expect(loadedDataset.data.length).toBe(chunks);
149
+ expect(loadedDataset.data._raw.core.knownState()).toEqual(
150
+ largeMap.data._raw.core.knownState(),
151
+ );
117
152
  });
@@ -1198,6 +1198,98 @@ describe("subscribeToCoValue", () => {
1198
1198
  expect(onUnavailable).not.toHaveBeenCalled();
1199
1199
  expect(onUnauthorized).not.toHaveBeenCalled();
1200
1200
  });
1201
+
1202
+ it("should subscribe to a large coValue", async () => {
1203
+ const syncServer = await setupJazzTestSync({ asyncPeers: true });
1204
+
1205
+ const LargeDataset = co.map({
1206
+ metadata: z.object({
1207
+ name: z.string(),
1208
+ description: z.string(),
1209
+ createdAt: z.number(),
1210
+ }),
1211
+ data: co.list(z.string()),
1212
+ });
1213
+
1214
+ const group = Group.create(syncServer);
1215
+ const largeMap = LargeDataset.create(
1216
+ {
1217
+ metadata: {
1218
+ name: "Large Dataset",
1219
+ description:
1220
+ "A dataset with many entries for testing large coValue subscription",
1221
+ createdAt: Date.now(),
1222
+ },
1223
+ data: LargeDataset.def.shape.data.create([], group),
1224
+ },
1225
+ group,
1226
+ );
1227
+ group.addMember("everyone", "reader");
1228
+
1229
+ const dataSize = 100 * 1024;
1230
+ const chunkSize = 1024;
1231
+ const chunks = dataSize / chunkSize;
1232
+
1233
+ const value = "x".repeat(chunkSize);
1234
+
1235
+ for (let i = 0; i < chunks; i++) {
1236
+ largeMap.data.push(value);
1237
+ }
1238
+
1239
+ // Wait for the large coValue to be fully synced
1240
+ await largeMap.data._raw.core.waitForSync();
1241
+
1242
+ const alice = await createJazzTestAccount();
1243
+
1244
+ let result = null as Loaded<typeof LargeDataset, { data: true }> | null;
1245
+ const updateFn = vi.fn().mockImplementation((value) => {
1246
+ result = value;
1247
+ });
1248
+
1249
+ // Test subscribing to the large coValue
1250
+ const unsubscribe = subscribeToCoValue(
1251
+ zodSchemaToCoSchema(LargeDataset),
1252
+ largeMap.id,
1253
+ {
1254
+ loadAs: alice,
1255
+ resolve: {
1256
+ data: true,
1257
+ },
1258
+ },
1259
+ updateFn,
1260
+ );
1261
+
1262
+ onTestFinished(unsubscribe);
1263
+
1264
+ await waitFor(() => {
1265
+ expect(updateFn).toHaveBeenCalled();
1266
+ });
1267
+
1268
+ assert(result);
1269
+
1270
+ expect(updateFn).toHaveBeenCalledTimes(1);
1271
+ expect(result.metadata.name).toBe("Large Dataset");
1272
+ expect(result.metadata.description).toBe(
1273
+ "A dataset with many entries for testing large coValue subscription",
1274
+ );
1275
+
1276
+ expect(result.data.length).toBe(chunks);
1277
+ expect(result.data._raw.core.knownState()).toEqual(
1278
+ largeMap.data._raw.core.knownState(),
1279
+ );
1280
+
1281
+ // Test that updates to the large coValue are properly subscribed
1282
+ updateFn.mockClear();
1283
+ largeMap.data.push("new entry");
1284
+
1285
+ await waitFor(() => {
1286
+ expect(updateFn).toHaveBeenCalled();
1287
+ });
1288
+
1289
+ expect(updateFn).toHaveBeenCalledTimes(1);
1290
+ expect(result.data.length).toBe(chunks + 1);
1291
+ expect(result.data[chunks]).toBe("new entry");
1292
+ });
1201
1293
  });
1202
1294
 
1203
1295
  describe("createCoValueObservable", () => {