jazz-tools 0.18.29 → 0.18.31
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/.svelte-kit/__package__/media/image.svelte +7 -4
- package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/media/image.types.d.ts +1 -0
- package/.svelte-kit/__package__/media/image.types.d.ts.map +1 -1
- package/.svelte-kit/__package__/tests/media/image.svelte.test.js +63 -0
- package/.turbo/turbo-build.log +60 -60
- package/CHANGELOG.md +26 -0
- package/dist/better-auth/auth/client.d.ts +1 -1
- package/dist/better-auth/auth/server.d.ts +1 -1
- package/dist/better-auth/auth/server.d.ts.map +1 -1
- package/dist/better-auth/auth/server.js.map +1 -1
- package/dist/better-auth/database-adapter/index.d.ts +3 -3
- package/dist/better-auth/database-adapter/index.d.ts.map +1 -1
- package/dist/better-auth/database-adapter/index.js +6 -2
- package/dist/better-auth/database-adapter/index.js.map +1 -1
- package/dist/better-auth/database-adapter/utils.d.ts.map +1 -1
- package/dist/browser/index.d.ts +2 -1
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/{chunk-F55R554M.js → chunk-6BIYT3KH.js} +51 -30
- package/dist/chunk-6BIYT3KH.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspector/{custom-element-35MDW4SW.js → custom-element-RQTLPAPJ.js} +584 -298
- package/dist/inspector/custom-element-RQTLPAPJ.js.map +1 -0
- package/dist/inspector/index.js +570 -338
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/inspector/ui/index.d.ts +6 -0
- package/dist/inspector/ui/index.d.ts.map +1 -0
- package/dist/inspector/viewer/group-view.d.ts +3 -2
- package/dist/inspector/viewer/group-view.d.ts.map +1 -1
- package/dist/inspector/viewer/page.d.ts.map +1 -1
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/media/image.d.ts +8 -0
- package/dist/react/media/image.d.ts.map +1 -1
- package/dist/react-native-core/index.js +3 -3
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/react-native-core/media/image.d.ts +15 -0
- package/dist/react-native-core/media/image.d.ts.map +1 -1
- package/dist/svelte/media/image.svelte +7 -4
- package/dist/svelte/media/image.svelte.d.ts.map +1 -1
- package/dist/svelte/media/image.types.d.ts +1 -0
- package/dist/svelte/media/image.types.d.ts.map +1 -1
- package/dist/svelte/tests/media/image.svelte.test.js +63 -0
- package/dist/testing.js +8 -1
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/account.d.ts +1 -0
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/group.d.ts +3 -3
- package/dist/tools/coValues/group.d.ts.map +1 -1
- package/dist/tools/implementation/invites.d.ts +2 -2
- package/dist/tools/implementation/invites.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts +3 -1
- package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodReExport.d.ts +1 -1
- package/dist/tools/implementation/zodSchema/zodReExport.d.ts.map +1 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts +0 -2
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/testing.d.ts +1 -0
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/CoValueCoreSubscription.test.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/better-auth/auth/server.ts +7 -2
- package/src/better-auth/auth/tests/server.test.ts +39 -17
- package/src/better-auth/database-adapter/index.ts +8 -5
- package/src/better-auth/database-adapter/utils.ts +4 -0
- package/src/browser/index.ts +2 -1
- package/src/inspector/ui/index.ts +5 -0
- package/src/inspector/viewer/group-view.tsx +304 -20
- package/src/inspector/viewer/new-app.tsx +4 -4
- package/src/inspector/viewer/page.tsx +16 -2
- package/src/react/media/image.tsx +11 -2
- package/src/react/tests/media/image.test.tsx +94 -0
- package/src/react-native-core/media/image.tsx +11 -3
- package/src/svelte/media/image.svelte +7 -4
- package/src/svelte/media/image.types.ts +1 -0
- package/src/svelte/tests/media/image.svelte.test.ts +85 -0
- package/src/tools/coValues/account.ts +30 -5
- package/src/tools/coValues/group.ts +13 -12
- package/src/tools/coValues/inbox.ts +5 -5
- package/src/tools/implementation/invites.ts +3 -8
- package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +5 -1
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +2 -0
- package/src/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.ts +63 -50
- package/src/tools/implementation/zodSchema/zodReExport.ts +2 -2
- package/src/tools/subscribe/CoValueCoreSubscription.ts +17 -0
- package/src/tools/subscribe/SubscriptionScope.ts +1 -27
- package/src/tools/testing.ts +7 -0
- package/src/tools/{subscribe → tests}/CoValueCoreSubscription.test.ts +233 -3
- package/src/tools/tests/coFeed.branch.test.ts +14 -5
- package/src/tools/tests/coMap.test.ts +139 -42
- package/src/tools/tests/coOptional.test.ts +9 -1
- package/src/tools/tests/groupsAndAccounts.test.ts +156 -1
- package/src/tools/tests/load.test.ts +198 -1
- package/src/tools/tests/zod.test-d.ts +0 -2
- package/src/tools/tests/zod.test.ts +43 -40
- package/dist/chunk-F55R554M.js.map +0 -1
- package/dist/inspector/custom-element-35MDW4SW.js.map +0 -1
- package/dist/tools/subscribe/CoValueCoreSubscription.test.d.ts.map +0 -1
- /package/dist/tools/{subscribe → tests}/CoValueCoreSubscription.test.d.ts +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
-
import { Group, co, z } from "../exports.js";
|
|
3
|
-
import { CoValueCoreSubscription } from "
|
|
1
|
+
import { assert, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { Group, co, exportCoValue, z } from "../exports.js";
|
|
3
|
+
import { CoValueCoreSubscription } from "../subscribe/CoValueCoreSubscription.js";
|
|
4
4
|
import {
|
|
5
5
|
createJazzTestAccount,
|
|
6
|
+
disableJazzTestSync,
|
|
6
7
|
getPeerConnectedToTestSyncServer,
|
|
7
8
|
setupJazzTestSync,
|
|
8
9
|
} from "../testing.js";
|
|
@@ -1100,4 +1101,233 @@ describe("CoValueCoreSubscription", async () => {
|
|
|
1100
1101
|
subscription.unsubscribe();
|
|
1101
1102
|
});
|
|
1102
1103
|
});
|
|
1104
|
+
|
|
1105
|
+
test("should wait for the full streaming", async () => {
|
|
1106
|
+
disableJazzTestSync();
|
|
1107
|
+
|
|
1108
|
+
const alice = await createJazzTestAccount({
|
|
1109
|
+
isCurrentActiveAccount: true,
|
|
1110
|
+
creationProps: { name: "Hermes Puggington" },
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
const Person = co.map({
|
|
1114
|
+
name: z.string(),
|
|
1115
|
+
update: z.number(),
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
const group = Group.create();
|
|
1119
|
+
|
|
1120
|
+
const person = Person.create(
|
|
1121
|
+
{
|
|
1122
|
+
name: "Bob",
|
|
1123
|
+
update: 1,
|
|
1124
|
+
},
|
|
1125
|
+
group,
|
|
1126
|
+
);
|
|
1127
|
+
|
|
1128
|
+
for (let i = 0; i <= 100; i++) {
|
|
1129
|
+
person.$jazz.applyDiff({
|
|
1130
|
+
name: "1".repeat(1024),
|
|
1131
|
+
update: i,
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
const bob = await createJazzTestAccount({
|
|
1136
|
+
isCurrentActiveAccount: true,
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
const personContent = await exportCoValue(Person, person.$jazz.id, {
|
|
1140
|
+
loadAs: alice,
|
|
1141
|
+
});
|
|
1142
|
+
assert(personContent);
|
|
1143
|
+
|
|
1144
|
+
const lastPiece = personContent.pop();
|
|
1145
|
+
assert(lastPiece);
|
|
1146
|
+
|
|
1147
|
+
for (const content of personContent) {
|
|
1148
|
+
bob.$jazz.localNode.syncManager.handleNewContent(content, "import");
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
// Simulate the streaming delay on the last piece of the group
|
|
1152
|
+
setTimeout(() => {
|
|
1153
|
+
bob.$jazz.localNode.syncManager.handleNewContent(lastPiece, "import");
|
|
1154
|
+
}, 10);
|
|
1155
|
+
|
|
1156
|
+
// Load the value and expect the migration to run only once
|
|
1157
|
+
// Subscribe to the person
|
|
1158
|
+
let lastResult: any = null;
|
|
1159
|
+
const listener = vi.fn();
|
|
1160
|
+
const subscription = new CoValueCoreSubscription(
|
|
1161
|
+
person.$jazz.localNode,
|
|
1162
|
+
person.$jazz.id,
|
|
1163
|
+
(result) => {
|
|
1164
|
+
lastResult = result;
|
|
1165
|
+
listener(result);
|
|
1166
|
+
},
|
|
1167
|
+
);
|
|
1168
|
+
|
|
1169
|
+
await waitFor(() => expect(listener).toHaveBeenCalled());
|
|
1170
|
+
|
|
1171
|
+
expect(lastResult.core.isCompletelyDownloaded()).toBe(true);
|
|
1172
|
+
|
|
1173
|
+
subscription.unsubscribe();
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
test("should wait for the full streaming of the group", async () => {
|
|
1177
|
+
disableJazzTestSync();
|
|
1178
|
+
|
|
1179
|
+
const alice = await createJazzTestAccount({
|
|
1180
|
+
isCurrentActiveAccount: true,
|
|
1181
|
+
creationProps: { name: "Hermes Puggington" },
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
const Person = co.map({
|
|
1185
|
+
name: z.string(),
|
|
1186
|
+
update: z.number(),
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
const group = Group.create();
|
|
1190
|
+
|
|
1191
|
+
const person = Person.create(
|
|
1192
|
+
{
|
|
1193
|
+
name: "Bob",
|
|
1194
|
+
update: 1,
|
|
1195
|
+
},
|
|
1196
|
+
group,
|
|
1197
|
+
);
|
|
1198
|
+
|
|
1199
|
+
// Make the group to grow big enough to trigger the streaming
|
|
1200
|
+
for (let i = 0; i <= 300; i++) {
|
|
1201
|
+
group.$jazz.raw.rotateReadKey();
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
group.addMember("everyone", "reader");
|
|
1205
|
+
|
|
1206
|
+
const bob = await createJazzTestAccount({
|
|
1207
|
+
isCurrentActiveAccount: true,
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
const personContent = await exportCoValue(Person, person.$jazz.id, {
|
|
1211
|
+
loadAs: alice,
|
|
1212
|
+
});
|
|
1213
|
+
assert(personContent);
|
|
1214
|
+
|
|
1215
|
+
const lastGroupPiece = personContent.findLast(
|
|
1216
|
+
(content) => content.id === group.$jazz.id,
|
|
1217
|
+
);
|
|
1218
|
+
assert(lastGroupPiece);
|
|
1219
|
+
|
|
1220
|
+
for (const content of personContent.filter(
|
|
1221
|
+
(content) => content !== lastGroupPiece,
|
|
1222
|
+
)) {
|
|
1223
|
+
bob.$jazz.localNode.syncManager.handleNewContent(content, "import");
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// Simulate the streaming delay on the last piece of the group
|
|
1227
|
+
setTimeout(() => {
|
|
1228
|
+
bob.$jazz.localNode.syncManager.handleNewContent(
|
|
1229
|
+
lastGroupPiece,
|
|
1230
|
+
"import",
|
|
1231
|
+
);
|
|
1232
|
+
}, 10);
|
|
1233
|
+
|
|
1234
|
+
// Load the value and expect the migration to run only once
|
|
1235
|
+
// Subscribe to the person
|
|
1236
|
+
let lastResult: any = null;
|
|
1237
|
+
const listener = vi.fn();
|
|
1238
|
+
const subscription = new CoValueCoreSubscription(
|
|
1239
|
+
person.$jazz.localNode,
|
|
1240
|
+
person.$jazz.id,
|
|
1241
|
+
(result) => {
|
|
1242
|
+
lastResult = result;
|
|
1243
|
+
listener(result);
|
|
1244
|
+
},
|
|
1245
|
+
);
|
|
1246
|
+
|
|
1247
|
+
await waitFor(() => expect(listener).toHaveBeenCalled());
|
|
1248
|
+
|
|
1249
|
+
expect(lastResult.core.isCompletelyDownloaded()).toBe(true);
|
|
1250
|
+
|
|
1251
|
+
subscription.unsubscribe();
|
|
1252
|
+
});
|
|
1253
|
+
|
|
1254
|
+
test.skip("should wait for the full streaming of the parent group", async () => {
|
|
1255
|
+
disableJazzTestSync();
|
|
1256
|
+
|
|
1257
|
+
const alice = await createJazzTestAccount({
|
|
1258
|
+
isCurrentActiveAccount: true,
|
|
1259
|
+
creationProps: { name: "Hermes Puggington" },
|
|
1260
|
+
});
|
|
1261
|
+
|
|
1262
|
+
const Person = co.map({
|
|
1263
|
+
name: z.string(),
|
|
1264
|
+
update: z.number(),
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
const group = Group.create();
|
|
1268
|
+
const parentGroup = Group.create();
|
|
1269
|
+
|
|
1270
|
+
const person = Person.create(
|
|
1271
|
+
{
|
|
1272
|
+
name: "Bob",
|
|
1273
|
+
update: 1,
|
|
1274
|
+
},
|
|
1275
|
+
group,
|
|
1276
|
+
);
|
|
1277
|
+
|
|
1278
|
+
// Make the parent group to grow big enough to trigger the streaming
|
|
1279
|
+
for (let i = 0; i <= 300; i++) {
|
|
1280
|
+
parentGroup.$jazz.raw.rotateReadKey();
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
group.addMember(parentGroup);
|
|
1284
|
+
parentGroup.addMember("everyone", "reader");
|
|
1285
|
+
|
|
1286
|
+
const bob = await createJazzTestAccount({
|
|
1287
|
+
isCurrentActiveAccount: true,
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1290
|
+
const personContent = await exportCoValue(Person, person.$jazz.id, {
|
|
1291
|
+
loadAs: alice,
|
|
1292
|
+
});
|
|
1293
|
+
assert(personContent);
|
|
1294
|
+
|
|
1295
|
+
const lastGroupPiece = personContent.findLast(
|
|
1296
|
+
(content) => content.id === parentGroup.$jazz.id,
|
|
1297
|
+
);
|
|
1298
|
+
assert(lastGroupPiece);
|
|
1299
|
+
|
|
1300
|
+
for (const content of personContent.filter(
|
|
1301
|
+
(content) => content !== lastGroupPiece,
|
|
1302
|
+
)) {
|
|
1303
|
+
bob.$jazz.localNode.syncManager.handleNewContent(content, "import");
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// Simulate the streaming delay on the last piece of the group
|
|
1307
|
+
setTimeout(() => {
|
|
1308
|
+
bob.$jazz.localNode.syncManager.handleNewContent(
|
|
1309
|
+
lastGroupPiece,
|
|
1310
|
+
"import",
|
|
1311
|
+
);
|
|
1312
|
+
}, 10);
|
|
1313
|
+
|
|
1314
|
+
// Load the value and expect the migration to run only once
|
|
1315
|
+
// Subscribe to the person
|
|
1316
|
+
let lastResult: any = null;
|
|
1317
|
+
const listener = vi.fn();
|
|
1318
|
+
const subscription = new CoValueCoreSubscription(
|
|
1319
|
+
person.$jazz.localNode,
|
|
1320
|
+
person.$jazz.id,
|
|
1321
|
+
(result) => {
|
|
1322
|
+
lastResult = result;
|
|
1323
|
+
listener(result);
|
|
1324
|
+
},
|
|
1325
|
+
);
|
|
1326
|
+
|
|
1327
|
+
await waitFor(() => expect(listener).toHaveBeenCalled());
|
|
1328
|
+
|
|
1329
|
+
expect(lastResult.core.isCompletelyDownloaded()).toBe(true);
|
|
1330
|
+
|
|
1331
|
+
subscription.unsubscribe();
|
|
1332
|
+
});
|
|
1103
1333
|
});
|
|
@@ -247,6 +247,8 @@ describe("CoFeed Branching", async () => {
|
|
|
247
247
|
Group.create(me).makePublic("writer"),
|
|
248
248
|
);
|
|
249
249
|
|
|
250
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
251
|
+
|
|
250
252
|
const branch = await TestStream.load(originalFeed.$jazz.id, {
|
|
251
253
|
unstable_branch: { name: "double-merge-branch" },
|
|
252
254
|
});
|
|
@@ -258,7 +260,16 @@ describe("CoFeed Branching", async () => {
|
|
|
258
260
|
// First merge
|
|
259
261
|
branch.$jazz.unstable_merge();
|
|
260
262
|
|
|
261
|
-
|
|
263
|
+
const feed = await TestStream.load(originalFeed.$jazz.id);
|
|
264
|
+
assert(feed);
|
|
265
|
+
|
|
266
|
+
if (feed.perAccount[me.$jazz.id]?.value !== "jam") {
|
|
267
|
+
console.log(feed.$jazz.raw.items, feed.perAccount[me.$jazz.id]?.value);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
expect(feed.perAccount[me.$jazz.id]?.value).toEqual("jam");
|
|
271
|
+
|
|
272
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
262
273
|
|
|
263
274
|
// Make more changes to the branch
|
|
264
275
|
branch.$jazz.push("cheese");
|
|
@@ -267,10 +278,8 @@ describe("CoFeed Branching", async () => {
|
|
|
267
278
|
branch.$jazz.unstable_merge();
|
|
268
279
|
|
|
269
280
|
// Verify all changes are applied
|
|
270
|
-
expect(
|
|
271
|
-
expect(
|
|
272
|
-
"cheese",
|
|
273
|
-
);
|
|
281
|
+
expect(feed.perAccount[me.$jazz.id]?.value).toEqual("cheese");
|
|
282
|
+
expect(feed.perSession[me.$jazz.sessionID]?.value).toEqual("cheese");
|
|
274
283
|
});
|
|
275
284
|
|
|
276
285
|
test("two users merge different branches with different edits", async () => {
|
|
@@ -17,9 +17,11 @@ import {
|
|
|
17
17
|
TypeSym,
|
|
18
18
|
activeAccountContext,
|
|
19
19
|
coValueClassFromCoValueClassOrSchema,
|
|
20
|
+
exportCoValue,
|
|
20
21
|
} from "../internal.js";
|
|
21
22
|
import {
|
|
22
23
|
createJazzTestAccount,
|
|
24
|
+
disableJazzTestSync,
|
|
23
25
|
getPeerConnectedToTestSyncServer,
|
|
24
26
|
runWithoutActiveAccount,
|
|
25
27
|
setupJazzTestSync,
|
|
@@ -2101,48 +2103,6 @@ describe("CoMap migration", () => {
|
|
|
2101
2103
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
2102
2104
|
});
|
|
2103
2105
|
|
|
2104
|
-
test("should run only when the value is fully loaded", async () => {
|
|
2105
|
-
await setupJazzTestSync({
|
|
2106
|
-
asyncPeers: true,
|
|
2107
|
-
});
|
|
2108
|
-
await createJazzTestAccount({
|
|
2109
|
-
isCurrentActiveAccount: true,
|
|
2110
|
-
creationProps: { name: "Hermes Puggington" },
|
|
2111
|
-
});
|
|
2112
|
-
|
|
2113
|
-
const migration = vi.fn();
|
|
2114
|
-
const Person = co
|
|
2115
|
-
.map({
|
|
2116
|
-
name: z.string(),
|
|
2117
|
-
update: z.number(),
|
|
2118
|
-
})
|
|
2119
|
-
.withMigration((person) => {
|
|
2120
|
-
migration(person.update);
|
|
2121
|
-
});
|
|
2122
|
-
|
|
2123
|
-
const person = Person.create({
|
|
2124
|
-
name: "Bob",
|
|
2125
|
-
update: 1,
|
|
2126
|
-
});
|
|
2127
|
-
|
|
2128
|
-
// Pump the value to reach streaming
|
|
2129
|
-
for (let i = 0; i <= 300; i++) {
|
|
2130
|
-
person.$jazz.raw.assign({
|
|
2131
|
-
name: "1".repeat(1024),
|
|
2132
|
-
update: i,
|
|
2133
|
-
});
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
// Upload and unmount, to force the streaming download
|
|
2137
|
-
await person.$jazz.waitForSync();
|
|
2138
|
-
person.$jazz.raw.core.unmount();
|
|
2139
|
-
|
|
2140
|
-
// Load the value and expect the migration to run only once
|
|
2141
|
-
await Person.load(person.$jazz.id);
|
|
2142
|
-
expect(migration).toHaveBeenCalledTimes(1);
|
|
2143
|
-
expect(migration).toHaveBeenCalledWith(300);
|
|
2144
|
-
});
|
|
2145
|
-
|
|
2146
2106
|
test("should not break recursive schemas", async () => {
|
|
2147
2107
|
const PersonV1 = co.map({
|
|
2148
2108
|
name: z.string(),
|
|
@@ -2192,6 +2152,143 @@ describe("CoMap migration", () => {
|
|
|
2192
2152
|
expect(loaded?.friend?.name).toEqual("Charlie");
|
|
2193
2153
|
expect(loaded?.friend?.version).toEqual(2);
|
|
2194
2154
|
});
|
|
2155
|
+
|
|
2156
|
+
test("should wait for the full streaming before running the migration", async () => {
|
|
2157
|
+
disableJazzTestSync();
|
|
2158
|
+
const alice = await createJazzTestAccount({
|
|
2159
|
+
isCurrentActiveAccount: true,
|
|
2160
|
+
creationProps: { name: "Hermes Puggington" },
|
|
2161
|
+
});
|
|
2162
|
+
|
|
2163
|
+
const migration = vi.fn();
|
|
2164
|
+
const Person = co
|
|
2165
|
+
.map({
|
|
2166
|
+
name: z.string(),
|
|
2167
|
+
update: z.number(),
|
|
2168
|
+
})
|
|
2169
|
+
.withMigration((person) => {
|
|
2170
|
+
migration(person.update);
|
|
2171
|
+
});
|
|
2172
|
+
|
|
2173
|
+
const person = Person.create({
|
|
2174
|
+
name: "Bob",
|
|
2175
|
+
update: 1,
|
|
2176
|
+
});
|
|
2177
|
+
|
|
2178
|
+
person.$jazz.owner.addMember("everyone", "reader");
|
|
2179
|
+
|
|
2180
|
+
// Pump the value to reach streaming
|
|
2181
|
+
for (let i = 0; i <= 300; i++) {
|
|
2182
|
+
person.$jazz.raw.assign({
|
|
2183
|
+
name: "1".repeat(1024),
|
|
2184
|
+
update: i,
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
const bob = await createJazzTestAccount({
|
|
2189
|
+
isCurrentActiveAccount: true,
|
|
2190
|
+
});
|
|
2191
|
+
|
|
2192
|
+
const personContent = await exportCoValue(Person, person.$jazz.id, {
|
|
2193
|
+
loadAs: alice,
|
|
2194
|
+
});
|
|
2195
|
+
assert(personContent);
|
|
2196
|
+
|
|
2197
|
+
migration.mockClear();
|
|
2198
|
+
|
|
2199
|
+
const lastPiece = personContent.pop();
|
|
2200
|
+
assert(lastPiece);
|
|
2201
|
+
|
|
2202
|
+
for (const content of personContent) {
|
|
2203
|
+
bob.$jazz.localNode.syncManager.handleNewContent(content, "storage");
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
// Simulate the streaming delay on the last piece
|
|
2207
|
+
setTimeout(() => {
|
|
2208
|
+
bob.$jazz.localNode.syncManager.handleNewContent(lastPiece, "storage");
|
|
2209
|
+
}, 10);
|
|
2210
|
+
|
|
2211
|
+
// Load the value and expect the migration to run only once
|
|
2212
|
+
const loadedPerson = await Person.load(person.$jazz.id, { loadAs: bob });
|
|
2213
|
+
assert(loadedPerson);
|
|
2214
|
+
expect(migration).toHaveBeenCalledTimes(1);
|
|
2215
|
+
expect(migration).toHaveBeenCalledWith(300);
|
|
2216
|
+
});
|
|
2217
|
+
|
|
2218
|
+
test("should run only when the group is fully loaded", async () => {
|
|
2219
|
+
disableJazzTestSync();
|
|
2220
|
+
|
|
2221
|
+
const alice = await createJazzTestAccount({
|
|
2222
|
+
isCurrentActiveAccount: true,
|
|
2223
|
+
creationProps: { name: "Hermes Puggington" },
|
|
2224
|
+
});
|
|
2225
|
+
const migration = vi.fn();
|
|
2226
|
+
|
|
2227
|
+
const Person = co
|
|
2228
|
+
.map({
|
|
2229
|
+
name: z.string(),
|
|
2230
|
+
update: z.number(),
|
|
2231
|
+
})
|
|
2232
|
+
.withMigration((person) => {
|
|
2233
|
+
migration({
|
|
2234
|
+
groupStreaming:
|
|
2235
|
+
person.$jazz.owner.$jazz.raw.core.verified.isStreaming(),
|
|
2236
|
+
});
|
|
2237
|
+
});
|
|
2238
|
+
|
|
2239
|
+
const group = Group.create();
|
|
2240
|
+
|
|
2241
|
+
const person = Person.create(
|
|
2242
|
+
{
|
|
2243
|
+
name: "Bob",
|
|
2244
|
+
update: 1,
|
|
2245
|
+
},
|
|
2246
|
+
group,
|
|
2247
|
+
);
|
|
2248
|
+
|
|
2249
|
+
for (let i = 0; i <= 300; i++) {
|
|
2250
|
+
group.$jazz.raw.rotateReadKey();
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
group.addMember("everyone", "reader");
|
|
2254
|
+
|
|
2255
|
+
const bob = await createJazzTestAccount({
|
|
2256
|
+
isCurrentActiveAccount: true,
|
|
2257
|
+
});
|
|
2258
|
+
|
|
2259
|
+
const personContent = await exportCoValue(Person, person.$jazz.id, {
|
|
2260
|
+
loadAs: alice,
|
|
2261
|
+
});
|
|
2262
|
+
assert(personContent);
|
|
2263
|
+
|
|
2264
|
+
// Upload and unmount, to force the streaming download
|
|
2265
|
+
migration.mockClear();
|
|
2266
|
+
|
|
2267
|
+
const lastGroupPiece = personContent.findLast(
|
|
2268
|
+
(content) => content.id === group.$jazz.id,
|
|
2269
|
+
);
|
|
2270
|
+
assert(lastGroupPiece);
|
|
2271
|
+
|
|
2272
|
+
for (const content of personContent.filter(
|
|
2273
|
+
(content) => content !== lastGroupPiece,
|
|
2274
|
+
)) {
|
|
2275
|
+
bob.$jazz.localNode.syncManager.handleNewContent(content, "import");
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
// Simulate the streaming delay on the last piece of the group
|
|
2279
|
+
setTimeout(() => {
|
|
2280
|
+
bob.$jazz.localNode.syncManager.handleNewContent(
|
|
2281
|
+
lastGroupPiece,
|
|
2282
|
+
"import",
|
|
2283
|
+
);
|
|
2284
|
+
}, 10);
|
|
2285
|
+
|
|
2286
|
+
// Load the value and expect the migration to run only once
|
|
2287
|
+
const loadedPerson = await Person.load(person.$jazz.id, { loadAs: bob });
|
|
2288
|
+
assert(loadedPerson);
|
|
2289
|
+
expect(migration).toHaveBeenCalledTimes(1);
|
|
2290
|
+
expect(migration).toHaveBeenCalledWith({ groupStreaming: false });
|
|
2291
|
+
});
|
|
2195
2292
|
});
|
|
2196
2293
|
|
|
2197
2294
|
describe("createdAt & lastUpdatedAt", () => {
|
|
@@ -37,7 +37,7 @@ describe("co.optional", () => {
|
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
test("can use
|
|
40
|
+
test("can use schema.optional() on all CoValue schemas but co.optional()", async () => {
|
|
41
41
|
const Option1 = co.map({ type: z.literal("1") });
|
|
42
42
|
const Option2 = co.map({ type: z.literal("2") });
|
|
43
43
|
const Schema = co.map({
|
|
@@ -49,6 +49,7 @@ describe("co.optional", () => {
|
|
|
49
49
|
map: co.map({ field: z.string() }).optional(),
|
|
50
50
|
list: co.list(z.string()).optional(),
|
|
51
51
|
feed: co.feed(z.string()).optional(),
|
|
52
|
+
account: co.account().optional(),
|
|
52
53
|
union: co.discriminatedUnion("type", [Option1, Option2]).optional(),
|
|
53
54
|
});
|
|
54
55
|
|
|
@@ -62,6 +63,7 @@ describe("co.optional", () => {
|
|
|
62
63
|
expect(schema.map).toBeUndefined();
|
|
63
64
|
expect(schema.list).toBeUndefined();
|
|
64
65
|
expect(schema.feed).toBeUndefined();
|
|
66
|
+
expect(schema.account).toBeUndefined();
|
|
65
67
|
expect(schema.union).toBeUndefined();
|
|
66
68
|
|
|
67
69
|
schema.$jazz.set(
|
|
@@ -91,6 +93,11 @@ describe("co.optional", () => {
|
|
|
91
93
|
);
|
|
92
94
|
schema.$jazz.set("list", Schema.shape.list.innerType.create([]));
|
|
93
95
|
schema.$jazz.set("feed", Schema.shape.feed.innerType.create([]));
|
|
96
|
+
const loadedAccount = await co
|
|
97
|
+
.account()
|
|
98
|
+
.getMe()
|
|
99
|
+
.$jazz.ensureLoaded({ resolve: { profile: true, root: true } });
|
|
100
|
+
schema.$jazz.set("account", loadedAccount);
|
|
94
101
|
schema.$jazz.set("union", Option1.create({ type: "1" }));
|
|
95
102
|
|
|
96
103
|
expect(schema.plainText?.toString()).toEqual("Hello");
|
|
@@ -101,6 +108,7 @@ describe("co.optional", () => {
|
|
|
101
108
|
expect(schema.map?.field).toEqual("hello");
|
|
102
109
|
expect(schema.list).toEqual([]);
|
|
103
110
|
expect(schema.feed).not.toBeUndefined();
|
|
111
|
+
expect(schema.account?.profile.name).toEqual("Hermes Puggington");
|
|
104
112
|
expect(schema.union?.type).toEqual("1");
|
|
105
113
|
});
|
|
106
114
|
|