jazz-tools 0.7.0-alpha.9 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. package/.eslintrc.cjs +3 -10
  2. package/.prettierrc.js +9 -0
  3. package/.turbo/turbo-build.log +14 -15
  4. package/.turbo/turbo-lint.log +4 -0
  5. package/.turbo/turbo-test.log +140 -0
  6. package/CHANGELOG.md +331 -27
  7. package/LICENSE.txt +1 -1
  8. package/README.md +10 -2
  9. package/dist/coValues/account.js +86 -41
  10. package/dist/coValues/account.js.map +1 -1
  11. package/dist/coValues/coList.js +75 -48
  12. package/dist/coValues/coList.js.map +1 -1
  13. package/dist/coValues/coMap.js +167 -44
  14. package/dist/coValues/coMap.js.map +1 -1
  15. package/dist/coValues/coStream.js +192 -35
  16. package/dist/coValues/coStream.js.map +1 -1
  17. package/dist/coValues/deepLoading.js +60 -0
  18. package/dist/coValues/deepLoading.js.map +1 -0
  19. package/dist/coValues/extensions/imageDef.js +10 -7
  20. package/dist/coValues/extensions/imageDef.js.map +1 -1
  21. package/dist/coValues/group.js +73 -13
  22. package/dist/coValues/group.js.map +1 -1
  23. package/dist/coValues/interfaces.js +58 -35
  24. package/dist/coValues/interfaces.js.map +1 -1
  25. package/dist/implementation/devtoolsFormatters.js +114 -0
  26. package/dist/implementation/devtoolsFormatters.js.map +1 -0
  27. package/dist/implementation/refs.js +58 -18
  28. package/dist/implementation/refs.js.map +1 -1
  29. package/dist/implementation/schema.js +58 -0
  30. package/dist/implementation/schema.js.map +1 -0
  31. package/dist/implementation/subscriptionScope.js +19 -1
  32. package/dist/implementation/subscriptionScope.js.map +1 -1
  33. package/dist/implementation/symbols.js +5 -0
  34. package/dist/implementation/symbols.js.map +1 -0
  35. package/dist/index.js +4 -5
  36. package/dist/index.js.map +1 -1
  37. package/dist/internal.js +5 -2
  38. package/dist/internal.js.map +1 -1
  39. package/dist/tests/coList.test.js +51 -48
  40. package/dist/tests/coList.test.js.map +1 -1
  41. package/dist/tests/coMap.test.js +131 -74
  42. package/dist/tests/coMap.test.js.map +1 -1
  43. package/dist/tests/coStream.test.js +56 -41
  44. package/dist/tests/coStream.test.js.map +1 -1
  45. package/dist/tests/deepLoading.test.js +188 -0
  46. package/dist/tests/deepLoading.test.js.map +1 -0
  47. package/dist/tests/groupsAndAccounts.test.js +83 -0
  48. package/dist/tests/groupsAndAccounts.test.js.map +1 -0
  49. package/package.json +17 -9
  50. package/src/coValues/account.ts +186 -128
  51. package/src/coValues/coList.ts +156 -107
  52. package/src/coValues/coMap.ts +272 -148
  53. package/src/coValues/coStream.ts +388 -87
  54. package/src/coValues/deepLoading.ts +229 -0
  55. package/src/coValues/extensions/imageDef.ts +17 -13
  56. package/src/coValues/group.ts +166 -59
  57. package/src/coValues/interfaces.ts +189 -160
  58. package/src/implementation/devtoolsFormatters.ts +110 -0
  59. package/src/implementation/inspect.ts +1 -1
  60. package/src/implementation/refs.ts +80 -28
  61. package/src/implementation/schema.ts +141 -0
  62. package/src/implementation/subscriptionScope.ts +48 -12
  63. package/src/implementation/symbols.ts +11 -0
  64. package/src/index.ts +19 -8
  65. package/src/internal.ts +7 -3
  66. package/src/tests/coList.test.ts +77 -62
  67. package/src/tests/coMap.test.ts +201 -114
  68. package/src/tests/coStream.test.ts +113 -84
  69. package/src/tests/deepLoading.test.ts +304 -0
  70. package/src/tests/groupsAndAccounts.test.ts +91 -0
  71. package/dist/implementation/encoding.js +0 -26
  72. package/dist/implementation/encoding.js.map +0 -1
  73. package/src/implementation/encoding.ts +0 -105
