on-zero 0.4.26 → 0.4.28

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 (123) hide show
  1. package/dist/cjs/createZeroClient.cjs +14 -1
  2. package/dist/cjs/createZeroClient.native.js +15 -1
  3. package/dist/cjs/createZeroClient.native.js.map +1 -1
  4. package/dist/cjs/httpPull/auth.test.cjs +197 -0
  5. package/dist/cjs/httpPull/auth.test.native.js +279 -0
  6. package/dist/cjs/httpPull/auth.test.native.js.map +1 -0
  7. package/dist/cjs/httpPull/churn.test.cjs +132 -0
  8. package/dist/cjs/httpPull/churn.test.native.js +155 -0
  9. package/dist/cjs/httpPull/churn.test.native.js.map +1 -0
  10. package/dist/cjs/httpPull/fixtureSchema.cjs +76 -0
  11. package/dist/cjs/httpPull/fixtureSchema.native.js +82 -0
  12. package/dist/cjs/httpPull/fixtureSchema.native.js.map +1 -0
  13. package/dist/cjs/httpPull/fixtureServer.cjs +340 -0
  14. package/dist/cjs/httpPull/fixtureServer.native.js +534 -0
  15. package/dist/cjs/httpPull/fixtureServer.native.js.map +1 -0
  16. package/dist/cjs/httpPull/integration.test.cjs +53 -0
  17. package/dist/cjs/httpPull/integration.test.native.js +60 -0
  18. package/dist/cjs/httpPull/integration.test.native.js.map +1 -0
  19. package/dist/cjs/httpPull/rebase.test.cjs +360 -0
  20. package/dist/cjs/httpPull/rebase.test.native.js +420 -0
  21. package/dist/cjs/httpPull/rebase.test.native.js.map +1 -0
  22. package/dist/cjs/httpPull/relations.test.cjs +107 -0
  23. package/dist/cjs/httpPull/relations.test.native.js +119 -0
  24. package/dist/cjs/httpPull/relations.test.native.js.map +1 -0
  25. package/dist/cjs/httpPull/testHarness.cjs +100 -0
  26. package/dist/cjs/httpPull/testHarness.native.js +112 -0
  27. package/dist/cjs/httpPull/testHarness.native.js.map +1 -0
  28. package/dist/cjs/httpPull/transport.test.cjs +588 -0
  29. package/dist/cjs/httpPull/transport.test.native.js +677 -0
  30. package/dist/cjs/httpPull/transport.test.native.js.map +1 -0
  31. package/dist/cjs/httpPullTransport.cjs +447 -0
  32. package/dist/cjs/httpPullTransport.native.js +710 -0
  33. package/dist/cjs/httpPullTransport.native.js.map +1 -0
  34. package/dist/cjs/index.cjs +1 -0
  35. package/dist/cjs/index.native.js +1 -0
  36. package/dist/cjs/index.native.js.map +1 -1
  37. package/dist/esm/createZeroClient.mjs +14 -1
  38. package/dist/esm/createZeroClient.mjs.map +1 -1
  39. package/dist/esm/createZeroClient.native.js +15 -1
  40. package/dist/esm/createZeroClient.native.js.map +1 -1
  41. package/dist/esm/httpPull/auth.test.mjs +198 -0
  42. package/dist/esm/httpPull/auth.test.mjs.map +1 -0
  43. package/dist/esm/httpPull/auth.test.native.js +277 -0
  44. package/dist/esm/httpPull/auth.test.native.js.map +1 -0
  45. package/dist/esm/httpPull/churn.test.mjs +133 -0
  46. package/dist/esm/httpPull/churn.test.mjs.map +1 -0
  47. package/dist/esm/httpPull/churn.test.native.js +153 -0
  48. package/dist/esm/httpPull/churn.test.native.js.map +1 -0
  49. package/dist/esm/httpPull/fixtureSchema.mjs +50 -0
  50. package/dist/esm/httpPull/fixtureSchema.mjs.map +1 -0
  51. package/dist/esm/httpPull/fixtureSchema.native.js +53 -0
  52. package/dist/esm/httpPull/fixtureSchema.native.js.map +1 -0
  53. package/dist/esm/httpPull/fixtureServer.mjs +315 -0
  54. package/dist/esm/httpPull/fixtureServer.mjs.map +1 -0
  55. package/dist/esm/httpPull/fixtureServer.native.js +506 -0
  56. package/dist/esm/httpPull/fixtureServer.native.js.map +1 -0
  57. package/dist/esm/httpPull/integration.test.mjs +54 -0
  58. package/dist/esm/httpPull/integration.test.mjs.map +1 -0
  59. package/dist/esm/httpPull/integration.test.native.js +58 -0
  60. package/dist/esm/httpPull/integration.test.native.js.map +1 -0
  61. package/dist/esm/httpPull/rebase.test.mjs +361 -0
  62. package/dist/esm/httpPull/rebase.test.mjs.map +1 -0
  63. package/dist/esm/httpPull/rebase.test.native.js +418 -0
  64. package/dist/esm/httpPull/rebase.test.native.js.map +1 -0
  65. package/dist/esm/httpPull/relations.test.mjs +108 -0
  66. package/dist/esm/httpPull/relations.test.mjs.map +1 -0
  67. package/dist/esm/httpPull/relations.test.native.js +117 -0
  68. package/dist/esm/httpPull/relations.test.native.js.map +1 -0
  69. package/dist/esm/httpPull/testHarness.mjs +72 -0
  70. package/dist/esm/httpPull/testHarness.mjs.map +1 -0
  71. package/dist/esm/httpPull/testHarness.native.js +81 -0
  72. package/dist/esm/httpPull/testHarness.native.js.map +1 -0
  73. package/dist/esm/httpPull/transport.test.mjs +589 -0
  74. package/dist/esm/httpPull/transport.test.mjs.map +1 -0
  75. package/dist/esm/httpPull/transport.test.native.js +675 -0
  76. package/dist/esm/httpPull/transport.test.native.js.map +1 -0
  77. package/dist/esm/httpPullTransport.mjs +421 -0
  78. package/dist/esm/httpPullTransport.mjs.map +1 -0
  79. package/dist/esm/httpPullTransport.native.js +681 -0
  80. package/dist/esm/httpPullTransport.native.js.map +1 -0
  81. package/dist/esm/index.js +1 -0
  82. package/dist/esm/index.js.map +1 -1
  83. package/dist/esm/index.mjs +1 -0
  84. package/dist/esm/index.mjs.map +1 -1
  85. package/dist/esm/index.native.js +1 -0
  86. package/dist/esm/index.native.js.map +1 -1
  87. package/package.json +2 -2
  88. package/src/createZeroClient.tsx +22 -0
  89. package/src/httpPull/auth.test.ts +208 -0
  90. package/src/httpPull/churn.test.ts +147 -0
  91. package/src/httpPull/fixtureSchema.ts +82 -0
  92. package/src/httpPull/fixtureServer.ts +391 -0
  93. package/src/httpPull/integration.test.ts +57 -0
  94. package/src/httpPull/rebase.test.ts +368 -0
  95. package/src/httpPull/relations.test.ts +135 -0
  96. package/src/httpPull/testHarness.ts +95 -0
  97. package/src/httpPull/transport.test.ts +603 -0
  98. package/src/httpPullTransport.ts +587 -0
  99. package/src/index.ts +1 -0
  100. package/types/createZeroClient.d.ts +3 -1
  101. package/types/createZeroClient.d.ts.map +1 -1
  102. package/types/httpPull/auth.test.d.ts +2 -0
  103. package/types/httpPull/auth.test.d.ts.map +1 -0
  104. package/types/httpPull/churn.test.d.ts +2 -0
  105. package/types/httpPull/churn.test.d.ts.map +1 -0
  106. package/types/httpPull/fixtureSchema.d.ts +111 -0
  107. package/types/httpPull/fixtureSchema.d.ts.map +1 -0
  108. package/types/httpPull/fixtureServer.d.ts +14 -0
  109. package/types/httpPull/fixtureServer.d.ts.map +1 -0
  110. package/types/httpPull/integration.test.d.ts +2 -0
  111. package/types/httpPull/integration.test.d.ts.map +1 -0
  112. package/types/httpPull/rebase.test.d.ts +2 -0
  113. package/types/httpPull/rebase.test.d.ts.map +1 -0
  114. package/types/httpPull/relations.test.d.ts +2 -0
  115. package/types/httpPull/relations.test.d.ts.map +1 -0
  116. package/types/httpPull/testHarness.d.ts +32 -0
  117. package/types/httpPull/testHarness.d.ts.map +1 -0
  118. package/types/httpPull/transport.test.d.ts +2 -0
  119. package/types/httpPull/transport.test.d.ts.map +1 -0
  120. package/types/httpPullTransport.d.ts +13 -0
  121. package/types/httpPullTransport.d.ts.map +1 -0
  122. package/types/index.d.ts +1 -0
  123. package/types/index.d.ts.map +1 -1
