jazz-tools 0.8.45 → 0.8.49
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +16 -0
- package/dist/{chunk-5WLKIDKU.js → chunk-6OHBW32Q.js} +15 -6
- package/dist/chunk-6OHBW32Q.js.map +1 -0
- package/dist/index.native.js +1 -1
- package/dist/index.web.js +1 -1
- package/package.json +2 -2
- package/src/coValues/account.ts +9 -2
- package/src/coValues/coMap.ts +8 -2
- package/src/implementation/createContext.ts +2 -2
- package/src/tests/coMap.test.ts +9 -6
- package/src/tests/groupsAndAccounts.test.ts +0 -62
- package/src/tests/inbox.test.ts +43 -0
- package/src/tests/utils.ts +2 -2
- package/dist/chunk-5WLKIDKU.js.map +0 -1
package/package.json
CHANGED
package/src/coValues/account.ts
CHANGED
@@ -185,7 +185,7 @@ export class Account extends CoValueBase implements CoValue {
|
|
185
185
|
fromRaw: rawAccount,
|
186
186
|
}) as A;
|
187
187
|
|
188
|
-
await account.
|
188
|
+
await account.applyMigration?.(creationProps);
|
189
189
|
},
|
190
190
|
});
|
191
191
|
|
@@ -236,7 +236,7 @@ export class Account extends CoValueBase implements CoValue {
|
|
236
236
|
return this.toJSON();
|
237
237
|
}
|
238
238
|
|
239
|
-
|
239
|
+
async applyMigration(creationProps?: { name: string }) {
|
240
240
|
if (creationProps) {
|
241
241
|
const profileGroup = RegisteredSchemas["Group"].create({ owner: this });
|
242
242
|
profileGroup.addMember("everyone", "reader");
|
@@ -256,6 +256,13 @@ export class Account extends CoValueBase implements CoValue {
|
|
256
256
|
profile.set("inbox", inboxRoot.id);
|
257
257
|
profile.set("inboxInvite", inboxRoot.inviteLink);
|
258
258
|
}
|
259
|
+
|
260
|
+
await this.migrate(creationProps);
|
261
|
+
}
|
262
|
+
|
263
|
+
// Placeholder method for subclasses to override
|
264
|
+
migrate(creationProps?: { name: string }) {
|
265
|
+
creationProps; // To avoid unused parameter warning
|
259
266
|
}
|
260
267
|
|
261
268
|
/** @category Subscription & Loading */
|
package/src/coValues/coMap.ts
CHANGED
@@ -617,8 +617,14 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
617
617
|
} else if (key in target) {
|
618
618
|
return Reflect.get(target, key, receiver);
|
619
619
|
} else {
|
620
|
-
const
|
621
|
-
|
620
|
+
const schema = target._schema;
|
621
|
+
|
622
|
+
if (!schema) {
|
623
|
+
return undefined;
|
624
|
+
}
|
625
|
+
|
626
|
+
const descriptor = (schema[key as keyof CoMap["_schema"]] ||
|
627
|
+
schema[ItemsSym]) as Schema;
|
622
628
|
if (descriptor && typeof key === "string") {
|
623
629
|
const raw = target._raw.get(key);
|
624
630
|
|
@@ -169,7 +169,7 @@ export async function createJazzContext<Acc extends Account>(
|
|
169
169
|
fromRaw: rawAccount,
|
170
170
|
}) as Acc;
|
171
171
|
|
172
|
-
await account.
|
172
|
+
await account.applyMigration(creationProps);
|
173
173
|
},
|
174
174
|
});
|
175
175
|
|
@@ -218,7 +218,7 @@ export async function createJazzContext<Acc extends Account>(
|
|
218
218
|
fromRaw: rawAccount,
|
219
219
|
}) as Acc;
|
220
220
|
|
221
|
-
await account.
|
221
|
+
await account.applyMigration(creationProps);
|
222
222
|
},
|
223
223
|
});
|
224
224
|
|
package/src/tests/coMap.test.ts
CHANGED
@@ -38,8 +38,6 @@ describe("Simple CoMap operations", async () => {
|
|
38
38
|
crypto: Crypto,
|
39
39
|
});
|
40
40
|
|
41
|
-
console.log("TestMap schema", TestMap.prototype._schema);
|
42
|
-
|
43
41
|
const birthday = new Date();
|
44
42
|
|
45
43
|
const map = TestMap.create(
|
@@ -82,6 +80,13 @@ describe("Simple CoMap operations", async () => {
|
|
82
80
|
expect(mapWithExtra.color).toEqual("red");
|
83
81
|
});
|
84
82
|
|
83
|
+
test("Empty schema", () => {
|
84
|
+
const emptyMap = CoMap.create({}, { owner: me });
|
85
|
+
|
86
|
+
// @ts-expect-error
|
87
|
+
expect(emptyMap.color).toEqual(undefined);
|
88
|
+
});
|
89
|
+
|
85
90
|
describe("Mutation", () => {
|
86
91
|
test("assignment & deletion", () => {
|
87
92
|
map.color = "blue";
|
@@ -468,10 +473,8 @@ describe("CoMap resolution", async () => {
|
|
468
473
|
const queue = new cojsonInternals.Channel<TestMap>();
|
469
474
|
|
470
475
|
TestMap.subscribe(map.id, meOnSecondPeer, {}, (subscribedMap) => {
|
471
|
-
|
472
|
-
|
473
|
-
subscribedMap.nested?.twiceNested?.taste,
|
474
|
-
);
|
476
|
+
// Read to property to trigger loading
|
477
|
+
subscribedMap.nested?.twiceNested?.taste;
|
475
478
|
void queue.push(subscribedMap);
|
476
479
|
});
|
477
480
|
|
@@ -166,68 +166,6 @@ describe("Group inheritance", () => {
|
|
166
166
|
expect(mapAsReaderAfterUpdate?.title).toBe("In Grand Child");
|
167
167
|
});
|
168
168
|
|
169
|
-
test("Group inheritance should fail if the current account doesn't have admin role in both groups", async () => {
|
170
|
-
const me = await Account.create({
|
171
|
-
creationProps: { name: "Hermes Puggington" },
|
172
|
-
crypto: Crypto,
|
173
|
-
});
|
174
|
-
|
175
|
-
const other = await Account.createAs(me, {
|
176
|
-
creationProps: { name: "Another user" },
|
177
|
-
});
|
178
|
-
|
179
|
-
const parentGroup = Group.create({ owner: me });
|
180
|
-
parentGroup.addMember(other, "writer");
|
181
|
-
const group = Group.create({ owner: me });
|
182
|
-
group.addMember(other, "admin");
|
183
|
-
|
184
|
-
const parentGroupOnTheOtherSide = await Group.load(
|
185
|
-
parentGroup.id,
|
186
|
-
other,
|
187
|
-
{},
|
188
|
-
);
|
189
|
-
const groupOnTheOtherSide = await Group.load(group.id, other, {});
|
190
|
-
|
191
|
-
if (!groupOnTheOtherSide || !parentGroupOnTheOtherSide) {
|
192
|
-
throw new Error("CoValue not available");
|
193
|
-
}
|
194
|
-
|
195
|
-
expect(() => groupOnTheOtherSide.extend(parentGroupOnTheOtherSide)).toThrow(
|
196
|
-
"To extend a group, the current account must have admin role in both groups",
|
197
|
-
);
|
198
|
-
});
|
199
|
-
|
200
|
-
test("Group inheritance should work if the current account has admin role in both groups", async () => {
|
201
|
-
const me = await Account.create({
|
202
|
-
creationProps: { name: "Hermes Puggington" },
|
203
|
-
crypto: Crypto,
|
204
|
-
});
|
205
|
-
|
206
|
-
const other = await Account.createAs(me, {
|
207
|
-
creationProps: { name: "Another user" },
|
208
|
-
});
|
209
|
-
|
210
|
-
const parentGroup = Group.create({ owner: me });
|
211
|
-
parentGroup.addMember(other, "admin");
|
212
|
-
const group = Group.create({ owner: me });
|
213
|
-
group.addMember(other, "admin");
|
214
|
-
|
215
|
-
const parentGroupOnTheOtherSide = await Group.load(
|
216
|
-
parentGroup.id,
|
217
|
-
other,
|
218
|
-
{},
|
219
|
-
);
|
220
|
-
const groupOnTheOtherSide = await Group.load(group.id, other, {});
|
221
|
-
|
222
|
-
if (!groupOnTheOtherSide || !parentGroupOnTheOtherSide) {
|
223
|
-
throw new Error("CoValue not available");
|
224
|
-
}
|
225
|
-
|
226
|
-
expect(() =>
|
227
|
-
groupOnTheOtherSide.extend(parentGroupOnTheOtherSide),
|
228
|
-
).not.toThrow();
|
229
|
-
});
|
230
|
-
|
231
169
|
test("waitForSync should resolve when the value is uploaded", async () => {
|
232
170
|
const { clientNode, serverNode, clientAccount } = await setupTwoNodes();
|
233
171
|
|
package/src/tests/inbox.test.ts
CHANGED
@@ -51,6 +51,49 @@ describe("Inbox", () => {
|
|
51
51
|
unsubscribe();
|
52
52
|
});
|
53
53
|
|
54
|
+
it("should work with empty CoMaps", async () => {
|
55
|
+
const { clientAccount: sender, serverAccount: receiver } =
|
56
|
+
await setupTwoNodes();
|
57
|
+
|
58
|
+
class EmptyMessage extends CoMap {}
|
59
|
+
|
60
|
+
const receiverInbox = await Inbox.load(receiver);
|
61
|
+
|
62
|
+
// Create a message from sender
|
63
|
+
const message = EmptyMessage.create(
|
64
|
+
{},
|
65
|
+
{
|
66
|
+
owner: Group.create({ owner: sender }),
|
67
|
+
},
|
68
|
+
);
|
69
|
+
|
70
|
+
// Setup inbox sender
|
71
|
+
const inboxSender = await InboxSender.load(receiver.id, sender);
|
72
|
+
inboxSender.sendMessage(message);
|
73
|
+
|
74
|
+
// Track received messages
|
75
|
+
const receivedMessages: EmptyMessage[] = [];
|
76
|
+
let senderAccountID: unknown = undefined;
|
77
|
+
|
78
|
+
// Subscribe to inbox messages
|
79
|
+
const unsubscribe = receiverInbox.subscribe(
|
80
|
+
EmptyMessage,
|
81
|
+
async (message, id) => {
|
82
|
+
senderAccountID = id;
|
83
|
+
receivedMessages.push(message);
|
84
|
+
},
|
85
|
+
);
|
86
|
+
|
87
|
+
// Wait for message to be received
|
88
|
+
await waitFor(() => receivedMessages.length === 1);
|
89
|
+
|
90
|
+
expect(receivedMessages.length).toBe(1);
|
91
|
+
expect(receivedMessages[0]?.id).toBe(message.id);
|
92
|
+
expect(senderAccountID).toBe(sender.id);
|
93
|
+
|
94
|
+
unsubscribe();
|
95
|
+
});
|
96
|
+
|
54
97
|
it("should return the result of the message", async () => {
|
55
98
|
const { clientAccount: sender, serverAccount: receiver } =
|
56
99
|
await setupTwoNodes();
|
package/src/tests/utils.ts
CHANGED
@@ -59,7 +59,7 @@ export async function setupTwoNodes() {
|
|
59
59
|
fromRaw: rawAccount,
|
60
60
|
});
|
61
61
|
|
62
|
-
await account.
|
62
|
+
await account.applyMigration(creationProps);
|
63
63
|
},
|
64
64
|
});
|
65
65
|
|
@@ -72,7 +72,7 @@ export async function setupTwoNodes() {
|
|
72
72
|
fromRaw: rawAccount,
|
73
73
|
});
|
74
74
|
|
75
|
-
await account.
|
75
|
+
await account.applyMigration(creationProps);
|
76
76
|
},
|
77
77
|
});
|
78
78
|
|