cojson 0.2.2 → 0.2.3

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.
Files changed (58) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/dist/account.d.ts +7 -7
  3. package/dist/account.js +2 -2
  4. package/dist/account.js.map +1 -1
  5. package/dist/coValue.d.ts +26 -23
  6. package/dist/coValue.js +14 -0
  7. package/dist/coValue.js.map +1 -1
  8. package/dist/coValueCore.d.ts +6 -6
  9. package/dist/coValueCore.js.map +1 -1
  10. package/dist/coValues/coList.d.ts +22 -22
  11. package/dist/coValues/coList.js +3 -2
  12. package/dist/coValues/coList.js.map +1 -1
  13. package/dist/coValues/coMap.d.ts +29 -35
  14. package/dist/coValues/coMap.js +17 -8
  15. package/dist/coValues/coMap.js.map +1 -1
  16. package/dist/coValues/coStream.d.ts +28 -27
  17. package/dist/coValues/coStream.js +15 -6
  18. package/dist/coValues/coStream.js.map +1 -1
  19. package/dist/coValues/static.d.ts +4 -4
  20. package/dist/coValues/static.js.map +1 -1
  21. package/dist/group.d.ts +8 -6
  22. package/dist/group.js +20 -4
  23. package/dist/group.js.map +1 -1
  24. package/dist/index.d.ts +7 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/media.d.ts +1 -2
  27. package/dist/node.d.ts +7 -3
  28. package/dist/node.js +37 -7
  29. package/dist/node.js.map +1 -1
  30. package/dist/queries.d.ts +114 -0
  31. package/dist/queries.js +260 -0
  32. package/dist/queries.js.map +1 -0
  33. package/dist/{testUtils.d.ts → tests/testUtils.d.ts} +9 -9
  34. package/dist/{testUtils.js → tests/testUtils.js} +7 -5
  35. package/dist/tests/testUtils.js.map +1 -0
  36. package/package.json +2 -2
  37. package/src/account.ts +5 -5
  38. package/src/coValue.ts +54 -28
  39. package/src/coValueCore.ts +6 -6
  40. package/src/coValues/coList.ts +73 -37
  41. package/src/coValues/coMap.ts +134 -68
  42. package/src/coValues/coStream.ts +86 -55
  43. package/src/coValues/static.ts +5 -5
  44. package/src/group.ts +50 -11
  45. package/src/index.ts +10 -8
  46. package/src/media.ts +1 -2
  47. package/src/node.ts +70 -19
  48. package/src/queries.ts +519 -0
  49. package/src/{account.test.ts → tests/account.test.ts} +4 -4
  50. package/src/{coValue.test.ts → tests/coValue.test.ts} +5 -5
  51. package/src/{coValueCore.test.ts → tests/coValueCore.test.ts} +7 -7
  52. package/src/{crypto.test.ts → tests/crypto.test.ts} +3 -3
  53. package/src/{group.test.ts → tests/group.test.ts} +2 -2
  54. package/src/{permissions.test.ts → tests/permissions.test.ts} +5 -5
  55. package/src/tests/queries.test.ts +301 -0
  56. package/src/{sync.test.ts → tests/sync.test.ts} +10 -10
  57. package/src/{testUtils.ts → tests/testUtils.ts} +8 -6
  58. package/dist/testUtils.js.map +0 -1
