jazz-tools 0.18.27 → 0.18.28

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 (40) hide show
  1. package/.turbo/turbo-build.log +57 -57
  2. package/CHANGELOG.md +13 -0
  3. package/dist/{chunk-ZIAN4UY5.js → chunk-YOL3XDDW.js} +158 -120
  4. package/dist/chunk-YOL3XDDW.js.map +1 -0
  5. package/dist/index.js +1 -1
  6. package/dist/react-core/hooks.d.ts +4 -0
  7. package/dist/react-core/hooks.d.ts.map +1 -1
  8. package/dist/react-core/index.js +5 -0
  9. package/dist/react-core/index.js.map +1 -1
  10. package/dist/testing.js +1 -1
  11. package/dist/tools/coValues/coList.d.ts +11 -3
  12. package/dist/tools/coValues/coList.d.ts.map +1 -1
  13. package/dist/tools/coValues/coMap.d.ts +21 -5
  14. package/dist/tools/coValues/coMap.d.ts.map +1 -1
  15. package/dist/tools/coValues/group.d.ts +2 -2
  16. package/dist/tools/coValues/group.d.ts.map +1 -1
  17. package/dist/tools/coValues/inbox.d.ts.map +1 -1
  18. package/dist/tools/coValues/interfaces.d.ts +9 -0
  19. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  20. package/dist/tools/exports.d.ts +1 -1
  21. package/dist/tools/exports.d.ts.map +1 -1
  22. package/dist/tools/tests/coList.unique.test.d.ts +2 -0
  23. package/dist/tools/tests/coList.unique.test.d.ts.map +1 -0
  24. package/dist/tools/tests/coMap.unique.test.d.ts +2 -0
  25. package/dist/tools/tests/coMap.unique.test.d.ts.map +1 -0
  26. package/package.json +4 -4
  27. package/src/react-core/hooks.ts +8 -0
  28. package/src/react-core/tests/useAccount.test.ts +61 -1
  29. package/src/react-core/tests/usePassPhraseAuth.test.ts +74 -2
  30. package/src/tools/coValues/coList.ts +38 -35
  31. package/src/tools/coValues/coMap.ts +38 -38
  32. package/src/tools/coValues/group.ts +5 -1
  33. package/src/tools/coValues/inbox.ts +4 -3
  34. package/src/tools/coValues/interfaces.ts +88 -0
  35. package/src/tools/exports.ts +1 -0
  36. package/src/tools/tests/coList.test.ts +0 -190
  37. package/src/tools/tests/coList.unique.test.ts +244 -0
  38. package/src/tools/tests/coMap.test.ts +0 -433
  39. package/src/tools/tests/coMap.unique.test.ts +474 -0
  40. package/dist/chunk-ZIAN4UY5.js.map +0 -1
@@ -1164,196 +1164,6 @@ describe("CoList subscription", async () => {
1164
1164
  });
1165
1165
  });
1166
1166
 