@@ -0,0 +1,418 @@
1
+ import { afterEach, expect, test } from "vitest";
2
+ import { eventually, startZeroHttpHarness, waitForComplete } from "./testHarness.native.js";
3
+ var harness;
4
+ afterEach(async function () {
5
+ await (harness === null || harness === void 0 ? void 0 : harness.close());
6
+ harness = void 0;
7
+ });
8
+ test("ack-then-pull keeps optimistic rows visible until the authoritative snapshot lands", async function () {
9
+ var postPushPull = deferred();
10
+ var postPushPullStarted = deferred();
11
+ var shouldHoldPostPushPull = false;
12
+ harness = await startZeroHttpHarness({
13
+ seed: {
14
+ user: [{
15
+ id: "u1",
16
+ name: "ada"
17
+ }],
18
+ project: [{
19
+ id: "p1",
20
+ ownerId: "u1",
21
+ name: "first"
22
+ }],
23
+ member: []
24
+ },
25
+ interceptFetch: function (next) {
26
+ return async function (input, init) {
27
+ var path = new URL(String(input)).pathname;
28
+ if (path === "/push") {
29
+ var response = await next(input, init);
30
+ shouldHoldPostPushPull = true;
31
+ return response;
32
+ }
33
+ if (path === "/pull" && shouldHoldPostPushPull) {
34
+ shouldHoldPostPushPull = false;
35
+ postPushPullStarted.resolve();
36
+ await postPushPull.promise;
37
+ }
38
+ return next(input, init);
39
+ };
40
+ }
41
+ });
42
+ var zero = harness.createZero("u1");
43
+ var view = zero.query.project.materialize();
44
+ await waitForComplete(view);
45
+ var emissions = recordEmissions(view);
46
+ var mutation = zero.mutate.project.create({
47
+ id: "p2",
48
+ ownerId: "u1",
49
+ name: "second"
50
+ });
51
+ await mutation.client;
52
+ await eventually(function () {
53
+ return expect(projectIDs(view.data)).toContain("p2");
54
+ });
55
+ await mutation.server;
56
+ await postPushPullStarted.promise;
57
+ expect(projectIDs(view.data)).toContain("p2");
58
+ postPushPull.resolve();
59
+ await harness.transport.pull();
60
+ await eventually(function () {
61
+ return expect(projectIDs(view.data).sort()).toEqual(["p1", "p2"]);
62
+ });
63
+ expectNeverDisappearsAfterFirstSeen(emissions, "p2");
64
+ expect(harness.server.rows("project").sort(byID)).toEqual([{
65
+ id: "p1",
66
+ ownerId: "u1",
67
+ name: "first"
68
+ }, {
69
+ id: "p2",
70
+ ownerId: "u1",
71
+ name: "second"
72
+ }]);
73
+ emissions.cleanup();
74
+ view.destroy();
75
+ });
76
+ test("pull-then-ack rebases optimistic rows over a newer snapshot", async function () {
77
+ var pushGate = deferred();
78
+ var pushStarted = deferred();
79
+ harness = await startZeroHttpHarness({
80
+ seed: {
81
+ user: [{
82
+ id: "u1",
83
+ name: "ada"
84
+ }],
85
+ project: [{
86
+ id: "p1",
87
+ ownerId: "u1",
88
+ name: "first"
89
+ }],
90
+ member: []
91
+ },
92
+ interceptFetch: function (next) {
93
+ return async function (input, init) {
94
+ var path = new URL(String(input)).pathname;
95
+ if (path === "/push") {
96
+ var body = JSON.parse(String(init === null || init === void 0 ? void 0 : init.body));
97
+ pushStarted.resolve(body);
98
+ await pushGate.promise;
99
+ }
100
+ return next(input, init);
101
+ };
102
+ }
103
+ });
104
+ var zero = harness.createZero("u1");
105
+ var view = zero.query.project.materialize();
106
+ await waitForComplete(view);
107
+ var emissions = recordEmissions(view);
108
+ var mutation = zero.mutate.project.create({
109
+ id: "p2",
110
+ ownerId: "u1",
111
+ name: "optimistic"
112
+ });
113
+ await mutation.client;
114
+ await eventually(function () {
115
+ return expect(projectIDs(view.data)).toContain("p2");
116
+ });
117
+ var heldPush = await pushStarted.promise;
118
+ await rawPush(harness, {
119
+ clientGroupID: heldPush.clientGroupID,
120
+ clientID: "server-side",
121
+ id: 1,
122
+ name: "project|create",
123
+ args: {
124
+ id: "p-server",
125
+ ownerId: "u1",
126
+ name: "server change"
127
+ }
128
+ });
129
+ await harness.transport.pull();
130
+ await eventually(function () {
131
+ return expect(projectIDs(view.data).sort()).toEqual(["p-server", "p1", "p2"]);
132
+ });
133
+ expect(harness.server.rows("project").map(function (row) {
134
+ return row.id;
135
+ }).sort()).toEqual(["p-server", "p1"]);
136
+ pushGate.resolve();
137
+ await mutation.server;
138
+ await harness.transport.pull();
139
+ await eventually(function () {
140
+ return expect(projectIDs(view.data).sort()).toEqual(["p-server", "p1", "p2"]);
141
+ });
142
+ expectNeverDisappearsAfterFirstSeen(emissions, "p2");
143
+ expect(harness.server.rows("project").sort(byID)).toEqual([{
144
+ id: "p-server",
145
+ ownerId: "u1",
146
+ name: "server change"
147
+ }, {
148
+ id: "p1",
149
+ ownerId: "u1",
150
+ name: "first"
151
+ }, {
152
+ id: "p2",
153
+ ownerId: "u1",
154
+ name: "optimistic"
155
+ }]);
156
+ emissions.cleanup();
157
+ view.destroy();
158
+ });
159
+ test("app-error rollback advances LMID and reverts optimistic state after pull", async function () {
160
+ var _emissions_values_at;
161
+ var pushGate = deferred();
162
+ var pushStarted = deferred();
163
+ var clientGroupID = "";
164
+ harness = await startZeroHttpHarness({
165
+ seed: {
166
+ user: [{
167
+ id: "u1",
168
+ name: "ada"
169
+ }, {
170
+ id: "u2",
171
+ name: "ben"
172
+ }],
173
+ project: [{
174
+ id: "p1",
175
+ ownerId: "u2",
176
+ name: "shared"
177
+ }],
178
+ member: [{
179
+ id: "m1",
180
+ projectId: "p1",
181
+ userId: "u1"
182
+ }]
183
+ },
184
+ interceptFetch: function (next) {
185
+ return async function (input, init) {
186
+ if (new URL(String(input)).pathname === "/push") {
187
+ var body = JSON.parse(String(init === null || init === void 0 ? void 0 : init.body));
188
+ clientGroupID = body.clientGroupID;
189
+ pushStarted.resolve();
190
+ await pushGate.promise;
191
+ }
192
+ return next(input, init);
193
+ };
194
+ }
195
+ });
196
+ var zero = harness.createZero("u1");
197
+ var view = zero.query.project.materialize();
198
+ await waitForComplete(view);
199
+ var emissions = recordEmissions(view);
200
+ var mutation = zero.mutate.project.rename({
201
+ id: "p1",
202
+ name: "stolen"
203
+ });
204
+ await mutation.client;
205
+ await pushStarted.promise;
206
+ expect(projectName(view.data, "p1")).toBe("stolen");
207
+ expect(harness.server.rows("project")).toEqual([{
208
+ id: "p1",
209
+ ownerId: "u2",
210
+ name: "shared"
211
+ }]);
212
+ pushGate.resolve();
213
+ await expect(mutation.server).resolves.toMatchObject({
214
+ type: "error",
215
+ error: {
216
+ type: "app",
217
+ details: "forbidden"
218
+ }
219
+ });
220
+ await harness.transport.pull();
221
+ await eventually(function () {
222
+ return expect(projectName(view.data, "p1")).toBe("shared");
223
+ });
224
+ expect(emissions.values.map(function (rows) {
225
+ return projectName(rows, "p1");
226
+ })).toContain("stolen");
227
+ expect((_emissions_values_at = emissions.values.at(-1)) === null || _emissions_values_at === void 0 ? void 0 : _emissions_values_at[0]).toEqual({
228
+ id: "p1",
229
+ ownerId: "u2",
230
+ name: "shared"
231
+ });
232
+ expect(harness.server.rows("project")).toEqual([{
233
+ id: "p1",
234
+ ownerId: "u2",
235
+ name: "shared"
236
+ }]);
237
+ var pull = await rawPull(harness, "u1", {
238
+ clientGroupID
239
+ });
240
+ expect(Object.values(pull.lastMutationIDChanges)).toContain(1);
241
+ emissions.cleanup();
242
+ view.destroy();
243
+ });
244
+ test("app-error rollback removes phantom optimistic create after pull", async function () {
245
+ var pushGate = deferred();
246
+ var pushStarted = deferred();
247
+ var clientGroupID = "";
248
+ harness = await startZeroHttpHarness({
249
+ seed: {
250
+ user: [{
251
+ id: "u1",
252
+ name: "ada"
253
+ }, {
254
+ id: "u2",
255
+ name: "ben"
256
+ }],
257
+ project: [],
258
+ member: []
259
+ },
260
+ interceptFetch: function (next) {
261
+ return async function (input, init) {
262
+ if (new URL(String(input)).pathname === "/push") {
263
+ var body = JSON.parse(String(init === null || init === void 0 ? void 0 : init.body));
264
+ clientGroupID = body.clientGroupID;
265
+ pushStarted.resolve();
266
+ await pushGate.promise;
267
+ }
268
+ return next(input, init);
269
+ };
270
+ }
271
+ });
272
+ var zero = harness.createZero("u1");
273
+ var view = zero.query.project.materialize();
274
+ await waitForComplete(view);
275
+ var emissions = recordEmissions(view);
276
+ var mutation = zero.mutate.project.create({
277
+ id: "p-phantom",
278
+ ownerId: "u2",
279
+ name: "forbidden"
280
+ });
281
+ await mutation.client;
282
+ await pushStarted.promise;
283
+ await eventually(function () {
284
+ return expect(projectIDs(view.data)).toContain("p-phantom");
285
+ });
286
+ expect(harness.server.rows("project")).toEqual([]);
287
+ pushGate.resolve();
288
+ await expect(mutation.server).resolves.toMatchObject({
289
+ type: "error",
290
+ error: {
291
+ type: "app",
292
+ details: "forbidden"
293
+ }
294
+ });
295
+ await harness.transport.pull();
296
+ await eventually(function () {
297
+ return expect(projectIDs(view.data)).not.toContain("p-phantom");
298
+ });
299
+ expect(emissions.values.some(function (rows) {
300
+ return projectIDs(rows).includes("p-phantom");
301
+ })).toBe(true);
302
+ expect(emissions.values.at(-1)).toEqual([]);
303
+ expect(harness.server.rows("project")).toEqual([]);
304
+ var pull = await rawPull(harness, "u1", {
305
+ clientGroupID
306
+ });
307
+ expect(Object.values(pull.lastMutationIDChanges)).toContain(1);
308
+ emissions.cleanup();
309
+ view.destroy();
310
+ });
311
+ async function rawPush(harness2, mutation) {
312
+ var response = await fetch(`${harness2.server.url}/push`, {
313
+ method: "POST",
314
+ headers: {
315
+ authorization: "Bearer token-u1",
316
+ "content-type": "application/json"
317
+ },
318
+ body: JSON.stringify({
319
+ timestamp: Date.now(),
320
+ clientGroupID: mutation.clientGroupID,
321
+ pushVersion: 1,
322
+ requestID: `raw-${mutation.clientID}-${mutation.id}`,
323
+ mutations: [{
324
+ type: "custom",
325
+ name: mutation.name,
326
+ id: mutation.id,
327
+ clientID: mutation.clientID,
328
+ args: [mutation.args]
329
+ }]
330
+ })
331
+ });
332
+ expect(response.status).toBe(200);
333
+ return response.json();
334
+ }
335
+ async function rawPull(harness2, userID, body) {
336
+ var response = await fetch(`${harness2.server.url}/pull`, {
337
+ method: "POST",
338
+ headers: {
339
+ authorization: `Bearer token-${userID}`,
340
+ "content-type": "application/json"
341
+ },
342
+ body: JSON.stringify({
343
+ clientID: "raw-pull",
344
+ clientGroupID: body.clientGroupID,
345
+ cookie: null
346
+ })
347
+ });
348
+ expect(response.status).toBe(200);
349
+ return response.json();
350
+ }
351
+ function recordEmissions(view) {
352
+ var values = [];
353
+ var cleanup = view.addListener(function (data) {
354
+ return values.push(snapshot(data));
355
+ });
356
+ return {
357
+ values,
358
+ cleanup
359
+ };
360
+ }
361
+ function snapshot(rows) {
362
+ return JSON.parse(JSON.stringify(rows));
363
+ }
364
+ function projectIDs(rows) {
365
+ return rows.map(function (row) {
366
+ return row.id;
367
+ });
368
+ }
369
+ function projectName(rows, id) {
370
+ var _rows_find;
371
+ return (_rows_find = rows.find(function (row) {
372
+ return row.id === id;
373
+ })) === null || _rows_find === void 0 ? void 0 : _rows_find.name;
374
+ }
375
+ function expectNeverDisappearsAfterFirstSeen(emissions, id) {
376
+ var seen = false;
377
+ var _iteratorNormalCompletion = true,
378
+ _didIteratorError = false,
379
+ _iteratorError = void 0;
380
+ try {
381
+ for (var _iterator = emissions.values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
382
+ var rows = _step.value;
383
+ if (projectIDs(rows).includes(id)) seen = true;
384
+ if (seen) expect(projectIDs(rows)).toContain(id);
385
+ }
386
+ } catch (err) {
387
+ _didIteratorError = true;
388
+ _iteratorError = err;
389
+ } finally {
390
+ try {
391
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
392
+ _iterator.return();
393
+ }
394
+ } finally {
395
+ if (_didIteratorError) {
396
+ throw _iteratorError;
397
+ }
398
+ }
399
+ }
400
+ expect(seen).toBe(true);
401
+ }
402
+ function byID(a, b) {
403
+ return a.id.localeCompare(b.id);
404
+ }
405
+ function deferred() {
406
+ var resolve;
407
+ var reject;
408
+ var promise = new Promise(function (res, rej) {
409
+ resolve = res;
410
+ reject = rej;
411
+ });
412
+ return {
413
+ promise,
414
+ resolve,
415
+ reject
416
+ };
417
+ }
418
+ //# sourceMappingURL=rebase.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["afterEach","expect","test","eventually","startZeroHttpHarness","waitForComplete","harness","close","postPushPull","deferred","postPushPullStarted","shouldHoldPostPushPull","seed","user","id","name","project","ownerId","member","interceptFetch","next","input","init","path","URL","String","pathname","response","resolve","promise","zero","createZero","view","query","materialize","emissions","recordEmissions","mutation","mutate","create","client","projectIDs","data","toContain","server","transport","pull","sort","toEqual","expectNeverDisappearsAfterFirstSeen","rows","byID","cleanup","destroy","pushGate","pushStarted","body","JSON","parse","heldPush","rawPush","clientGroupID","clientID","args","map","row","_emissions_values_at","projectId","userId","rename","projectName","toBe","resolves","toMatchObject","type","error","details","values","at","rawPull","Object","lastMutationIDChanges"],"sources":["../../../src/httpPull/rebase.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,108 @@
1
+ import { afterEach, expect, test } from "vitest";
2
+ import { eventually, sleep, startZeroHttpHarness, waitForComplete } from "./testHarness.mjs";
3
+ let harness;
4
+ afterEach(async () => {
5
+ await harness?.close();
6
+ harness = void 0;
7
+ });
8
+ test("related project members appear, update, and vanish with visibility", async () => {
9
+ harness = await startZeroHttpHarness({
10
+ seed: {
11
+ user: [{
12
+ id: "u1",
13
+ name: "ada"
14
+ }, {
15
+ id: "u2",
16
+ name: "ben"
17
+ }],
18
+ project: [],
19
+ member: []
20
+ }
21
+ });
22
+ const u1 = harness.createZero("u1");
23
+ const u2 = harness.createZero("u2");
24
+ const u1Projects = u1.query.project.related("members").materialize();
25
+ const emissions = [];
26
+ const stopCapture = captureProjectEmissions(u1Projects, emissions);
27
+ try {
28
+ await expect(waitForComplete(u1Projects)).resolves.toEqual([]);
29
+ const created = u2.mutate.project.create({
30
+ id: "p-shared",
31
+ ownerId: "u2",
32
+ name: "shared"
33
+ });
34
+ await created.client;
35
+ await created.server;
36
+ const added = u2.mutate.member.add({
37
+ id: "m-u1-shared",
38
+ projectId: "p-shared",
39
+ userId: "u1"
40
+ });
41
+ await added.client;
42
+ await added.server;
43
+ await harness.transport.pull();
44
+ await eventually(() => {
45
+ expect(normalizeProjects(u1Projects.data)).toEqual([{
46
+ id: "p-shared",
47
+ ownerId: "u2",
48
+ name: "shared",
49
+ members: [{
50
+ id: "m-u1-shared",
51
+ projectId: "p-shared",
52
+ userId: "u1"
53
+ }]
54
+ }]);
55
+ });
56
+ const renamed = u2.mutate.project.rename({
57
+ id: "p-shared",
58
+ name: "renamed shared"
59
+ });
60
+ await renamed.client;
61
+ await renamed.server;
62
+ await harness.transport.pull();
63
+ await eventually(() => {
64
+ expect(normalizeProjects(u1Projects.data)).toEqual([{
65
+ id: "p-shared",
66
+ ownerId: "u2",
67
+ name: "renamed shared",
68
+ members: [{
69
+ id: "m-u1-shared",
70
+ projectId: "p-shared",
71
+ userId: "u1"
72
+ }]
73
+ }]);
74
+ });
75
+ const removed = u2.mutate.member.remove({
76
+ id: "m-u1-shared"
77
+ });
78
+ await removed.client;
79
+ await removed.server;
80
+ await harness.transport.pull();
81
+ await eventually(() => {
82
+ expect(normalizeProjects(u1Projects.data)).toEqual([]);
83
+ expect(emissions.at(-1)?.some(project => project.id === "p-shared")).toBe(false);
84
+ });
85
+ const emissionCountAfterRevocation = emissions.length;
86
+ await harness.transport.pull();
87
+ await sleep(50);
88
+ expect(emissions.length).toBe(emissionCountAfterRevocation);
89
+ } finally {
90
+ stopCapture();
91
+ u1Projects.destroy();
92
+ }
93
+ });
94
+ function captureProjectEmissions(view, emissions) {
95
+ return view.addListener(data => {
96
+ emissions.push(normalizeProjects(data));
97
+ });
98
+ }
99
+ function normalizeProjects(projects) {
100
+ return clone(projects).map(project => ({
101
+ ...project,
102
+ members: [...project.members].sort((a, b) => a.id.localeCompare(b.id))
103
+ })).sort((a, b) => a.id.localeCompare(b.id));
104
+ }
105
+ function clone(value) {
106
+ return JSON.parse(JSON.stringify(value));
107
+ }
108
+ //# sourceMappingURL=relations.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["afterEach","expect","test","eventually","sleep","startZeroHttpHarness","waitForComplete","harness","close","seed","user","id","name","project","member","u1","createZero","u2","u1Projects","query","related","materialize","emissions","stopCapture","captureProjectEmissions","resolves","toEqual","created","mutate","create","ownerId","client","server","added","add","projectId","userId","transport","pull","normalizeProjects","data","members","renamed","rename","removed","remove","at","some","toBe","emissionCountAfterRevocation","length","destroy","view","addListener","push","projects","clone","map","sort","a","b","localeCompare","value","JSON","parse","stringify"],"sources":["../../../src/httpPull/relations.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,117 @@
1
+ import { afterEach, expect, test } from "vitest";
2
+ import { eventually, sleep, startZeroHttpHarness, waitForComplete } from "./testHarness.native.js";
3
+ var harness;
4
+ afterEach(async function () {
5
+ await (harness === null || harness === void 0 ? void 0 : harness.close());
6
+ harness = void 0;
7
+ });
8
+ test("related project members appear, update, and vanish with visibility", async function () {
9
+ harness = await startZeroHttpHarness({
10
+ seed: {
11
+ user: [{
12
+ id: "u1",
13
+ name: "ada"
14
+ }, {
15
+ id: "u2",
16
+ name: "ben"
17
+ }],
18
+ project: [],
19
+ member: []
20
+ }
21
+ });
22
+ var u1 = harness.createZero("u1");
23
+ var u2 = harness.createZero("u2");
24
+ var u1Projects = u1.query.project.related("members").materialize();
25
+ var emissions = [];
26
+ var stopCapture = captureProjectEmissions(u1Projects, emissions);
27
+ try {
28
+ await expect(waitForComplete(u1Projects)).resolves.toEqual([]);
29
+ var created = u2.mutate.project.create({
30
+ id: "p-shared",
31
+ ownerId: "u2",
32
+ name: "shared"
33
+ });
34
+ await created.client;
35
+ await created.server;
36
+ var added = u2.mutate.member.add({
37
+ id: "m-u1-shared",
38
+ projectId: "p-shared",
39
+ userId: "u1"
40
+ });
41
+ await added.client;
42
+ await added.server;
43
+ await harness.transport.pull();
44
+ await eventually(function () {
45
+ expect(normalizeProjects(u1Projects.data)).toEqual([{
46
+ id: "p-shared",
47
+ ownerId: "u2",
48
+ name: "shared",
49
+ members: [{
50
+ id: "m-u1-shared",
51
+ projectId: "p-shared",
52
+ userId: "u1"
53
+ }]
54
+ }]);
55
+ });
56
+ var renamed = u2.mutate.project.rename({
57
+ id: "p-shared",
58
+ name: "renamed shared"
59
+ });
60
+ await renamed.client;
61
+ await renamed.server;
62
+ await harness.transport.pull();
63
+ await eventually(function () {
64
+ expect(normalizeProjects(u1Projects.data)).toEqual([{
65
+ id: "p-shared",
66
+ ownerId: "u2",
67
+ name: "renamed shared",
68
+ members: [{
69
+ id: "m-u1-shared",
70
+ projectId: "p-shared",
71
+ userId: "u1"
72
+ }]
73
+ }]);
74
+ });
75
+ var removed = u2.mutate.member.remove({
76
+ id: "m-u1-shared"
77
+ });
78
+ await removed.client;
79
+ await removed.server;
80
+ await harness.transport.pull();
81
+ await eventually(function () {
82
+ var _emissions_at;
83
+ expect(normalizeProjects(u1Projects.data)).toEqual([]);
84
+ expect((_emissions_at = emissions.at(-1)) === null || _emissions_at === void 0 ? void 0 : _emissions_at.some(function (project) {
85
+ return project.id === "p-shared";
86
+ })).toBe(false);
87
+ });
88
+ var emissionCountAfterRevocation = emissions.length;
89
+ await harness.transport.pull();
90
+ await sleep(50);
91
+ expect(emissions.length).toBe(emissionCountAfterRevocation);
92
+ } finally {
93
+ stopCapture();
94
+ u1Projects.destroy();
95
+ }
96
+ });
97
+ function captureProjectEmissions(view, emissions) {
98
+ return view.addListener(function (data) {
99
+ emissions.push(normalizeProjects(data));
100
+ });
101
+ }
102
+ function normalizeProjects(projects) {
103
+ return clone(projects).map(function (project) {
104
+ return {
105
+ ...project,
106
+ members: [...project.members].sort(function (a, b) {
107
+ return a.id.localeCompare(b.id);
108
+ })
109
+ };
110
+ }).sort(function (a, b) {
111
+ return a.id.localeCompare(b.id);
112
+ });
113
+ }
114
+ function clone(value) {
115
+ return JSON.parse(JSON.stringify(value));
116
+ }
117
+ //# sourceMappingURL=relations.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["afterEach","expect","test","eventually","sleep","startZeroHttpHarness","waitForComplete","harness","close","seed","user","id","name","project","member","u1","createZero","u2","u1Projects","query","related","materialize","emissions","stopCapture","captureProjectEmissions","resolves","toEqual","created","mutate","create","ownerId","client","server","added","add","projectId","userId","transport","pull","normalizeProjects","data","members","renamed","rename","removed","remove","_emissions_at","at","some","toBe","emissionCountAfterRevocation","length"],"sources":["../../../src/httpPull/relations.test.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}