@@ -0,0 +1,301 @@
1
+ import { BinaryCoStream, CoList, CoMap, CoStream, Group, LocalNode, cojsonReady } from "..";
2
+
3
+ beforeEach(async () => {
4
+ await cojsonReady;
5
+ });
6
+
7
+ test("Queries with maps work", async () => {
8
+ const { node, accountID } =
9
+ LocalNode.withNewlyCreatedAccount("Hermes Puggington");
10
+
11
+ const group = node.createGroup();
12
+
13
+ let map = group.createMap<
14
+ CoMap<{
15
+ hello: "world";
16
+ subMap: CoMap<{
17
+ hello: "world" | "moon" | "sun";
18
+ id: string;
19
+ }>;
20
+ }>
21
+ >();
22
+
23
+ const done = new Promise<void>((resolve) => {
24
+ const unsubQuery = node.query(map.id, (queriedMap) => {
25
+ // console.log("update", update);
26
+ if (queriedMap) {
27
+ expect(queriedMap.type).toBe("comap");
28
+ expect(queriedMap.id).toEqual(map.id);
29
+ expect(queriedMap.core).toEqual(map.core);
30
+ expect(queriedMap.group).toBeInstanceOf(Group);
31
+ expect(queriedMap.group.id).toBe(group.id);
32
+ expect(queriedMap.meta).toBe(null);
33
+ expect(queriedMap.hello).toBe("world");
34
+ expect(Object.keys(queriedMap)).toEqual(["hello", "subMap"]);
35
+ if (queriedMap.edits.hello?.by?.profile?.name) {
36
+ expect(queriedMap.edits.hello).toMatchObject({
37
+ by: {
38
+ id: accountID,
39
+ profile: {
40
+ id: node.expectProfileLoaded(accountID).id,
41
+ name: "Hermes Puggington",
42
+ },
43
+ isMe: true,
44
+ },
45
+ at: new Date(map.getLastEntry("hello")!.at),
46
+ });
47
+ if (queriedMap.subMap) {
48
+ expect(queriedMap.subMap.type).toBe("comap");
49
+ expect(queriedMap.subMap.id).toEqual(subMap.id);
50
+ expect(queriedMap.subMap.core).toEqual(subMap.core);
51
+ expect(queriedMap.subMap.group).toBeInstanceOf(Group);
52
+ expect(queriedMap.subMap.group.id).toBe(group.id);
53
+ expect(queriedMap.subMap.meta).toBe(null);
54
+ expect(queriedMap.subMap.shadowed.id).toBe("foreignID");
55
+ if (queriedMap.subMap.hello === "moon") {
56
+ // console.log("got to 'moon'");
57
+ queriedMap.subMap.edit((subMap) => {
58
+ subMap.set("hello", "sun");
59
+ });
60
+ } else if (
61
+ queriedMap.subMap.hello === "sun" &&
62
+ queriedMap.subMap.edits.hello?.by?.profile?.name ===
63
+ "Hermes Puggington"
64
+ ) {
65
+ // console.log("final update", queriedMap);
66
+ resolve();
67
+ unsubQuery();
68
+ }
69
+ }
70
+ }
71
+ }
72
+ });
73
+ });
74
+
75
+ map = map.edit((map) => {
76
+ map.set("hello", "world");
77
+ });
78
+
79
+ let subMap = group.createMap<
80
+ CoMap<{
81
+ hello: "world" | "moon" | "sun";
82
+ id: string;
83
+ }>
84
+ >();
85
+
86
+ map = map.edit((map) => {
87
+ map.set("subMap", subMap);
88
+ });
89
+
90
+ subMap = subMap.edit((subMap) => {
91
+ subMap.set("hello", "world");
92
+ subMap.set("id", "foreignID");
93
+ });
94
+
95
+ subMap = subMap.edit((subMap) => {
96
+ subMap.set("hello", "moon");
97
+ });
98
+
99
+ await done;
100
+ });
101
+
102
+ test("Queries with lists work", () => {
103
+ const { node, accountID } =
104
+ LocalNode.withNewlyCreatedAccount("Hermes Puggington");
105
+
106
+ const group = node.createGroup();
107
+
108
+ let list = group.createList<CoList<string>>();
109
+
110
+ const done = new Promise<void>((resolve) => {
111
+ const unsubQuery = node.query(list.id, (queriedList) => {
112
+ if (queriedList) {
113
+ // console.log("update", queriedList, queriedList.edits);
114
+ expect(queriedList.type).toBe("colist");
115
+ expect(queriedList.id).toEqual(list.id);
116
+ expect(queriedList.core).toEqual(list.core);
117
+ expect(queriedList.group).toBeInstanceOf(Group);
118
+ expect(queriedList.group.id).toBe(group.id);
119
+ expect(queriedList.meta).toBe(null);
120
+ expect(queriedList[0]).toBe("hello");
121
+ expect(queriedList[1]).toBe("world");
122
+ expect(queriedList[2]).toBe("moon");
123
+ if (queriedList.edits[2]?.by?.profile?.name) {
124
+ expect(queriedList.edits[2]).toMatchObject({
125
+ by: {
126
+ id: accountID,
127
+ profile: {
128
+ id: node.expectProfileLoaded(accountID).id,
129
+ name: "Hermes Puggington",
130
+ },
131
+ isMe: true,
132
+ },
133
+ at: expect.any(Date),
134
+ });
135
+ if (queriedList.length === 3) {
136
+ queriedList.edit((list) => {
137
+ list.push("sun");
138
+ });
139
+ } else if (
140
+ queriedList.length === 4 &&
141
+ queriedList.edits[3]?.by?.profile?.name ===
142
+ "Hermes Puggington"
143
+ ) {
144
+ expect(queriedList[3]).toBe("sun");
145
+ // console.log("final update", queriedList);
146
+ resolve();
147
+ unsubQuery();
148
+ }
149
+ }
150
+ }
151
+ });
152
+ });
153
+
154
+ list = list.edit((list) => {
155
+ list.push("hello");
156
+ list.push("world");
157
+ list.push("moon");
158
+ });
159
+
160
+ return done;
161
+ });
162
+
163
+ test("List of nested maps works", () => {
164
+ const { node } = LocalNode.withNewlyCreatedAccount("Hermes Puggington");
165
+
166
+ const group = node.createGroup();
167
+
168
+ let list = group.createList<CoList<CoMap<{ hello: "world" }>>>();
169
+
170
+ const done = new Promise<void>((resolve) => {
171
+ const unsubQuery = node.query(list.id, (queriedList) => {
172
+ if (queriedList && queriedList[0]) {
173
+ // console.log("update", queriedList);
174
+ expect(queriedList[0]).toMatchObject({
175
+ hello: "world",
176
+ id: list.get(0)!,
177
+ });
178
+ // console.log("final update", queriedList);
179
+ resolve();
180
+ unsubQuery();
181
+ }
182
+ });
183
+ });
184
+
185
+ list = list.edit((list) => {
186
+ list.push(
187
+ group.createMap<CoMap<{ hello: "world" }>>({
188
+ hello: "world",
189
+ })
190
+ );
191
+ });
192
+
193
+ return done;
194
+ });
195
+
196
+ test("Queries with streams work", () => {
197
+ const { node, accountID } =
198
+ LocalNode.withNewlyCreatedAccount("Hermes Puggington");
199
+
200
+ const group = node.createGroup();
201
+
202
+ let stream = group.createStream<CoStream<string>>();
203
+
204
+ const done = new Promise<void>((resolve) => {
205
+ const unsubQuery = node.query(stream.id, (queriedStream) => {
206
+ if (queriedStream) {
207
+ console.log("update", queriedStream);
208
+ if (queriedStream.me?.by?.profile?.name) {
209
+ expect(queriedStream.type).toBe("costream");
210
+ expect(queriedStream.id).toEqual(stream.id);
211
+ expect(queriedStream.core).toEqual(stream.core);
212
+ expect(queriedStream.group).toBeInstanceOf(Group);
213
+ expect(queriedStream.group.id).toBe(group.id);
214
+ expect(queriedStream.meta).toBe(null);
215
+ const expectedEntry = {
216
+ last: "world",
217
+ by: {
218
+ id: accountID,
219
+ isMe: true,
220
+ profile: {
221
+ id: node.expectProfileLoaded(accountID).id,
222
+ name: "Hermes Puggington",
223
+ },
224
+ },
225
+ at: new Date(
226
+ stream.items[node.currentSessionID][1].madeAt
227
+ ),
228
+ all: [
229
+ {
230
+ value: "hello",
231
+ at: new Date(
232
+ stream.items[
233
+ node.currentSessionID
234
+ ][0].madeAt
235
+ ),
236
+ },
237
+ {
238
+ value: "world",
239
+ at: new Date(
240
+ stream.items[
241
+ node.currentSessionID
242
+ ][1].madeAt
243
+ ),
244
+ },
245
+ ],
246
+ };
247
+ expect(queriedStream.perSession).toMatchObject({
248
+ [node.currentSessionID]: expectedEntry,
249
+ });
250
+ expect(queriedStream.perAccount).toMatchObject({
251
+ [accountID]: expectedEntry,
252
+ });
253
+ expect(queriedStream.me).toMatchObject(expectedEntry);
254
+ console.log("final update", queriedStream);
255
+ resolve();
256
+ unsubQuery();
257
+ }
258
+ }
259
+ });
260
+ });
261
+
262
+ stream = stream.edit((stream) => {
263
+ stream.push("hello");
264
+ stream.push("world");
265
+ });
266
+
267
+ return done;
268
+ });
269
+
270
+ test("Streams of nested maps work", () => {
271
+ const { node } = LocalNode.withNewlyCreatedAccount("Hermes Puggington");
272
+
273
+ const group = node.createGroup();
274
+
275
+ let stream = group.createStream<CoStream<CoMap<{ hello: "world" }>>>();
276
+
277
+ const done = new Promise<void>((resolve) => {
278
+ const unsubQuery = node.query(stream.id, (queriedStream) => {
279
+ if (queriedStream && queriedStream.me?.last) {
280
+ // console.log("update", queriedList);
281
+ expect(queriedStream.me.last).toMatchObject({
282
+ hello: "world",
283
+ id: map.id,
284
+ });
285
+ // console.log("final update", queriedList);
286
+ resolve();
287
+ unsubQuery();
288
+ }
289
+ });
290
+ });
291
+
292
+ const map = group.createMap<CoMap<{ hello: "world" }>>({
293
+ hello: "world",
294
+ });
295
+
296
+ stream = stream.edit((list) => {
297
+ list.push(map);
298
+ });
299
+
300
+ return done;
301
+ });
@@ -1,17 +1,17 @@
1
- import { newRandomSessionID } from "./coValueCore.js";
2
- import { LocalNode } from "./node.js";
3
- import { SyncMessage } from "./sync.js";
4
- import { expectMap } from "./coValue.js";
5
- import { MapOpPayload } from "./coValues/coMap.js";
6
- import { Group } from "./group.js";
1
+ import { newRandomSessionID } from "../coValueCore.js";
2
+ import { LocalNode } from "../node.js";
3
+ import { SyncMessage } from "../sync.js";
4
+ import { expectMap } from "../coValue.js";
5
+ import { MapOpPayload } from "../coValues/coMap.js";
6
+ import { Group } from "../group.js";
7
7
  import {
8
8
  randomAnonymousAccountAndSessionID,
9
9
  shouldNotResolve,
10
10
  } from "./testUtils.js";