1167
- describe("CoList unique methods", () => {
1168
- test("loadUnique returns existing list", async () => {
1169
- const ItemList = co.list(z.string());
1170
- const group = Group.create();
1171
-
1172
- const originalList = ItemList.create(["item1", "item2", "item3"], {
1173
- owner: group,
1174
- unique: "test-list",
1175
- });
1176
-
1177
- const foundList = await ItemList.loadUnique("test-list", group.$jazz.id);
1178
- expect(foundList).toEqual(originalList);
1179
- expect(foundList?.length).toBe(3);
1180
- expect(foundList?.[0]).toBe("item1");
1181
- });
1182
-
1183
- test("loadUnique returns null for non-existent list", async () => {
1184
- const ItemList = co.list(z.string());
1185
- const group = Group.create();
1186
-
1187
- const foundList = await ItemList.loadUnique("non-existent", group.$jazz.id);
1188
- expect(foundList).toBeNull();
1189
- });
1190
-
1191
- test("upsertUnique creates new list when none exists", async () => {
1192
- const ItemList = co.list(z.string());
1193
- const group = Group.create();
1194
-
1195
- const sourceData = ["item1", "item2", "item3"];
1196
-
1197
- const result = await ItemList.upsertUnique({
1198
- value: sourceData,
1199
- unique: "new-list",
1200
- owner: group,
1201
- });
1202
-
1203
- expect(result).not.toBeNull();
1204
- expect(result?.length).toBe(3);
1205
- expect(result?.[0]).toBe("item1");
1206
- expect(result?.[1]).toBe("item2");
1207
- expect(result?.[2]).toBe("item3");
1208
- });
1209
-
1210
- test("upsertUnique without an active account", async () => {
1211
- const account = activeAccountContext.get();
1212
- const ItemList = co.list(z.string());
1213
-
1214
- const sourceData = ["item1", "item2", "item3"];
1215
-
1216
- const result = await runWithoutActiveAccount(() => {
1217
- return ItemList.upsertUnique({
1218
- value: sourceData,
1219
- unique: "new-list",
1220
- owner: account,
1221
- });
1222
- });
1223
-
1224
- expect(result).not.toBeNull();
1225
- expect(result?.length).toBe(3);
1226
- expect(result?.[0]).toBe("item1");
1227
- expect(result?.[1]).toBe("item2");
1228
- expect(result?.[2]).toBe("item3");
1229
-
1230
- expect(result?.$jazz.owner).toEqual(account);
1231
- });
1232
-
1233
- test("upsertUnique updates existing list", async () => {
1234
- const ItemList = co.list(z.string());
1235
- const group = Group.create();
1236
-
1237
- // Create initial list
1238
- const originalList = ItemList.create(["original1", "original2"], {
1239
- owner: group,
1240
- unique: "update-list",
1241
- });
1242
-
1243
- // Upsert with new data
1244
- const updatedList = await ItemList.upsertUnique({
1245
- value: ["updated1", "updated2", "updated3"],
1246
- unique: "update-list",
1247
- owner: group,
1248
- });
1249
-
1250
- expect(updatedList).toEqual(originalList); // Should be the same instance
1251
- expect(updatedList?.length).toBe(3);
1252
- expect(updatedList?.[0]).toBe("updated1");
1253
- expect(updatedList?.[1]).toBe("updated2");
1254
- expect(updatedList?.[2]).toBe("updated3");
1255
- });
1256
-
1257
- test("upsertUnique with CoValue items", async () => {
1258
- const Item = co.map({
1259
- name: z.string(),
1260
- value: z.number(),
1261
- });
1262
- const ItemList = co.list(Item);
1263
- const group = Group.create();
1264
-
1265
- const items = [
1266
- Item.create({ name: "First", value: 1 }, group),
1267
- Item.create({ name: "Second", value: 2 }, group),
1268
- ];
1269
-
1270
- const result = await ItemList.upsertUnique({
1271
- value: items,
1272
- unique: "item-list",
1273
- owner: group,
1274
- resolve: { $each: true },
1275
- });
1276
-
1277
- expect(result).not.toBeNull();
1278
- expect(result?.length).toBe(2);
1279
- expect(result?.[0]?.name).toBe("First");
1280
- expect(result?.[1]?.name).toBe("Second");
1281
- });
1282
-
1283
- test("upsertUnique updates list with CoValue items", async () => {
1284
- const Item = co.map({
1285
- name: z.string(),
1286
- value: z.number(),
1287
- });
1288
- const ItemList = co.list(Item);
1289
- const group = Group.create();
1290
-
1291
- // Create initial list
1292
- const initialItems = [Item.create({ name: "Initial", value: 0 }, group)];
1293
- const originalList = ItemList.create(initialItems, {
1294
- owner: group,
1295
- unique: "updateable-item-list",
1296
- });
1297
-
1298
- // Upsert with new items
1299
- const newItems = [
1300
- Item.create({ name: "Updated", value: 1 }, group),
1301
- Item.create({ name: "Added", value: 2 }, group),
1302
- ];
1303
-
1304
- const updatedList = await ItemList.upsertUnique({
1305
- value: newItems,
1306
- unique: "updateable-item-list",
1307
- owner: group,
1308
- resolve: { $each: true },
1309
- });
1310
-
1311
- expect(updatedList).toEqual(originalList); // Should be the same instance
1312
- expect(updatedList?.length).toBe(2);
1313
- expect(updatedList?.[0]?.name).toBe("Updated");
1314
- expect(updatedList?.[1]?.name).toBe("Added");
1315
- });
1316
-
1317
- test("findUnique returns correct ID", async () => {
1318
- const ItemList = co.list(z.string());
1319
- const group = Group.create();
1320
-
1321
- const originalList = ItemList.create(["test"], {
1322
- owner: group,
1323
- unique: "find-test",
1324
- });
1325
-
1326
- const foundId = ItemList.findUnique("find-test", group.$jazz.id);
1327
- expect(foundId).toBe(originalList.$jazz.id);
1328
- });
1329
-
1330
- test("upsertUnique with resolve options", async () => {
1331
- const Category = co.map({ title: z.string() });
1332
- const Item = co.map({
1333
- name: z.string(),
1334
- category: Category,
1335
- });
1336
- const ItemList = co.list(Item);
1337
- const group = Group.create();
1338
-
1339
- const category = Category.create({ title: "Category 1" }, group);
1340
-
1341
- const items = [Item.create({ name: "Item 1", category }, group)];
1342
-
1343
- const result = await ItemList.upsertUnique({
1344
- value: items,
1345
- unique: "resolved-list",
1346
- owner: group,
1347
- resolve: { $each: { category: true } },
1348
- });
1349
-
1350
- expect(result).not.toBeNull();
1351
- expect(result?.length).toBe(1);
1352
- expect(result?.[0]?.name).toBe("Item 1");
1353
- expect(result?.[0]?.category?.title).toBe("Category 1");
1354
- });
1355
- });
1356
-
1357
1167
  describe("co.list schema", () => {
1358
1168
  test("can access the inner schema of a co.list", () => {
1359
1169
  const Keywords = co.list(co.plainText());
@@ -0,0 +1,244 @@
1
+ import { WasmCrypto } from "cojson/crypto/WasmCrypto";
2
+ import { assert, beforeEach, describe, expect, test, vi } from "vitest";
3
+ import { Account, Group, subscribeToCoValue, z } from "../index.js";
4
+ import {
5
+ Loaded,
6
+ activeAccountContext,
7
+ co,
8
+ coValueClassFromCoValueClassOrSchema,
9
+ } from "../internal.js";
10
+ import {
11
+ createJazzTestAccount,
12
+ runWithoutActiveAccount,
13
+ setupJazzTestSync,
14
+ } from "../testing.js";
15
+ import { setupTwoNodes, waitFor } from "./utils.js";
16
+
17
+ const Crypto = await WasmCrypto.create();
18
+
19
+ let me = await Account.create({
20
+ creationProps: { name: "Hermes Puggington" },
21
+ crypto: Crypto,
22
+ });
23
+
24
+ beforeEach(async () => {
25
+ await setupJazzTestSync();
26
+
27
+ me = await createJazzTestAccount({
28
+ isCurrentActiveAccount: true,
29
+ creationProps: { name: "Hermes Puggington" },
30
+ });
31
+ });
32
+
33
+ describe("CoList unique methods", () => {
34
+ test("loadUnique returns existing list", async () => {
35
+ const ItemList = co.list(z.string());
36
+ const group = Group.create();
37
+
38
+ const originalList = ItemList.create(["item1", "item2", "item3"], {
39
+ owner: group,
40
+ unique: "test-list",
41
+ });
42
+
43
+ const foundList = await ItemList.loadUnique("test-list", group.$jazz.id);
44
+ expect(foundList).toEqual(originalList);
45
+ expect(foundList?.length).toBe(3);
46
+ expect(foundList?.[0]).toBe("item1");
47
+ });
48
+
49
+ test("loadUnique returns null for non-existent list", async () => {
50
+ const ItemList = co.list(z.string());
51
+ const group = Group.create();
52
+
53
+ const foundList = await ItemList.loadUnique("non-existent", group.$jazz.id);
54
+ expect(foundList).toBeNull();
55
+ });
56
+
57
+ test("upsertUnique creates new list when none exists", async () => {
58
+ const ItemList = co.list(z.string());
59
+ const group = Group.create();
60
+
61
+ const sourceData = ["item1", "item2", "item3"];
62
+
63
+ const result = await ItemList.upsertUnique({
64
+ value: sourceData,
65
+ unique: "new-list",
66
+ owner: group,
67
+ });
68
+
69
+ expect(result).not.toBeNull();
70
+ expect(result?.length).toBe(3);
71
+ expect(result?.[0]).toBe("item1");
72
+ expect(result?.[1]).toBe("item2");
73
+ expect(result?.[2]).toBe("item3");
74
+ });
75
+
76
+ test("upsertUnique without an active account", async () => {
77
+ const account = activeAccountContext.get();
78
+ const ItemList = co.list(z.string());
79
+
80
+ const sourceData = ["item1", "item2", "item3"];
81
+
82
+ const result = await runWithoutActiveAccount(() => {
83
+ return ItemList.upsertUnique({
84
+ value: sourceData,
85
+ unique: "new-list",
86
+ owner: account,
87
+ });
88
+ });
89
+
90
+ expect(result).not.toBeNull();
91
+ expect(result?.length).toBe(3);
92
+ expect(result?.[0]).toBe("item1");
93
+ expect(result?.[1]).toBe("item2");
94
+ expect(result?.[2]).toBe("item3");
95
+
96
+ expect(result?.$jazz.owner).toEqual(account);
97
+ });
98
+
99
+ test("upsertUnique updates existing list", async () => {
100
+ const ItemList = co.list(z.string());
101
+ const group = Group.create();
102
+
103
+ // Create initial list
104
+ const originalList = ItemList.create(["original1", "original2"], {
105
+ owner: group,
106
+ unique: "update-list",
107
+ });
108
+
109
+ // Upsert with new data
110
+ const updatedList = await ItemList.upsertUnique({
111
+ value: ["updated1", "updated2", "updated3"],
112
+ unique: "update-list",
113
+ owner: group,
114
+ });
115
+
116
+ expect(updatedList).toEqual(originalList); // Should be the same instance
117
+ expect(updatedList?.length).toBe(3);
118
+ expect(updatedList?.[0]).toBe("updated1");
119
+ expect(updatedList?.[1]).toBe("updated2");
120
+ expect(updatedList?.[2]).toBe("updated3");
121
+ });
122
+
123
+ test("upsertUnique with CoValue items", async () => {
124
+ const Item = co.map({
125
+ name: z.string(),
126
+ value: z.number(),
127
+ });
128
+ const ItemList = co.list(Item);
129
+ const group = Group.create();
130
+
131
+ const items = [
132
+ Item.create({ name: "First", value: 1 }, group),
133
+ Item.create({ name: "Second", value: 2 }, group),
134
+ ];
135
+
136
+ const result = await ItemList.upsertUnique({
137
+ value: items,
138
+ unique: "item-list",
139
+ owner: group,
140
+ resolve: { $each: true },
141
+ });
142
+
143
+ expect(result).not.toBeNull();
144
+ expect(result?.length).toBe(2);
145
+ expect(result?.[0]?.name).toBe("First");
146
+ expect(result?.[1]?.name).toBe("Second");
147
+ });
148
+
149
+ test("upsertUnique updates list with CoValue items", async () => {
150
+ const Item = co.map({
151
+ name: z.string(),
152
+ value: z.number(),
153
+ });
154
+ const ItemList = co.list(Item);
155
+ const group = Group.create();
156
+
157
+ // Create initial list
158
+ const initialItems = [Item.create({ name: "Initial", value: 0 }, group)];
159
+ const originalList = ItemList.create(initialItems, {
160
+ owner: group,
161
+ unique: "updateable-item-list",
162
+ });
163
+
164
+ // Upsert with new items
165
+ const newItems = [
166
+ Item.create({ name: "Updated", value: 1 }, group),
167
+ Item.create({ name: "Added", value: 2 }, group),
168
+ ];
169
+
170
+ const updatedList = await ItemList.upsertUnique({
171
+ value: newItems,
172
+ unique: "updateable-item-list",
173
+ owner: group,
174
+ resolve: { $each: true },
175
+ });
176
+
177
+ expect(updatedList).toEqual(originalList); // Should be the same instance
178
+ expect(updatedList?.length).toBe(2);
179
+ expect(updatedList?.[0]?.name).toBe("Updated");
180
+ expect(updatedList?.[1]?.name).toBe("Added");
181
+ });
182
+
183
+ test("findUnique returns correct ID", async () => {
184
+ const ItemList = co.list(z.string());
185
+ const group = Group.create();
186
+
187
+ const originalList = ItemList.create(["test"], {
188
+ owner: group,
189
+ unique: "find-test",
190
+ });
191
+
192
+ const foundId = ItemList.findUnique("find-test", group.$jazz.id);
193
+ expect(foundId).toBe(originalList.$jazz.id);
194
+ });
195
+
196
+ test("upsertUnique with resolve options", async () => {
197
+ const Category = co.map({ title: z.string() });
198
+ const Item = co.map({
199
+ name: z.string(),
200
+ category: Category,
201
+ });
202
+ const ItemList = co.list(Item);
203
+ const group = Group.create();
204
+
205
+ const category = Category.create({ title: "Category 1" }, group);
206
+
207
+ const items = [Item.create({ name: "Item 1", category }, group)];
208
+
209
+ const result = await ItemList.upsertUnique({
210
+ value: items,
211
+ unique: "resolved-list",
212
+ owner: group,
213
+ resolve: { $each: { category: true } },
214
+ });
215
+
216
+ expect(result).not.toBeNull();
217
+ expect(result?.length).toBe(1);
218
+ expect(result?.[0]?.name).toBe("Item 1");
219
+ expect(result?.[0]?.category?.title).toBe("Category 1");
220
+ });
221
+
222
+ test("concurrently upserting the same value", async () => {
223
+ const ItemList = co.list(z.string());
224
+
225
+ const owner = Group.create();
226
+
227
+ const promises = Array.from({ length: 3 }, (_, i) =>
228
+ ItemList.upsertUnique({
229
+ owner,
230
+ unique: "concurrent",
231
+ value: [`Item ${i}`, `Second ${i}`],
232
+ }),
233
+ );
234
+
235
+ await Promise.all(promises);
236
+
237
+ const result = await ItemList.loadUnique("concurrent", owner.$jazz.id);
238
+ assert(result);
239
+
240
+ expect(result.length).toBe(2);
241
+ expect(result[0]).toBe(`Item 2`);
242
+ expect(result[1]).toBe(`Second 2`);
243
+ });
244
+ });