jazz-tools 0.15.0 → 0.15.1
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 +44 -44
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-FSIM7N33.js → chunk-VBDJM6Z5.js} +142 -31
- package/dist/chunk-VBDJM6Z5.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspector/index.js +30 -4
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/viewer/new-app.d.ts.map +1 -1
- package/dist/inspector/viewer/use-open-inspector.d.ts +2 -0
- package/dist/inspector/viewer/use-open-inspector.d.ts.map +1 -0
- package/dist/inspector/viewer/use-page-path.d.ts.map +1 -1
- package/dist/react/index.js +0 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/testing.js +0 -2
- package/dist/react/testing.js.map +1 -1
- package/dist/react-native-core/index.js +2 -18
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/media.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/coFeed.d.ts +9 -0
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +98 -2
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +3 -0
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +12 -0
- 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/subscribe/CoValueCoreSubscription.d.ts +2 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts +2 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/inspector/viewer/new-app.tsx +2 -1
- package/src/inspector/viewer/use-open-inspector.ts +18 -0
- package/src/inspector/viewer/use-page-path.ts +14 -1
- package/src/react-native-core/media.tsx +2 -22
- package/src/tools/coValues/coFeed.ts +38 -0
- package/src/tools/coValues/coMap.ts +118 -14
- package/src/tools/coValues/interfaces.ts +14 -4
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +38 -0
- package/src/tools/implementation/zodSchema/zodCo.ts +6 -0
- package/src/tools/subscribe/CoValueCoreSubscription.ts +12 -9
- package/src/tools/subscribe/SubscriptionScope.ts +31 -19
- package/src/tools/tests/coFeed.test.ts +69 -0
- package/src/tools/tests/coMap.test.ts +480 -4
- package/src/tools/tests/load.test.ts +2 -1
- package/dist/chunk-FSIM7N33.js.map +0 -1
@@ -1,3 +1,4 @@
|
|
1
|
+
import { cojsonInternals } from "cojson";
|
1
2
|
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
2
3
|
import {
|
3
4
|
assert,
|
@@ -11,13 +12,19 @@ import {
|
|
11
12
|
} from "vitest";
|
12
13
|
import { Group, co, subscribeToCoValue, z } from "../exports.js";
|
13
14
|
import { Account } from "../index.js";
|
14
|
-
import { Loaded, zodSchemaToCoSchema } from "../internal.js";
|
15
|
-
import {
|
15
|
+
import { ID, Loaded, zodSchemaToCoSchema } from "../internal.js";
|
16
|
+
import {
|
17
|
+
createJazzTestAccount,
|
18
|
+
getPeerConnectedToTestSyncServer,
|
19
|
+
setupJazzTestSync,
|
20
|
+
} from "../testing.js";
|
16
21
|
import { setupTwoNodes, waitFor } from "./utils.js";
|
17
22
|
|
18
23
|
const Crypto = await WasmCrypto.create();
|
19
24
|
|
20
25
|
beforeEach(async () => {
|
26
|
+
cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 1000;
|
27
|
+
|
21
28
|
await setupJazzTestSync();
|
22
29
|
|
23
30
|
await createJazzTestAccount({
|
@@ -543,6 +550,115 @@ describe("CoMap resolution", async () => {
|
|
543
550
|
expect(loadedPerson.dog?.name).toEqual("Rex");
|
544
551
|
});
|
545
552
|
|
553
|
+
test("loading a remotely available map with skipRetry set to true", async () => {
|
554
|
+
// Make the retry delay extra long to ensure that it's not used
|
555
|
+
cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 100_000_000;
|
556
|
+
|
557
|
+
const Dog = co.map({
|
558
|
+
name: z.string(),
|
559
|
+
breed: z.string(),
|
560
|
+
});
|
561
|
+
|
562
|
+
const Person = co.map({
|
563
|
+
name: z.string(),
|
564
|
+
age: z.number(),
|
565
|
+
dog: Dog,
|
566
|
+
});
|
567
|
+
|
568
|
+
const currentAccount = Account.getMe();
|
569
|
+
|
570
|
+
// Disconnect the current account
|
571
|
+
currentAccount._raw.core.node.syncManager.getPeers().forEach((peer) => {
|
572
|
+
peer.gracefulShutdown();
|
573
|
+
});
|
574
|
+
|
575
|
+
const group = Group.create();
|
576
|
+
group.addMember("everyone", "writer");
|
577
|
+
|
578
|
+
const person = Person.create(
|
579
|
+
{
|
580
|
+
name: "John",
|
581
|
+
age: 20,
|
582
|
+
dog: Dog.create({ name: "Rex", breed: "Labrador" }, group),
|
583
|
+
},
|
584
|
+
group,
|
585
|
+
);
|
586
|
+
|
587
|
+
const userB = await createJazzTestAccount();
|
588
|
+
|
589
|
+
// We expect that the test doesn't hang here and immediately returns null
|
590
|
+
const loadedPerson = await Person.load(person.id, {
|
591
|
+
loadAs: userB,
|
592
|
+
skipRetry: true,
|
593
|
+
});
|
594
|
+
|
595
|
+
expect(loadedPerson).toBeNull();
|
596
|
+
});
|
597
|
+
|
598
|
+
test("loading a remotely available map with skipRetry set to false", async () => {
|
599
|
+
// Make the retry delay extra long to avoid flakyness in the resolved checks
|
600
|
+
cojsonInternals.CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 100_000_000;
|
601
|
+
|
602
|
+
const Dog = co.map({
|
603
|
+
name: z.string(),
|
604
|
+
breed: z.string(),
|
605
|
+
});
|
606
|
+
|
607
|
+
const Person = co.map({
|
608
|
+
name: z.string(),
|
609
|
+
age: z.number(),
|
610
|
+
dog: Dog,
|
611
|
+
});
|
612
|
+
|
613
|
+
const currentAccount = Account.getMe();
|
614
|
+
|
615
|
+
// Disconnect the current account
|
616
|
+
currentAccount._raw.core.node.syncManager.getPeers().forEach((peer) => {
|
617
|
+
peer.gracefulShutdown();
|
618
|
+
});
|
619
|
+
|
620
|
+
const group = Group.create();
|
621
|
+
group.addMember("everyone", "writer");
|
622
|
+
|
623
|
+
const person = Person.create(
|
624
|
+
{
|
625
|
+
name: "John",
|
626
|
+
age: 20,
|
627
|
+
dog: Dog.create({ name: "Rex", breed: "Labrador" }, group),
|
628
|
+
},
|
629
|
+
group,
|
630
|
+
);
|
631
|
+
|
632
|
+
const userB = await createJazzTestAccount();
|
633
|
+
let resolved = false;
|
634
|
+
const promise = Person.load(person.id, {
|
635
|
+
loadAs: userB,
|
636
|
+
skipRetry: false,
|
637
|
+
});
|
638
|
+
promise.then(() => {
|
639
|
+
resolved = true;
|
640
|
+
});
|
641
|
+
|
642
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
643
|
+
|
644
|
+
expect(resolved).toBe(false);
|
645
|
+
|
646
|
+
// Reconnect the current account
|
647
|
+
currentAccount._raw.core.node.syncManager.addPeer(
|
648
|
+
getPeerConnectedToTestSyncServer(),
|
649
|
+
);
|
650
|
+
|
651
|
+
const loadedPerson = await promise;
|
652
|
+
|
653
|
+
expect(resolved).toBe(true);
|
654
|
+
assert(loadedPerson);
|
655
|
+
expect(loadedPerson.dog).toBe(null);
|
656
|
+
|
657
|
+
await waitFor(() => expect(loadedPerson.dog).toBeTruthy());
|
658
|
+
|
659
|
+
expect(loadedPerson.dog?.name).toEqual("Rex");
|
660
|
+
});
|
661
|
+
|
546
662
|
test("accessing the value refs", async () => {
|
547
663
|
const Dog = co.map({
|
548
664
|
name: z.string(),
|
@@ -1197,8 +1313,368 @@ describe("Creating and finding unique CoMaps", async () => {
|
|
1197
1313
|
{ owner: group, unique: { name: "Alice" } },
|
1198
1314
|
);
|
1199
1315
|
|
1200
|
-
const foundAlice = Person.
|
1201
|
-
expect(foundAlice).toEqual(alice
|
1316
|
+
const foundAlice = await Person.loadUnique({ name: "Alice" }, group.id);
|
1317
|
+
expect(foundAlice).toEqual(alice);
|
1318
|
+
});
|
1319
|
+
|
1320
|
+
test("manual upserting pattern", async () => {
|
1321
|
+
// Schema
|
1322
|
+
const Event = co.map({
|
1323
|
+
title: z.string(),
|
1324
|
+
identifier: z.string(),
|
1325
|
+
external_id: z.string(),
|
1326
|
+
});
|
1327
|
+
|
1328
|
+
// Data
|
1329
|
+
const sourceData = {
|
1330
|
+
title: "Test Event Title",
|
1331
|
+
identifier: "test-event-identifier",
|
1332
|
+
_id: "test-event-external-id",
|
1333
|
+
};
|
1334
|
+
const workspace = Group.create();
|
1335
|
+
|
1336
|
+
// Pattern
|
1337
|
+
let activeEvent = await Event.loadUnique(
|
1338
|
+
{ identifier: sourceData.identifier },
|
1339
|
+
workspace.id,
|
1340
|
+
);
|
1341
|
+
if (!activeEvent) {
|
1342
|
+
activeEvent = Event.create(
|
1343
|
+
{
|
1344
|
+
title: sourceData.title,
|
1345
|
+
identifier: sourceData.identifier,
|
1346
|
+
external_id: sourceData._id,
|
1347
|
+
},
|
1348
|
+
workspace,
|
1349
|
+
);
|
1350
|
+
} else {
|
1351
|
+
activeEvent.applyDiff({
|
1352
|
+
title: sourceData.title,
|
1353
|
+
identifier: sourceData.identifier,
|
1354
|
+
external_id: sourceData._id,
|
1355
|
+
});
|
1356
|
+
}
|
1357
|
+
expect(activeEvent).toEqual({
|
1358
|
+
title: sourceData.title,
|
1359
|
+
identifier: sourceData.identifier,
|
1360
|
+
external_id: sourceData._id,
|
1361
|
+
});
|
1362
|
+
});
|
1363
|
+
|
1364
|
+
test("upserting a non-existent value", async () => {
|
1365
|
+
// Schema
|
1366
|
+
const Event = co.map({
|
1367
|
+
title: z.string(),
|
1368
|
+
identifier: z.string(),
|
1369
|
+
external_id: z.string(),
|
1370
|
+
});
|
1371
|
+
|
1372
|
+
// Data
|
1373
|
+
const sourceData = {
|
1374
|
+
title: "Test Event Title",
|
1375
|
+
identifier: "test-event-identifier",
|
1376
|
+
_id: "test-event-external-id",
|
1377
|
+
};
|
1378
|
+
const workspace = Group.create();
|
1379
|
+
|
1380
|
+
// Upserting
|
1381
|
+
const activeEvent = await Event.upsertUnique({
|
1382
|
+
value: {
|
1383
|
+
title: sourceData.title,
|
1384
|
+
identifier: sourceData.identifier,
|
1385
|
+
external_id: sourceData._id,
|
1386
|
+
},
|
1387
|
+
unique: sourceData.identifier,
|
1388
|
+
owner: workspace,
|
1389
|
+
});
|
1390
|
+
expect(activeEvent).toEqual({
|
1391
|
+
title: sourceData.title,
|
1392
|
+
identifier: sourceData.identifier,
|
1393
|
+
external_id: sourceData._id,
|
1394
|
+
});
|
1395
|
+
});
|
1396
|
+
|
1397
|
+
test("upserting an existing value", async () => {
|
1398
|
+
// Schema
|
1399
|
+
const Event = co.map({
|
1400
|
+
title: z.string(),
|
1401
|
+
identifier: z.string(),
|
1402
|
+
external_id: z.string(),
|
1403
|
+
});
|
1404
|
+
|
1405
|
+
// Data
|
1406
|
+
const oldSourceData = {
|
1407
|
+
title: "Old Event Title",
|
1408
|
+
identifier: "test-event-identifier",
|
1409
|
+
_id: "test-event-external-id",
|
1410
|
+
};
|
1411
|
+
const newSourceData = {
|
1412
|
+
title: "New Event Title",
|
1413
|
+
identifier: "test-event-identifier",
|
1414
|
+
_id: "test-event-external-id",
|
1415
|
+
};
|
1416
|
+
expect(oldSourceData.identifier).toEqual(newSourceData.identifier);
|
1417
|
+
const workspace = Group.create();
|
1418
|
+
const oldActiveEvent = Event.create(
|
1419
|
+
{
|
1420
|
+
title: oldSourceData.title,
|
1421
|
+
identifier: oldSourceData.identifier,
|
1422
|
+
external_id: oldSourceData._id,
|
1423
|
+
},
|
1424
|
+
workspace,
|
1425
|
+
);
|
1426
|
+
|
1427
|
+
// Upserting
|
1428
|
+
const activeEvent = await Event.upsertUnique({
|
1429
|
+
value: {
|
1430
|
+
title: newSourceData.title,
|
1431
|
+
identifier: newSourceData.identifier,
|
1432
|
+
external_id: newSourceData._id,
|
1433
|
+
},
|
1434
|
+
unique: newSourceData.identifier,
|
1435
|
+
owner: workspace,
|
1436
|
+
});
|
1437
|
+
expect(activeEvent).toEqual({
|
1438
|
+
title: newSourceData.title,
|
1439
|
+
identifier: newSourceData.identifier,
|
1440
|
+
external_id: newSourceData._id,
|
1441
|
+
});
|
1442
|
+
expect(activeEvent).not.toEqual(oldActiveEvent);
|
1443
|
+
});
|
1444
|
+
|
1445
|
+
test("upserting a non-existent value with resolve", async () => {
|
1446
|
+
const Project = co.map({
|
1447
|
+
name: z.string(),
|
1448
|
+
});
|
1449
|
+
const Organisation = co.map({
|
1450
|
+
name: z.string(),
|
1451
|
+
projects: co.list(Project),
|
1452
|
+
});
|
1453
|
+
const workspace = Group.create();
|
1454
|
+
|
1455
|
+
const myOrg = await Organisation.upsertUnique({
|
1456
|
+
value: {
|
1457
|
+
name: "My organisation",
|
1458
|
+
projects: co.list(Project).create(
|
1459
|
+
[
|
1460
|
+
Project.create(
|
1461
|
+
{
|
1462
|
+
name: "My project",
|
1463
|
+
},
|
1464
|
+
workspace,
|
1465
|
+
),
|
1466
|
+
],
|
1467
|
+
workspace,
|
1468
|
+
),
|
1469
|
+
},
|
1470
|
+
unique: { name: "My organisation" },
|
1471
|
+
owner: workspace,
|
1472
|
+
resolve: {
|
1473
|
+
projects: {
|
1474
|
+
$each: true,
|
1475
|
+
},
|
1476
|
+
},
|
1477
|
+
});
|
1478
|
+
assert(myOrg);
|
1479
|
+
expect(myOrg).not.toBeNull();
|
1480
|
+
expect(myOrg.name).toEqual("My organisation");
|
1481
|
+
expect(myOrg.projects.length).toBe(1);
|
1482
|
+
expect(myOrg.projects[0]).toMatchObject({
|
1483
|
+
name: "My project",
|
1484
|
+
});
|
1485
|
+
});
|
1486
|
+
|
1487
|
+
test("upserting an existing value with resolve", async () => {
|
1488
|
+
const Project = co.map({
|
1489
|
+
name: z.string(),
|
1490
|
+
});
|
1491
|
+
const Organisation = co.map({
|
1492
|
+
name: z.string(),
|
1493
|
+
projects: co.list(Project),
|
1494
|
+
});
|
1495
|
+
const workspace = Group.create();
|
1496
|
+
const initialProject = await Project.upsertUnique({
|
1497
|
+
value: {
|
1498
|
+
name: "My project",
|
1499
|
+
},
|
1500
|
+
unique: { unique: "First project" },
|
1501
|
+
owner: workspace,
|
1502
|
+
});
|
1503
|
+
assert(initialProject);
|
1504
|
+
expect(initialProject).not.toBeNull();
|
1505
|
+
expect(initialProject.name).toEqual("My project");
|
1506
|
+
|
1507
|
+
const myOrg = await Organisation.upsertUnique({
|
1508
|
+
value: {
|
1509
|
+
name: "My organisation",
|
1510
|
+
projects: co.list(Project).create([initialProject], workspace),
|
1511
|
+
},
|
1512
|
+
unique: { name: "My organisation" },
|
1513
|
+
owner: workspace,
|
1514
|
+
resolve: {
|
1515
|
+
projects: {
|
1516
|
+
$each: true,
|
1517
|
+
},
|
1518
|
+
},
|
1519
|
+
});
|
1520
|
+
assert(myOrg);
|
1521
|
+
expect(myOrg).not.toBeNull();
|
1522
|
+
expect(myOrg.name).toEqual("My organisation");
|
1523
|
+
expect(myOrg.projects.length).toBe(1);
|
1524
|
+
expect(myOrg.projects.at(0)?.name).toEqual("My project");
|
1525
|
+
|
1526
|
+
const updatedProject = await Project.upsertUnique({
|
1527
|
+
value: {
|
1528
|
+
name: "My updated project",
|
1529
|
+
},
|
1530
|
+
unique: { unique: "First project" },
|
1531
|
+
owner: workspace,
|
1532
|
+
});
|
1533
|
+
|
1534
|
+
assert(updatedProject);
|
1535
|
+
expect(updatedProject).not.toBeNull();
|
1536
|
+
expect(updatedProject).toEqual(initialProject);
|
1537
|
+
expect(updatedProject.name).toEqual("My updated project");
|
1538
|
+
expect(myOrg.projects.length).toBe(1);
|
1539
|
+
expect(myOrg.projects.at(0)?.name).toEqual("My updated project");
|
1540
|
+
});
|
1541
|
+
|
1542
|
+
test("upserting a partially loaded value on an new value with resolve", async () => {
|
1543
|
+
const Project = co.map({
|
1544
|
+
name: z.string(),
|
1545
|
+
});
|
1546
|
+
const Organisation = co.map({
|
1547
|
+
name: z.string(),
|
1548
|
+
projects: co.list(Project),
|
1549
|
+
});
|
1550
|
+
const publicAccess = Group.create();
|
1551
|
+
publicAccess.addMember("everyone", "writer");
|
1552
|
+
|
1553
|
+
const initialProject = await Project.upsertUnique({
|
1554
|
+
value: {
|
1555
|
+
name: "My project",
|
1556
|
+
},
|
1557
|
+
unique: { unique: "First project" },
|
1558
|
+
owner: publicAccess,
|
1559
|
+
});
|
1560
|
+
assert(initialProject);
|
1561
|
+
expect(initialProject).not.toBeNull();
|
1562
|
+
expect(initialProject.name).toEqual("My project");
|
1563
|
+
|
1564
|
+
const fullProjectList = co
|
1565
|
+
.list(Project)
|
1566
|
+
.create([initialProject], publicAccess);
|
1567
|
+
|
1568
|
+
const account = await createJazzTestAccount({
|
1569
|
+
isCurrentActiveAccount: true,
|
1570
|
+
});
|
1571
|
+
|
1572
|
+
const shallowProjectList = await co.list(Project).load(fullProjectList.id, {
|
1573
|
+
loadAs: account,
|
1574
|
+
});
|
1575
|
+
assert(shallowProjectList);
|
1576
|
+
|
1577
|
+
const publicAccessAsNewAccount = await Group.load(publicAccess.id, {
|
1578
|
+
loadAs: account,
|
1579
|
+
});
|
1580
|
+
assert(publicAccessAsNewAccount);
|
1581
|
+
|
1582
|
+
const updatedOrg = await Organisation.upsertUnique({
|
1583
|
+
value: {
|
1584
|
+
name: "My organisation",
|
1585
|
+
projects: shallowProjectList,
|
1586
|
+
},
|
1587
|
+
unique: { name: "My organisation" },
|
1588
|
+
owner: publicAccessAsNewAccount,
|
1589
|
+
resolve: {
|
1590
|
+
projects: {
|
1591
|
+
$each: true,
|
1592
|
+
},
|
1593
|
+
},
|
1594
|
+
});
|
1595
|
+
|
1596
|
+
assert(updatedOrg);
|
1597
|
+
|
1598
|
+
expect(updatedOrg.projects.id).toEqual(fullProjectList.id);
|
1599
|
+
expect(updatedOrg.projects.length).toBe(1);
|
1600
|
+
expect(updatedOrg.projects.at(0)?.name).toEqual("My project");
|
1601
|
+
});
|
1602
|
+
|
1603
|
+
test("upserting a partially loaded value on an existing value with resolve", async () => {
|
1604
|
+
const Project = co.map({
|
1605
|
+
name: z.string(),
|
1606
|
+
});
|
1607
|
+
const Organisation = co.map({
|
1608
|
+
name: z.string(),
|
1609
|
+
projects: co.list(Project),
|
1610
|
+
});
|
1611
|
+
const publicAccess = Group.create();
|
1612
|
+
publicAccess.addMember("everyone", "writer");
|
1613
|
+
|
1614
|
+
const initialProject = await Project.upsertUnique({
|
1615
|
+
value: {
|
1616
|
+
name: "My project",
|
1617
|
+
},
|
1618
|
+
unique: { unique: "First project" },
|
1619
|
+
owner: publicAccess,
|
1620
|
+
});
|
1621
|
+
assert(initialProject);
|
1622
|
+
expect(initialProject).not.toBeNull();
|
1623
|
+
expect(initialProject.name).toEqual("My project");
|
1624
|
+
|
1625
|
+
const myOrg = await Organisation.upsertUnique({
|
1626
|
+
value: {
|
1627
|
+
name: "My organisation",
|
1628
|
+
projects: co.list(Project).create([], publicAccess),
|
1629
|
+
},
|
1630
|
+
unique: { name: "My organisation" },
|
1631
|
+
owner: publicAccess,
|
1632
|
+
resolve: {
|
1633
|
+
projects: {
|
1634
|
+
$each: true,
|
1635
|
+
},
|
1636
|
+
},
|
1637
|
+
});
|
1638
|
+
assert(myOrg);
|
1639
|
+
|
1640
|
+
const fullProjectList = co
|
1641
|
+
.list(Project)
|
1642
|
+
.create([initialProject], publicAccess);
|
1643
|
+
|
1644
|
+
const account = await createJazzTestAccount({
|
1645
|
+
isCurrentActiveAccount: true,
|
1646
|
+
});
|
1647
|
+
|
1648
|
+
const shallowProjectList = await co.list(Project).load(fullProjectList.id, {
|
1649
|
+
loadAs: account,
|
1650
|
+
});
|
1651
|
+
assert(shallowProjectList);
|
1652
|
+
|
1653
|
+
const publicAccessAsNewAccount = await Group.load(publicAccess.id, {
|
1654
|
+
loadAs: account,
|
1655
|
+
});
|
1656
|
+
assert(publicAccessAsNewAccount);
|
1657
|
+
|
1658
|
+
const updatedOrg = await Organisation.upsertUnique({
|
1659
|
+
value: {
|
1660
|
+
name: "My organisation",
|
1661
|
+
projects: shallowProjectList,
|
1662
|
+
},
|
1663
|
+
unique: { name: "My organisation" },
|
1664
|
+
owner: publicAccessAsNewAccount,
|
1665
|
+
resolve: {
|
1666
|
+
projects: {
|
1667
|
+
$each: true,
|
1668
|
+
},
|
1669
|
+
},
|
1670
|
+
});
|
1671
|
+
|
1672
|
+
assert(updatedOrg);
|
1673
|
+
|
1674
|
+
expect(updatedOrg.projects.id).toEqual(fullProjectList.id);
|
1675
|
+
expect(updatedOrg.projects.length).toBe(1);
|
1676
|
+
expect(updatedOrg.projects.at(0)?.name).toEqual("My project");
|
1677
|
+
expect(updatedOrg.id).toEqual(myOrg.id);
|
1202
1678
|
});
|
1203
1679
|
|
1204
1680
|
test("complex discriminated union", () => {
|
@@ -30,7 +30,7 @@ test("load a value", async () => {
|
|
30
30
|
expect(john?.name).toBe("John");
|
31
31
|
});
|
32
32
|
|
33
|
-
test("retry an unavailable
|
33
|
+
test("retry an unavailable value", async () => {
|
34
34
|
const Person = co.map({
|
35
35
|
name: z.string(),
|
36
36
|
});
|
@@ -69,6 +69,7 @@ test("retry an unavailable a value", async () => {
|
|
69
69
|
);
|
70
70
|
|
71
71
|
const john = await promise;
|
72
|
+
expect(resolved).toBe(true);
|
72
73
|
expect(john).not.toBeNull();
|
73
74
|
expect(john?.name).toBe("John");
|
74
75
|
});
|