11
- import { connectedPeers, newStreamPair } from "./streamUtils.js";
12
- import { AccountID } from "./account.js";
13
- import { cojsonReady } from "./index.js";
14
- import { stableStringify } from "./jsonStringify.js";
11
+ import { connectedPeers, newStreamPair } from "../streamUtils.js";
12
+ import { AccountID } from "../account.js";
13
+ import { cojsonReady } from "../index.js";
14
+ import { stableStringify } from "../jsonStringify.js";
15
15
 
16
16
  beforeEach(async () => {
17
17
  await cojsonReady;
@@ -1,9 +1,11 @@
1
- import { AgentSecret, createdNowUnique, getAgentID, newRandomAgentSecret } from "./crypto.js";
2
- import { newRandomSessionID } from "./coValueCore.js";
3
- import { LocalNode } from "./node.js";
4
- import { expectGroupContent } from "./group.js";
5
- import { AnonymousControlledAccount } from "./account.js";
6
- import { SessionID } from "./ids.js";
1
+ import { AgentSecret, createdNowUnique, getAgentID, newRandomAgentSecret } from "../crypto.js";
2
+ import { newRandomSessionID } from "../coValueCore.js";
3
+ import { LocalNode } from "../node.js";
4
+ import { expectGroupContent } from "../group.js";
5
+ import { AnonymousControlledAccount } from "../account.js";
6
+ import { SessionID } from "../ids.js";
7
+ // @ts-ignore
8
+ import { expect } from "bun:test";
7
9
 
8
10
  export function randomAnonymousAccountAndSessionID(): [AnonymousControlledAccount, SessionID] {
9
11
  const agentSecret = newRandomAgentSecret();
@@ -1 +0,0 @@
1
- {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"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"}