jazz-tools 0.7.0-alpha.8 → 0.7.1

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 (72) hide show
  1. package/.eslintrc.cjs +3 -10
  2. package/.prettierrc.js +9 -0
  3. package/.turbo/turbo-build.log +3 -19
  4. package/.turbo/turbo-lint.log +4 -0
  5. package/.turbo/turbo-test.log +140 -0
  6. package/CHANGELOG.md +304 -0
  7. package/README.md +10 -2
  8. package/dist/coValues/account.js +59 -41
  9. package/dist/coValues/account.js.map +1 -1
  10. package/dist/coValues/coList.js +49 -46
  11. package/dist/coValues/coList.js.map +1 -1
  12. package/dist/coValues/coMap.js +143 -44
  13. package/dist/coValues/coMap.js.map +1 -1
  14. package/dist/coValues/coStream.js +144 -35
  15. package/dist/coValues/coStream.js.map +1 -1
  16. package/dist/coValues/deepLoading.js +60 -0
  17. package/dist/coValues/deepLoading.js.map +1 -0
  18. package/dist/coValues/extensions/imageDef.js +10 -7
  19. package/dist/coValues/extensions/imageDef.js.map +1 -1
  20. package/dist/coValues/group.js +49 -13
  21. package/dist/coValues/group.js.map +1 -1
  22. package/dist/coValues/interfaces.js +70 -31
  23. package/dist/coValues/interfaces.js.map +1 -1
  24. package/dist/implementation/devtoolsFormatters.js +114 -0
  25. package/dist/implementation/devtoolsFormatters.js.map +1 -0
  26. package/dist/implementation/refs.js +58 -18
  27. package/dist/implementation/refs.js.map +1 -1
  28. package/dist/implementation/schema.js +58 -0
  29. package/dist/implementation/schema.js.map +1 -0
  30. package/dist/implementation/subscriptionScope.js +19 -1
  31. package/dist/implementation/subscriptionScope.js.map +1 -1
  32. package/dist/implementation/symbols.js +5 -0
  33. package/dist/implementation/symbols.js.map +1 -0
  34. package/dist/index.js +3 -5
  35. package/dist/index.js.map +1 -1
  36. package/dist/internal.js +5 -2
  37. package/dist/internal.js.map +1 -1
  38. package/dist/tests/coList.test.js +51 -48
  39. package/dist/tests/coList.test.js.map +1 -1
  40. package/dist/tests/coMap.test.js +131 -73
  41. package/dist/tests/coMap.test.js.map +1 -1
  42. package/dist/tests/coStream.test.js +56 -41
  43. package/dist/tests/coStream.test.js.map +1 -1
  44. package/dist/tests/deepLoading.test.js +188 -0
  45. package/dist/tests/deepLoading.test.js.map +1 -0
  46. package/dist/tests/groupsAndAccounts.test.js +83 -0
  47. package/dist/tests/groupsAndAccounts.test.js.map +1 -0
  48. package/package.json +17 -9
  49. package/src/coValues/account.ts +113 -125
  50. package/src/coValues/coList.ts +87 -103
  51. package/src/coValues/coMap.ts +200 -147
  52. package/src/coValues/coStream.ts +264 -80
  53. package/src/coValues/deepLoading.ts +229 -0
  54. package/src/coValues/extensions/imageDef.ts +17 -13
  55. package/src/coValues/group.ts +92 -58
  56. package/src/coValues/interfaces.ts +215 -115
  57. package/src/implementation/devtoolsFormatters.ts +110 -0
  58. package/src/implementation/inspect.ts +1 -1
  59. package/src/implementation/refs.ts +80 -28
  60. package/src/implementation/schema.ts +138 -0
  61. package/src/implementation/subscriptionScope.ts +48 -12
  62. package/src/implementation/symbols.ts +11 -0
  63. package/src/index.ts +12 -8
  64. package/src/internal.ts +7 -3
  65. package/src/tests/coList.test.ts +77 -62
  66. package/src/tests/coMap.test.ts +201 -113
  67. package/src/tests/coStream.test.ts +113 -84
  68. package/src/tests/deepLoading.test.ts +301 -0
  69. package/src/tests/groupsAndAccounts.test.ts +91 -0
  70. package/dist/implementation/encoding.js +0 -26
  71. package/dist/implementation/encoding.js.map +0 -1
  72. 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
  });