@@ -1,29 +1,30 @@
1
- import { expect, describe, test, beforeEach } from "vitest";
2
-
3
- import { webcrypto } from "node:crypto";
1
+ import { expect, describe, test } from "vitest";
4
2
  import { connectedPeers } from "cojson/src/streamUtils.js";
5
3
  import { newRandomSessionID } from "cojson/src/coValueCore.js";
6
4
  import { Effect, Queue } from "effect";
7
- import { BinaryCoStream, ID, Account, jazzReady, CoStream, val } from "..";
8
- import { Simplify } from "effect/Types";
9
-
10
- if (!("crypto" in globalThis)) {
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- (globalThis as any).crypto = webcrypto;
13
- }
14
-
15
- beforeEach(async () => {
16
- await jazzReady;
17
- });
5
+ import {
6
+ BinaryCoStream,
7
+ ID,
8
+ Account,
9
+ CoStream,
10
+ co,
11
+ WasmCrypto,
12
+ isControlledAccount,
13
+ } from "../index.js";
14
+
15
+ const Crypto = await WasmCrypto.create();
18
16
 
19
17
  describe("Simple CoStream operations", async () => {
20
18
  const me = await Account.create({
21
- name: "Hermes Puggington",
19
+ creationProps: { name: "Hermes Puggington" },
20
+ crypto: Crypto,
22
21
  });
22
+ if (!isControlledAccount(me)) {
23
+ throw "me is not a controlled account";
24
+ }
25
+ class TestStream extends CoStream.Of(co.string) {}
23
26
 
24
- class TestStream extends CoStream.Of(val.string) {}
25
-
26
- const stream = new TestStream(["milk"], { owner: me });
27
+ const stream = TestStream.create(["milk"], { owner: me });
27
28
 
28
29
  test("Construction", () => {
29
30
  expect(stream[me.id]?.value).toEqual("milk");
@@ -44,29 +45,30 @@ describe("Simple CoStream operations", async () => {
44
45
  });
45
46
 
46
47
  describe("CoStream resolution", async () => {
47
- class TwiceNestedStream extends CoStream.Of(val.string) {
48
+ class TwiceNestedStream extends CoStream.Of(co.string) {
48
49
  fancyValueOf(account: ID<Account>) {
49
50
  return "Sir " + this[account]?.value;
50
51
  }
51
52
  }
52
53
 
53
- class NestedStream extends CoStream.Of(val.ref(() => TwiceNestedStream)) {}
54
+ class NestedStream extends CoStream.Of(co.ref(TwiceNestedStream)) {}
54
55
 
55
- class TestStream extends CoStream.Of(val.ref(() => NestedStream)) {}
56
+ class TestStream extends CoStream.Of(co.ref(NestedStream)) {}
56
57
 
57
58
  const initNodeAndStream = async () => {
58
59
  const me = await Account.create({
59
- name: "Hermes Puggington",
60
+ creationProps: { name: "Hermes Puggington" },
61
+ crypto: Crypto,
60
62
  });
61
63
 
62
- const stream = new TestStream(
64
+ const stream = TestStream.create(
63
65
  [
64
- new NestedStream(
65
- [new TwiceNestedStream(["milk"], { owner: me })],
66
- { owner: me }
66
+ NestedStream.create(
67
+ [TwiceNestedStream.create(["milk"], { owner: me })],
68
+ { owner: me },
67
69
  ),
68
70
  ],
69
- { owner: me }
71
+ { owner: me },
70
72
  );
71
73
 
72
74
  return { me, stream };
@@ -75,7 +77,7 @@ describe("CoStream resolution", async () => {
75
77
  test("Construction", async () => {
76
78
  const { me, stream } = await initNodeAndStream();
77
79
  expect(stream[me.id]?.value?.[me.id]?.value?.[me.id]?.value).toEqual(
78
- "milk"
80
+ "milk",
79
81
  );
80
82
  });
81
83
 
@@ -84,80 +86,89 @@ describe("CoStream resolution", async () => {
84
86
  const [initialAsPeer, secondPeer] = connectedPeers(
85
87
  "initial",
86
88
  "second",
87
- { peer1role: "server", peer2role: "client" }
89
+ { peer1role: "server", peer2role: "client" },
88
90
  );
91
+ if (!isControlledAccount(me)) {
92
+ throw "me is not a controlled account";
93
+ }
89
94
  me._raw.core.node.syncManager.addPeer(secondPeer);
90
95
  const meOnSecondPeer = await Account.become({
91
96
  accountID: me.id,
92
97
  accountSecret: me._raw.agentSecret,
93
98
  peersToLoadFrom: [initialAsPeer],
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
100
  sessionID: newRandomSessionID(me.id as any),
101
+ crypto: Crypto,
95
102
  });
96
103
 
97
- const loadedStream = await TestStream.load(stream.id, {
98
- as: meOnSecondPeer,
99
- });
104
+ const loadedStream = await TestStream.load(
105
+ stream.id,
106
+ meOnSecondPeer,
107
+ [],
108
+ );
100
109
 
101
110
  expect(loadedStream?.[me.id]?.value).toEqual(null);
102
111
  expect(loadedStream?.[me.id]?.ref?.id).toEqual(
103
- stream[me.id]?.value?.id
112
+ stream[me.id]?.value?.id,
104
113
  );
105
114
 
106
115
  const loadedNestedStream = await NestedStream.load(
107
116
  stream[me.id]!.value!.id,
108
- { as: meOnSecondPeer }
117
+ meOnSecondPeer,
118
+ [],
109
119
  );
110
120
 
111
121
  // expect(loadedStream?.[me.id]?.value).toEqual(loadedNestedStream);
112
122
  expect(loadedStream?.[me.id]?.value?.id).toEqual(
113
- loadedNestedStream?.id
123
+ loadedNestedStream?.id,
114
124
  );
115
125
  expect(loadedStream?.[me.id]?.value?.[me.id]?.value).toEqual(null);
116
126
  // expect(loadedStream?.[me.id]?.ref?.value).toEqual(loadedNestedStream);
117
127
  expect(loadedStream?.[me.id]?.ref?.value?.id).toEqual(
118
- loadedNestedStream?.id
128
+ loadedNestedStream?.id,
119
129
  );
120
130
  expect(loadedStream?.[me.id]?.value?.[me.id]?.ref?.id).toEqual(
121
- stream[me.id]?.value?.[me.id]?.value?.id
131
+ stream[me.id]?.value?.[me.id]?.value?.id,
122
132
  );
123
133
 
124
134
  const loadedTwiceNestedStream = await TwiceNestedStream.load(
125
135
  stream[me.id]!.value![me.id]!.value!.id,
126
- { as: meOnSecondPeer }
136
+ meOnSecondPeer,
137
+ [],
127
138
  );
128
139
 
129
140
  // expect(loadedStream?.[me.id]?.value?.[me.id]?.value).toEqual(
130
141
  // loadedTwiceNestedStream
131
142
  // );
132
143
  expect(loadedStream?.[me.id]?.value?.[me.id]?.value?.id).toEqual(
133
- loadedTwiceNestedStream?.id
144
+ loadedTwiceNestedStream?.id,
134
145
  );
135
146
  expect(
136
- loadedStream?.[me.id]?.value?.[me.id]?.value?.fancyValueOf(me.id)
147
+ loadedStream?.[me.id]?.value?.[me.id]?.value?.fancyValueOf(me.id),
137
148
  ).toEqual("Sir milk");
138
149
  // expect(loadedStream?.[me.id]?.ref?.value).toEqual(loadedNestedStream);
139
150
  expect(loadedStream?.[me.id]?.ref?.value?.id).toEqual(
140
- loadedNestedStream?.id
151
+ loadedNestedStream?.id,
141
152
  );
142
153
  expect(loadedStream?.[me.id]?.value?.[me.id]?.ref?.value?.id).toEqual(
143
- loadedTwiceNestedStream?.id
154
+ loadedTwiceNestedStream?.id,
144
155
  );
145
156
 
146
- const otherNestedStream = new NestedStream(
147
- [new TwiceNestedStream(["butter"], { owner: meOnSecondPeer })],
148
- { owner: meOnSecondPeer }
157
+ const otherNestedStream = NestedStream.create(
158
+ [TwiceNestedStream.create(["butter"], { owner: meOnSecondPeer })],
159
+ { owner: meOnSecondPeer },
149
160
  );
150
161
  loadedStream?.push(otherNestedStream);
151
162
  // expect(loadedStream?.[me.id]?.value).toEqual(otherNestedStream);
152
163
  expect(loadedStream?.[me.id]?.value?.id).toEqual(otherNestedStream?.id);
153
164
  expect(loadedStream?.[me.id]?.ref?.value?.id).toEqual(
154
- otherNestedStream?.id
165
+ otherNestedStream?.id,
155
166
  );
156
167
  expect(loadedStream?.[me.id]?.value?.[me.id]?.value?.id).toEqual(
157
- otherNestedStream[me.id]?.value?.id
168
+ otherNestedStream[me.id]?.value?.id,
158
169
  );
159
170
  expect(
160
- loadedStream?.[me.id]?.value?.[me.id]?.value?.fancyValueOf(me.id)
171
+ loadedStream?.[me.id]?.value?.[me.id]?.value?.fancyValueOf(me.id),
161
172
  ).toEqual("Sir butter");
162
173
  });
163
174
 
@@ -167,16 +178,19 @@ describe("CoStream resolution", async () => {
167
178
  const [initialAsPeer, secondAsPeer] = connectedPeers(
168
179
  "initial",
169
180
  "second",
170
- { peer1role: "server", peer2role: "client" }
181
+ { peer1role: "server", peer2role: "client" },
171
182
  );
172
-
173
183
  me._raw.core.node.syncManager.addPeer(secondAsPeer);
174
-
184
+ if (!isControlledAccount(me)) {
185
+ throw "me is not a controlled account";
186
+ }
175
187
  const meOnSecondPeer = await Account.become({
176
188
  accountID: me.id,
177
189
  accountSecret: me._raw.agentSecret,
178
190
  peersToLoadFrom: [initialAsPeer],
191
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
192
  sessionID: newRandomSessionID(me.id as any),
193
+ crypto: Crypto,
180
194
  });
181
195
 
182
196
  await Effect.runPromise(
@@ -185,29 +199,29 @@ describe("CoStream resolution", async () => {
185
199
 
186
200
  TestStream.subscribe(
187
201
  stream.id,
188
- { as: meOnSecondPeer },
202
+ meOnSecondPeer,
203
+ [],
189
204
  (subscribedStream) => {
190
205
  console.log(
191
206
  "subscribedStream[me.id]",
192
- subscribedStream[me.id]
207
+ subscribedStream[me.id],
193
208
  );
194
209
  console.log(
195
210
  "subscribedStream[me.id]?.value?.[me.id]?.value",
196
- subscribedStream[me.id]?.value?.[me.id]?.value
211
+ subscribedStream[me.id]?.value?.[me.id]?.value,
197
212
  );
198
213
  console.log(
199
214
  "subscribedStream[me.id]?.value?.[me.id]?.value?.[me.id]?.value",
200
215
  subscribedStream[me.id]?.value?.[me.id]?.value?.[
201
216
  me.id
202
- ]?.value
217
+ ]?.value,
218
+ );
219
+ void Effect.runPromise(
220
+ Queue.offer(queue, subscribedStream),
203
221
  );
204
- Effect.runPromise(Queue.offer(queue, subscribedStream));
205
- }
222
+ },
206
223
  );
207
224
 
208
- type T = Simplify<TestStream>;
209
- const te: T = stream;
210
-
211
225
  const update1 = yield* $(Queue.take(queue));
212
226
  expect(update1[me.id]?.value).toEqual(null);
213
227
 
@@ -218,22 +232,22 @@ describe("CoStream resolution", async () => {
218
232
  const update3 = yield* $(Queue.take(queue));
219
233
  expect(update3[me.id]?.value?.[me.id]?.value).toBeDefined();
220
234
  expect(
221
- update3[me.id]?.value?.[me.id]?.value?.[me.id]?.value
235
+ update3[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
222
236
  ).toBe("milk");
223
237
 
224
238
  update3[me.id]!.value![me.id]!.value!.push("bread");
225
239
 
226
240
  const update4 = yield* $(Queue.take(queue));
227
241
  expect(
228
- update4[me.id]?.value?.[me.id]?.value?.[me.id]?.value
242
+ update4[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
229
243
  ).toBe("bread");
230
244
 
231
245
  // When assigning a new nested stream, we get an update
232
- const newTwiceNested = new TwiceNestedStream(["butter"], {
246
+ const newTwiceNested = TwiceNestedStream.create(["butter"], {
233
247
  owner: meOnSecondPeer,
234
248
  });
235
249
 
236
- const newNested = new NestedStream([newTwiceNested], {
250
+ const newNested = NestedStream.create([newTwiceNested], {
237
251
  owner: meOnSecondPeer,
238
252
  });
239
253
 
@@ -241,26 +255,27 @@ describe("CoStream resolution", async () => {
241
255
 
242
256
  const update5 = yield* $(Queue.take(queue));
243
257
  expect(
244
- update5[me.id]?.value?.[me.id]?.value?.[me.id]?.value
258
+ update5[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
245
259
  ).toBe("butter");
246
260
 
247
261
  // we get updates when the new nested stream changes
248
262
  newTwiceNested.push("jam");
249
263
  const update6 = yield* $(Queue.take(queue));
250
264
  expect(
251
- update6[me.id]?.value?.[me.id]?.value?.[me.id]?.value
265
+ update6[me.id]?.value?.[me.id]?.value?.[me.id]?.value,
252
266
  ).toBe("jam");
253
- })
267
+ }),
254
268
  );
255
269
  });
256
270
  });
257
271
 
258
272
  describe("Simple BinaryCoStream operations", async () => {
259
273
  const me = await Account.create({
260
- name: "Hermes Puggington",
274
+ creationProps: { name: "Hermes Puggington" },
275
+ crypto: Crypto,
261
276
  });
262
277
 
263
- const stream = new BinaryCoStream(undefined, { owner: me });
278
+ const stream = BinaryCoStream.create({ owner: me });
264
279
 
265
280
  test("Construction", () => {
266
281
  expect(stream.getChunks()).toBe(undefined);
@@ -285,10 +300,11 @@ describe("Simple BinaryCoStream operations", async () => {
285
300
  describe("BinaryCoStream loading & Subscription", async () => {
286
301
  const initNodeAndStream = async () => {
287
302
  const me = await Account.create({
288
- name: "Hermes Puggington",
303
+ creationProps: { name: "Hermes Puggington" },
304
+ crypto: Crypto,
289
305
  });
290
306
 
291
- const stream = new BinaryCoStream(undefined, { owner: me });
307
+ const stream = BinaryCoStream.create({ owner: me });
292
308
 
293
309
  stream.start({ mimeType: "text/plain" });
294
310
  stream.push(new Uint8Array([1, 2, 3]));
@@ -299,7 +315,7 @@ describe("BinaryCoStream loading & Subscription", async () => {
299
315
  };
300
316
 
301
317
  test("Construction", async () => {
302
- const { me, stream } = await initNodeAndStream();
318
+ const { stream } = await initNodeAndStream();
303
319
  expect(stream.getChunks()).toEqual({
304
320
  mimeType: "text/plain",
305
321
  chunks: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])],
@@ -312,19 +328,26 @@ describe("BinaryCoStream loading & Subscription", async () => {
312
328
  const [initialAsPeer, secondAsPeer] = connectedPeers(
313
329
  "initial",
314
330
  "second",
315
- { peer1role: "server", peer2role: "client" }
331
+ { peer1role: "server", peer2role: "client" },
316
332
  );
333
+ if (!isControlledAccount(me)) {
334
+ throw "me is not a controlled account";
335
+ }
317
336
  me._raw.core.node.syncManager.addPeer(secondAsPeer);
318
337
  const meOnSecondPeer = await Account.become({
319
338
  accountID: me.id,
320
339
  accountSecret: me._raw.agentSecret,
321
340
  peersToLoadFrom: [initialAsPeer],
341
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
322
342
  sessionID: newRandomSessionID(me.id as any),
343
+ crypto: Crypto,
323
344
  });
324
345
 
325
- const loadedStream = await BinaryCoStream.load(stream.id, {
326
- as: meOnSecondPeer,
327
- });
346
+ const loadedStream = await BinaryCoStream.load(
347
+ stream.id,
348
+ meOnSecondPeer,
349
+ [],
350
+ );
328
351
 
329
352
  expect(loadedStream?.getChunks()).toEqual({
330
353
  mimeType: "text/plain",
@@ -336,21 +359,24 @@ describe("BinaryCoStream loading & Subscription", async () => {
336
359
  test("Subscription", async () => {
337
360
  const { me } = await initNodeAndStream();
338
361
 
339
- const stream = new BinaryCoStream(undefined, { owner: me });
362
+ const stream = BinaryCoStream.create({ owner: me });
340
363
 
341
364
  const [initialAsPeer, secondAsPeer] = connectedPeers(
342
365
  "initial",
343
366
  "second",
344
- { peer1role: "server", peer2role: "client" }
367
+ { peer1role: "server", peer2role: "client" },
345
368
  );
346
-
347
369
  me._raw.core.node.syncManager.addPeer(secondAsPeer);
348
-
370
+ if (!isControlledAccount(me)) {
371
+ throw "me is not a controlled account";
372
+ }
349
373
  const meOnSecondPeer = await Account.become({
350
374
  accountID: me.id,
351
375
  accountSecret: me._raw.agentSecret,
352
376
  peersToLoadFrom: [initialAsPeer],
377
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
378
  sessionID: newRandomSessionID(me.id as any),
379
+ crypto: Crypto,
354
380
  });
355
381
 
356
382
  await Effect.runPromise(
@@ -359,10 +385,13 @@ describe("BinaryCoStream loading & Subscription", async () => {
359
385
 
360
386
  BinaryCoStream.subscribe(
361
387
  stream.id,
362
- { as: meOnSecondPeer },
388
+ meOnSecondPeer,
389
+ [],
363
390
  (subscribedStream) => {
364
- Effect.runPromise(Queue.offer(queue, subscribedStream));
365
- }
391
+ void Effect.runPromise(
392
+ Queue.offer(queue, subscribedStream),
393
+ );
394
+ },
366
395
  );
367
396
 
368
397
  const update1 = yield* $(Queue.take(queue));
@@ -417,7 +446,7 @@ describe("BinaryCoStream loading & Subscription", async () => {
417
446
  totalSizeBytes: undefined,
418
447
  finished: true,
419
448
  });
420
- })
449
+ }),
421
450
  );
422
451
  });
423
452
  });