jazz-tools 0.11.2 → 0.11.4

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.
@@ -4,6 +4,7 @@ import { describe, expect, test } from "vitest";
4
4
  import {
5
5
  Account,
6
6
  CoList,
7
+ CoMap,
7
8
  Group,
8
9
  co,
9
10
  createJazzContextFromExistingCredentials,
@@ -61,6 +62,69 @@ describe("Simple CoList operations", async () => {
61
62
  expect(list[1]).toBe("margarine");
62
63
  });
63
64
 
65
+ test("assignment with ref", () => {
66
+ class Ingredient extends CoMap {
67
+ name = co.string;
68
+ }
69
+
70
+ class Recipe extends CoList.Of(co.ref(Ingredient)) {}
71
+
72
+ const recipe = Recipe.create(
73
+ [
74
+ Ingredient.create({ name: "bread" }, me),
75
+ Ingredient.create({ name: "butter" }, me),
76
+ Ingredient.create({ name: "onion" }, me),
77
+ ],
78
+ { owner: me },
79
+ );
80
+
81
+ recipe[1] = Ingredient.create({ name: "margarine" }, me);
82
+ expect(recipe[1]?.name).toBe("margarine");
83
+ });
84
+
85
+ test("assign null on a required ref", () => {
86
+ class Ingredient extends CoMap {
87
+ name = co.string;
88
+ }
89
+
90
+ class Recipe extends CoList.Of(co.ref(Ingredient)) {}
91
+
92
+ const recipe = Recipe.create(
93
+ [
94
+ Ingredient.create({ name: "bread" }, me),
95
+ Ingredient.create({ name: "butter" }, me),
96
+ Ingredient.create({ name: "onion" }, me),
97
+ ],
98
+ { owner: me },
99
+ );
100
+
101
+ expect(() => {
102
+ recipe[1] = null;
103
+ }).toThrow("Cannot set required reference 1 to null");
104
+
105
+ expect(recipe[1]?.name).toBe("butter");
106
+ });
107
+
108
+ test("assign null on an optional ref", () => {
109
+ class Ingredient extends CoMap {
110
+ name = co.string;
111
+ }
112
+
113
+ class Recipe extends CoList.Of(co.optional.ref(Ingredient)) {}
114
+
115
+ const recipe = Recipe.create(
116
+ [
117
+ Ingredient.create({ name: "bread" }, me),
118
+ Ingredient.create({ name: "butter" }, me),
119
+ Ingredient.create({ name: "onion" }, me),
120
+ ],
121
+ { owner: me },
122
+ );
123
+
124
+ recipe[1] = null;
125
+ expect(recipe[1]).toBe(null);
126
+ });
127
+
64
128
  test("push", () => {
65
129
  const list = TestList.create(["bread", "butter", "onion"], {
66
130
  owner: me,
@@ -107,13 +171,115 @@ describe("Simple CoList operations", async () => {
107
171
  expect(list._raw.asArray()).toEqual(["butter", "onion"]);
108
172
  });
109
173
 
110
- test("splice", () => {
111
- const list = TestList.create(["bread", "butter", "onion"], {
112
- owner: me,
174
+ describe("splice", () => {
175
+ test("insert after 1st item with 1 item removed", () => {
176
+ const list = TestList.create(["bread", "butter", "onion"], {
177
+ owner: me,
178
+ });
179
+ list.splice(1, 1, "salt", "pepper");
180
+ expect(list.length).toBe(4);
181
+ expect(list._raw.asArray()).toEqual([
182
+ "bread",
183
+ "salt",
184
+ "pepper",
185
+ "onion",
186
+ ]);
187
+ });
188
+
189
+ test("insert before 1st item", () => {
190
+ const list = TestList.create(["bread", "butter", "onion"], {
191
+ owner: me,
192
+ });
193
+ list.splice(0, 0, "salt", "pepper");
194
+ expect(list.length).toBe(5);
195
+ expect(list._raw.asArray()).toEqual([
196
+ "salt",
197
+ "pepper",
198
+ "bread",
199
+ "butter",
200
+ "onion",
201
+ ]);
202
+ });
203
+
204
+ test("insert after 1st item", () => {
205
+ const list = TestList.create(["bread", "butter", "onion"], {
206
+ owner: me,
207
+ });
208
+ list.splice(1, 0, "salt", "pepper");
209
+ expect(list.length).toBe(5);
210
+ expect(list._raw.asArray()).toEqual([
211
+ "bread",
212
+ "salt",
213
+ "pepper",
214
+ "butter",
215
+ "onion",
216
+ ]);
217
+ });
218
+
219
+ test("insert after 2nd item", () => {
220
+ const list = TestList.create(["bread", "butter", "onion"], {
221
+ owner: me,
222
+ });
223
+ list.splice(2, 0, "salt", "pepper");
224
+ expect(list.length).toBe(5);
225
+ expect(list._raw.asArray()).toEqual([
226
+ "bread",
227
+ "butter",
228
+ "salt",
229
+ "pepper",
230
+ "onion",
231
+ ]);
113
232
  });
114
- list.splice(1, 1, "salt", "pepper");
115
- expect(list.length).toBe(4);
116
- expect(list._raw.asArray()).toEqual(["bread", "salt", "pepper", "onion"]);
233
+ });
234
+
235
+ test("sort", () => {
236
+ const list = TestList.create(
237
+ ["hedgehog", "giraffe", "iguana", "flamingo"],
238
+ { owner: me },
239
+ );
240
+
241
+ list.sort();
242
+ expect(list._raw.asArray()).toEqual([
243
+ "flamingo",
244
+ "giraffe",
245
+ "hedgehog",
246
+ "iguana",
247
+ ]);
248
+
249
+ list.sort((a, b) => b.localeCompare(a));
250
+ expect(list._raw.asArray()).toEqual([
251
+ "iguana",
252
+ "hedgehog",
253
+ "giraffe",
254
+ "flamingo",
255
+ ]);
256
+ });
257
+
258
+ test("sort list of refs", async () => {
259
+ class Message extends CoMap {
260
+ text = co.string;
261
+ }
262
+
263
+ class Chat extends CoList.Of(co.ref(Message)) {}
264
+
265
+ const chat = Chat.create(
266
+ [
267
+ Message.create({ text: "world" }, { owner: me }),
268
+ Message.create({ text: "hello" }, { owner: me }),
269
+ ],
270
+ { owner: me },
271
+ );
272
+
273
+ chat.sort((a, b) => a!.text.localeCompare(b!.text));
274
+ expect(chat.map((m) => m!.text)).toEqual(["hello", "world"]);
275
+
276
+ chat.push(Message.create({ text: "beans on toast" }, { owner: me }));
277
+ chat.sort((a, b) => a!.text.localeCompare(b!.text));
278
+ expect(chat.map((m) => m!.text)).toEqual([
279
+ "beans on toast",
280
+ "hello",
281
+ "world",
282
+ ]);
117
283
  });
118
284
 
119
285
  test("applyDiff", () => {
@@ -135,6 +301,147 @@ describe("Simple CoList operations", async () => {
135
301
  "cheese",
136
302
  ]);
137
303
  });
304
+
305
+ test("filter + assign to coMap", () => {
306
+ class TestMap extends CoMap {
307
+ list = co.ref(TestList);
308
+ }
309
+
310
+ const map = TestMap.create(
311
+ {
312
+ list: TestList.create(["bread", "butter", "onion"], {
313
+ owner: me,
314
+ }),
315
+ },
316
+ { owner: me },
317
+ );
318
+
319
+ expect(() => {
320
+ // @ts-expect-error
321
+ map.list = map.list?.filter((item) => item !== "butter");
322
+ }).toThrow("Cannot set reference list to a non-CoValue. Got bread,onion");
323
+
324
+ expect(map.list?._raw.asArray()).toEqual(["bread", "butter", "onion"]);
325
+ });
326
+
327
+ test("filter + assign to CoList", () => {
328
+ class TestListOfLists extends CoList.Of(co.ref(TestList)) {}
329
+
330
+ const list = TestListOfLists.create(
331
+ [
332
+ TestList.create(["bread", "butter", "onion"], {
333
+ owner: me,
334
+ }),
335
+ ],
336
+ { owner: me },
337
+ );
338
+
339
+ expect(() => {
340
+ // @ts-expect-error
341
+ list[0] = list[0]?.filter((item) => item !== "butter");
342
+ }).toThrow("Cannot set reference 0 to a non-CoValue. Got bread,onion");
343
+
344
+ expect(list[0]?._raw.asArray()).toEqual(["bread", "butter", "onion"]);
345
+ });
346
+ });
347
+ });
348
+
349
+ describe("CoList applyDiff operations", async () => {
350
+ const me = await Account.create({
351
+ creationProps: { name: "Hermes Puggington" },
352
+ crypto: Crypto,
353
+ });
354
+
355
+ test("applyDiff with primitive values", () => {
356
+ class StringList extends CoList.Of(co.string) {}
357
+ const list = StringList.create(["a", "b", "c"], { owner: me });
358
+
359
+ // Test adding items
360
+ list.applyDiff(["a", "b", "c", "d", "e"]);
361
+ expect(list._raw.asArray()).toEqual(["a", "b", "c", "d", "e"]);
362
+
363
+ // Test removing items
364
+ list.applyDiff(["a", "c", "e"]);
365
+ expect(list._raw.asArray()).toEqual(["a", "c", "e"]);
366
+
367
+ // Test replacing items
368
+ list.applyDiff(["x", "y", "z"]);
369
+ expect(list._raw.asArray()).toEqual(["x", "y", "z"]);
370
+
371
+ // Test empty list
372
+ list.applyDiff([]);
373
+ expect(list._raw.asArray()).toEqual([]);
374
+ });
375
+
376
+ test("applyDiff with reference values", () => {
377
+ class NestedItem extends CoList.Of(co.string) {
378
+ get value() {
379
+ return this[0];
380
+ }
381
+ }
382
+ class RefList extends CoList.Of(co.ref(NestedItem)) {}
383
+
384
+ const item1 = NestedItem.create(["item1"], { owner: me });
385
+ const item2 = NestedItem.create(["item2"], { owner: me });
386
+ const item3 = NestedItem.create(["item3"], { owner: me });
387
+ const item4 = NestedItem.create(["item4"], { owner: me });
388
+
389
+ const list = RefList.create([item1, item2], { owner: me });
390
+
391
+ // Test adding reference items
392
+ list.applyDiff([item1, item2, item3]);
393
+ expect(list.length).toBe(3);
394
+ expect(list[2]?.value).toBe("item3");
395
+
396
+ // Test removing reference items
397
+ list.applyDiff([item1, item3]);
398
+ expect(list.length).toBe(2);
399
+ expect(list[0]?.value).toBe("item1");
400
+ expect(list[1]?.value).toBe("item3");
401
+
402
+ // Test replacing reference items
403
+ list.applyDiff([item4]);
404
+ expect(list.length).toBe(1);
405
+ expect(list[0]?.value).toBe("item4");
406
+
407
+ // Test empty list
408
+ list.applyDiff([]);
409
+ expect(list._raw.asArray()).toEqual([]);
410
+ });
411
+
412
+ test("applyDiff with refs + filter", () => {
413
+ class TestMap extends CoMap {
414
+ type = co.string;
415
+ }
416
+
417
+ class TestList extends CoList.Of(co.ref(TestMap)) {}
418
+
419
+ const bread = TestMap.create({ type: "bread" }, me);
420
+ const butter = TestMap.create({ type: "butter" }, me);
421
+ const onion = TestMap.create({ type: "onion" }, me);
422
+
423
+ const list = TestList.create([bread, butter, onion], me);
424
+
425
+ list.applyDiff(list.filter((item) => item?.type !== "butter"));
426
+
427
+ expect(list._raw.asArray()).toEqual([bread.id, onion.id]);
428
+ });
429
+
430
+ test("applyDiff with mixed operations", () => {
431
+ class StringList extends CoList.Of(co.string) {}
432
+ const list = StringList.create(["a", "b", "c", "d", "e"], { owner: me });
433
+
434
+ // Test multiple operations at once
435
+ list.applyDiff(["a", "x", "c", "y", "e"]);
436
+ expect(list._raw.asArray()).toEqual(["a", "x", "c", "y", "e"]);
437
+
438
+ // Test reordering
439
+ list.applyDiff(["e", "c", "a", "y", "x"]);
440
+ expect(list._raw.asArray()).toEqual(["e", "c", "a", "y", "x"]);
441
+
442
+ // Test partial update
443
+ list.applyDiff(["e", "c", "new", "y", "x"]);
444
+ expect(list._raw.asArray()).toEqual(["e", "c", "new", "y", "x"]);
138
445
  });
139
446
  });
140
447
 
@@ -4,6 +4,7 @@ import { SchemaUnion } from "../coValues/schemaUnion.js";
4
4
  import {
5
5
  Account,
6
6
  CoMap,
7
+ CryptoProvider,
7
8
  co,
8
9
  loadCoValue,
9
10
  subscribeToCoValue,
@@ -63,7 +64,7 @@ const getWidgetSchemaFromRaw = (raw: BaseWidget["_raw"]) => {
63
64
  class WidgetUnion extends SchemaUnion.Of<BaseWidget>(getWidgetSchemaFromRaw) {}
64
65
 
65
66
  describe("SchemaUnion", () => {
66
- let Crypto: WasmCrypto;
67
+ let Crypto: CryptoProvider;
67
68
  let me: Account;
68
69
 
69
70
  beforeAll(async () => {