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/package.json CHANGED
@@ -19,9 +19,9 @@
19
19
  },
20
20
  "type": "module",
21
21
  "license": "MIT",
22
- "version": "0.8.45",
22
+ "version": "0.8.49",
23
23
  "dependencies": {
24
- "cojson": "0.8.45"
24
+ "cojson": "0.8.49"
25
25
  },
26
26
  "devDependencies": {
27
27
  "tsup": "8.3.5",
@@ -185,7 +185,7 @@ export class Account extends CoValueBase implements CoValue {
185
185
  fromRaw: rawAccount,
186
186
  }) as A;
187
187
 
188
- await account.migrate?.(creationProps);
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
- migrate(this: Account, creationProps?: { name: string }) {
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 */
@@ -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 descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
621
- target._schema[ItemsSym]) as Schema;
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.migrate?.(creationProps);
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.migrate?.(creationProps);
221
+ await account.applyMigration(creationProps);
222
222
  },
223
223
  });
224
224
 
@@ -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
- console.log(
472
- "subscribedMap.nested?.twiceNested?.taste",
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
 
@@ -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();
@@ -59,7 +59,7 @@ export async function setupTwoNodes() {
59
59
  fromRaw: rawAccount,
60
60
  });
61
61
 
62
- await account.migrate?.(creationProps);
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.migrate?.(creationProps);
75
+ await account.applyMigration(creationProps);
76
76
  },
77
77
  });
78
78