on-zero 0.6.17 → 0.6.19

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 (114) hide show
  1. package/dist/cjs/asyncTasks.native.js.map +1 -1
  2. package/dist/cjs/createZeroClient.cjs +1 -1
  3. package/dist/cjs/createZeroClient.connection.test.cjs +29 -0
  4. package/dist/cjs/createZeroClient.connection.test.native.js +29 -0
  5. package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
  6. package/dist/cjs/createZeroClient.native.js +1 -1
  7. package/dist/cjs/createZeroClient.native.js.map +1 -1
  8. package/dist/cjs/createZeroDirectServer.cjs +1 -1
  9. package/dist/cjs/createZeroDirectServer.native.js +1 -1
  10. package/dist/cjs/createZeroDirectServer.native.js.map +1 -1
  11. package/dist/cjs/createZeroServer.test.cjs +6 -0
  12. package/dist/cjs/createZeroServer.test.native.js +6 -0
  13. package/dist/cjs/createZeroServer.test.native.js.map +1 -1
  14. package/dist/cjs/createZeroServerCore.cjs +29 -1
  15. package/dist/cjs/createZeroServerCore.native.js +153 -1
  16. package/dist/cjs/createZeroServerCore.native.js.map +1 -1
  17. package/dist/cjs/httpPull/transport.test.cjs +127 -15
  18. package/dist/cjs/httpPull/transport.test.native.js +161 -16
  19. package/dist/cjs/httpPull/transport.test.native.js.map +1 -1
  20. package/dist/cjs/httpPullTransport.cjs +48 -18
  21. package/dist/cjs/httpPullTransport.native.js +57 -20
  22. package/dist/cjs/httpPullTransport.native.js.map +1 -1
  23. package/dist/cjs/modelRegistry.cjs +7 -4
  24. package/dist/cjs/modelRegistry.native.js +8 -4
  25. package/dist/cjs/modelRegistry.native.js.map +1 -1
  26. package/dist/cjs/mutations.cjs +15 -11
  27. package/dist/cjs/mutations.native.js +17 -11
  28. package/dist/cjs/mutations.native.js.map +1 -1
  29. package/dist/cjs/state.cjs +2 -3
  30. package/dist/cjs/state.native.js +2 -3
  31. package/dist/cjs/state.native.js.map +1 -1
  32. package/dist/cjs/syncHost.cjs +2 -1
  33. package/dist/cjs/syncHost.native.js +2 -1
  34. package/dist/cjs/syncHost.native.js.map +1 -1
  35. package/dist/cjs/usePermission.test.cjs +4 -2
  36. package/dist/cjs/usePermission.test.native.js +4 -2
  37. package/dist/cjs/usePermission.test.native.js.map +1 -1
  38. package/dist/esm/asyncTasks.mjs.map +1 -1
  39. package/dist/esm/asyncTasks.native.js.map +1 -1
  40. package/dist/esm/createZeroClient.connection.test.mjs +29 -0
  41. package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
  42. package/dist/esm/createZeroClient.connection.test.native.js +29 -0
  43. package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
  44. package/dist/esm/createZeroClient.mjs +2 -2
  45. package/dist/esm/createZeroClient.mjs.map +1 -1
  46. package/dist/esm/createZeroClient.native.js +2 -2
  47. package/dist/esm/createZeroClient.native.js.map +1 -1
  48. package/dist/esm/createZeroDirectServer.mjs +2 -2
  49. package/dist/esm/createZeroDirectServer.mjs.map +1 -1
  50. package/dist/esm/createZeroDirectServer.native.js +2 -2
  51. package/dist/esm/createZeroDirectServer.native.js.map +1 -1
  52. package/dist/esm/createZeroServer.test.mjs +6 -0
  53. package/dist/esm/createZeroServer.test.mjs.map +1 -1
  54. package/dist/esm/createZeroServer.test.native.js +6 -0
  55. package/dist/esm/createZeroServer.test.native.js.map +1 -1
  56. package/dist/esm/createZeroServerCore.mjs +29 -1
  57. package/dist/esm/createZeroServerCore.mjs.map +1 -1
  58. package/dist/esm/createZeroServerCore.native.js +153 -1
  59. package/dist/esm/createZeroServerCore.native.js.map +1 -1
  60. package/dist/esm/httpPull/transport.test.mjs +127 -15
  61. package/dist/esm/httpPull/transport.test.mjs.map +1 -1
  62. package/dist/esm/httpPull/transport.test.native.js +161 -16
  63. package/dist/esm/httpPull/transport.test.native.js.map +1 -1
  64. package/dist/esm/httpPullTransport.mjs +48 -18
  65. package/dist/esm/httpPullTransport.mjs.map +1 -1
  66. package/dist/esm/httpPullTransport.native.js +57 -20
  67. package/dist/esm/httpPullTransport.native.js.map +1 -1
  68. package/dist/esm/modelRegistry.mjs +7 -4
  69. package/dist/esm/modelRegistry.mjs.map +1 -1
  70. package/dist/esm/modelRegistry.native.js +8 -4
  71. package/dist/esm/modelRegistry.native.js.map +1 -1
  72. package/dist/esm/mutations.mjs +15 -11
  73. package/dist/esm/mutations.mjs.map +1 -1
  74. package/dist/esm/mutations.native.js +17 -11
  75. package/dist/esm/mutations.native.js.map +1 -1
  76. package/dist/esm/state.mjs +2 -3
  77. package/dist/esm/state.mjs.map +1 -1
  78. package/dist/esm/state.native.js +2 -3
  79. package/dist/esm/state.native.js.map +1 -1
  80. package/dist/esm/syncHost.mjs +2 -1
  81. package/dist/esm/syncHost.mjs.map +1 -1
  82. package/dist/esm/syncHost.native.js +2 -1
  83. package/dist/esm/syncHost.native.js.map +1 -1
  84. package/dist/esm/usePermission.test.mjs +6 -4
  85. package/dist/esm/usePermission.test.mjs.map +1 -1
  86. package/dist/esm/usePermission.test.native.js +6 -4
  87. package/dist/esm/usePermission.test.native.js.map +1 -1
  88. package/package.json +2 -2
  89. package/src/asyncTasks.ts +4 -1
  90. package/src/createZeroClient.connection.test.tsx +32 -0
  91. package/src/createZeroClient.tsx +7 -2
  92. package/src/createZeroDirectServer.ts +2 -2
  93. package/src/createZeroServer.test.ts +10 -0
  94. package/src/createZeroServerCore.ts +38 -1
  95. package/src/httpPull/transport.test.ts +143 -16
  96. package/src/httpPullTransport.ts +67 -30
  97. package/src/modelRegistry.ts +9 -4
  98. package/src/mutations.ts +19 -15
  99. package/src/state.ts +3 -3
  100. package/src/syncHost.ts +2 -2
  101. package/src/usePermission.test.ts +9 -3
  102. package/test-fixtures/server-return-types.ts +13 -1
  103. package/types/asyncTasks.d.ts +5 -1
  104. package/types/asyncTasks.d.ts.map +1 -1
  105. package/types/createZeroClient.d.ts.map +1 -1
  106. package/types/createZeroServerCore.d.ts.map +1 -1
  107. package/types/httpPullTransport.d.ts +13 -0
  108. package/types/httpPullTransport.d.ts.map +1 -1
  109. package/types/modelRegistry.d.ts.map +1 -1
  110. package/types/mutations.d.ts.map +1 -1
  111. package/types/state.d.ts +2 -2
  112. package/types/state.d.ts.map +1 -1
  113. package/types/syncHost.d.ts +1 -1
  114. package/types/syncHost.d.ts.map +1 -1
@@ -33,11 +33,130 @@ var import_createZeroDirectServer = require("./createZeroDirectServer.native.js"
33
33
  var import_createMutators = require("./helpers/createMutators.native.js");
34
34
  var import_mutatorContext = require("./helpers/mutatorContext.native.js");
35
35
  var import_queryContext = require("./helpers/queryContext.native.js");
36
+ function _assert_this_initialized(self) {
37
+ if (self === void 0) {
38
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
39
+ }
40
+ return self;
41
+ }
42
+ function _call_super(_this, derived, args) {
43
+ derived = _get_prototype_of(derived);
44
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
45
+ }
46
+ function _class_call_check(instance, Constructor) {
47
+ if (!(instance instanceof Constructor)) {
48
+ throw new TypeError("Cannot call a class as a function");
49
+ }
50
+ }
51
+ function _construct(Parent, args, Class) {
52
+ if (_is_native_reflect_construct()) {
53
+ _construct = Reflect.construct;
54
+ } else {
55
+ _construct = function construct(Parent2, args2, Class2) {
56
+ var a = [null];
57
+ a.push.apply(a, args2);
58
+ var Constructor = Function.bind.apply(Parent2, a);
59
+ var instance = new Constructor();
60
+ if (Class2) _set_prototype_of(instance, Class2.prototype);
61
+ return instance;
62
+ };
63
+ }
64
+ return _construct.apply(null, arguments);
65
+ }
66
+ function _define_property(obj, key, value) {
67
+ if (key in obj) {
68
+ Object.defineProperty(obj, key, {
69
+ value,
70
+ enumerable: true,
71
+ configurable: true,
72
+ writable: true
73
+ });
74
+ } else {
75
+ obj[key] = value;
76
+ }
77
+ return obj;
78
+ }
79
+ function _get_prototype_of(o) {
80
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o2) {
81
+ return o2.__proto__ || Object.getPrototypeOf(o2);
82
+ };
83
+ return _get_prototype_of(o);
84
+ }
85
+ function _inherits(subClass, superClass) {
86
+ if (typeof superClass !== "function" && superClass !== null) {
87
+ throw new TypeError("Super expression must either be null or a function");
88
+ }
89
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
90
+ constructor: {
91
+ value: subClass,
92
+ writable: true,
93
+ configurable: true
94
+ }
95
+ });
96
+ if (superClass) _set_prototype_of(subClass, superClass);
97
+ }
98
+ function _instanceof(left, right) {
99
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
100
+ return !!right[Symbol.hasInstance](left);
101
+ } else {
102
+ return left instanceof right;
103
+ }
104
+ }
105
+ function _is_native_function(fn) {
106
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
107
+ }
108
+ function _possible_constructor_return(self, call) {
109
+ if (call && (_type_of(call) === "object" || typeof call === "function")) {
110
+ return call;
111
+ }
112
+ return _assert_this_initialized(self);
113
+ }
114
+ function _set_prototype_of(o, p) {
115
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o2, p2) {
116
+ o2.__proto__ = p2;
117
+ return o2;
118
+ };
119
+ return _set_prototype_of(o, p);
120
+ }
36
121
  function _type_of(obj) {
37
122
  "@swc/helpers - typeof";
38
123
 
39
124
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
40
125
  }
126
+ function _wrap_native_super(Class) {
127
+ var _cache = typeof Map === "function" ? /* @__PURE__ */new Map() : void 0;
128
+ _wrap_native_super = function wrapNativeSuper(Class2) {
129
+ if (Class2 === null || !_is_native_function(Class2)) return Class2;
130
+ if (typeof Class2 !== "function") {
131
+ throw new TypeError("Super expression must either be null or a function");
132
+ }
133
+ if (typeof _cache !== "undefined") {
134
+ if (_cache.has(Class2)) return _cache.get(Class2);
135
+ _cache.set(Class2, Wrapper);
136
+ }
137
+ function Wrapper() {
138
+ return _construct(Class2, arguments, _get_prototype_of(this).constructor);
139
+ }
140
+ Wrapper.prototype = Object.create(Class2.prototype, {
141
+ constructor: {
142
+ value: Wrapper,
143
+ enumerable: false,
144
+ writable: true,
145
+ configurable: true
146
+ }
147
+ });
148
+ return _set_prototype_of(Wrapper, Class2);
149
+ };
150
+ return _wrap_native_super(Class);
151
+ }
152
+ function _is_native_reflect_construct() {
153
+ try {
154
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
155
+ } catch (_) {}
156
+ return (_is_native_reflect_construct = function () {
157
+ return !!result;
158
+ })();
159
+ }
41
160
  function createZeroServerCore(param) {
42
161
  var {
43
162
  createDatabase,
@@ -159,7 +278,16 @@ function withTransactionLifecycle(database, lifecycle) {
159
278
  var value = await database.transaction(async function (tx, hooks) {
160
279
  lifecycle.beginAttempt();
161
280
  try {
162
- var result = await callback(tx, hooks);
281
+ var result = await callback(tx, {
282
+ ...hooks,
283
+ async updateClientMutationID() {
284
+ var result2 = await hooks.updateClientMutationID();
285
+ if (input && input.mutationID < result2.lastMutationID) {
286
+ throw new ExpectedDuplicateMutation(input.clientID, input.mutationID, result2.lastMutationID);
287
+ }
288
+ return result2;
289
+ }
290
+ });
163
291
  lifecycle.completeAttempt();
164
292
  return result;
165
293
  } catch (error) {
@@ -171,11 +299,35 @@ function withTransactionLifecycle(database, lifecycle) {
171
299
  return value;
172
300
  } catch (error) {
173
301
  lifecycle.rollbackTransaction();
302
+ if (_instanceof(error, ExpectedDuplicateMutation)) {
303
+ return {
304
+ id: {
305
+ clientID: error.clientID,
306
+ id: error.mutationID
307
+ },
308
+ result: {
309
+ error: "alreadyProcessed",
310
+ details: error.message
311
+ }
312
+ };
313
+ }
174
314
  throw error;
175
315
  }
176
316
  }
177
317
  };
178
318
  }
319
+ var ExpectedDuplicateMutation = /* @__PURE__ */function (Error1) {
320
+ "use strict";
321
+
322
+ _inherits(ExpectedDuplicateMutation2, Error1);
323
+ function ExpectedDuplicateMutation2(clientID, mutationID, expectedMutationID) {
324
+ _class_call_check(this, ExpectedDuplicateMutation2);
325
+ var _this;
326
+ _this = _call_super(this, ExpectedDuplicateMutation2, [`Ignoring mutation from ${clientID} with ID ${mutationID} as it was already processed. Expected: ${expectedMutationID}`]), _define_property(_this, "clientID", void 0), _define_property(_this, "mutationID", void 0), _this.clientID = clientID, _this.mutationID = mutationID;
327
+ return _this;
328
+ }
329
+ return ExpectedDuplicateMutation2;
330
+ }(_wrap_native_super(Error));
179
331
  async function parseAlreadyProcessed(request, response) {
180
332
  var mutations = alreadyProcessedMutations(response);
181
333
  if (mutations.length === 0) return;
@@ -1 +1 @@
1
- {"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","createZeroServerCore_exports","__export","createZeroServerCore","module","exports","import_server","require","import_asyncTasks","import_createZeroDirectServer","import_createMutators","import_mutatorContext","import_queryContext","_type_of","obj","Symbol","constructor","param","createDatabase","createServerActions","defaultAllowAdminRole","defaultMutateAuthData","models","mutations","mutationValidators","persistAlreadyProcessed","queries","schema","validateMutation","validateQuery","permissions","server","createZeroDirectServerRuntime","handleMutationRequest","param2","authData","request","scheduleBackgroundTask","skipAsyncTasks","tasks","createAsyncTaskCollector","recoveryRequest","clone","mutators","createMutators","enqueueTask","can","environment","processor","PushProcessor","withTransactionLifecycle","lifecycle","response","process","parsed","parseAlreadyProcessed","committed","length","entries","map","entry","task","runWithAuthScope","runAsyncTaskEntries","background","asyncTasks","handleQueryRequest","Error","handler","name","args","resolveServerQuery","userID","id","runWithQueryContext","database","transaction","callback","input","tx","hooks","beginAttempt","result","completeAttempt","error","rollbackAttempt","commitTransaction","rollbackTransaction","alreadyProcessedMutations","upstreamSchema","URL","url","searchParams","get","body","json","clientGroupID","Array","isArray","filter","mutation","clientID"],"sources":["../../src/createZeroServerCore.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","createZeroServerCore_exports","__export","createZeroServerCore","module","exports","import_server","require","import_asyncTasks","import_createZeroDirectServer","import_createMutators","import_mutatorContext","import_queryContext","_assert_this_initialized","self","ReferenceError","_call_super","_this","derived","args","_get_prototype_of","_possible_constructor_return","_is_native_reflect_construct","Reflect","construct","constructor","apply","_class_call_check","instance","Constructor","TypeError","_construct","Parent","Class","Parent2","args2","Class2","a","push","Function","bind","_set_prototype_of","prototype","arguments","_define_property","obj","key","Object","defineProperty","enumerable","configurable","writable","o","setPrototypeOf","getPrototypeOf","o2","__proto__","_inherits","subClass","superClass","create","_instanceof","left","right","Symbol","hasInstance","_is_native_function","fn","toString","call","indexOf","_type_of","p","p2","_wrap_native_super","_cache","Map","wrapNativeSuper","has","get","set","Wrapper","result","Boolean","valueOf","_","param","createDatabase","createServerActions","defaultAllowAdminRole","defaultMutateAuthData","models","mutations","mutationValidators","persistAlreadyProcessed","queries","schema","validateMutation","validateQuery","permissions","server","createZeroDirectServerRuntime","handleMutationRequest","param2","authData","request","scheduleBackgroundTask","skipAsyncTasks","tasks","createAsyncTaskCollector","recoveryRequest","clone","mutators","createMutators","enqueueTask","can","environment","processor","PushProcessor","withTransactionLifecycle","lifecycle","response","process","parsed","parseAlreadyProcessed","committed","length","entries","map","entry","task","runWithAuthScope","runAsyncTaskEntries","background","asyncTasks"],"sources":["../../src/createZeroServerCore.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -434,22 +434,132 @@ let storageID = 0;
434
434
  cleanup();
435
435
  view.destroy();
436
436
  });
437
- (0, import_vitest.test)("transient pull failures back off reconnect attempts", async () => {
438
- const requests = [];
437
+ (0, import_vitest.test)("pull and push 500 reconnects keep socket opens on their current Zero attempt", async () => {
438
+ const lifecycle = [];
439
+ const zeroLogs = [];
440
+ let failPull = false;
441
+ let failPush = false;
439
442
  const fetch = import_vitest.vi.fn(async (input, init) => {
440
443
  const request = recordRequest(input, init);
441
- requests.push(request);
442
- (0, import_vitest.expect)(request.path).toBe("/pull");
443
- throw new TypeError("Failed to fetch");
444
+ if (request.path === "/pull") {
445
+ if (failPull) {
446
+ failPull = false;
447
+ return jsonResponse({
448
+ error: "injected pull outage"
449
+ }, {
450
+ status: 500
451
+ });
452
+ }
453
+ return jsonResponse({
454
+ cookie: request.body.cookie,
455
+ unchanged: true
456
+ });
457
+ }
458
+ if (failPush) {
459
+ failPush = false;
460
+ return jsonResponse({
461
+ error: "injected push outage"
462
+ }, {
463
+ status: 500
464
+ });
465
+ }
466
+ const mutation2 = request.body.mutations[0];
467
+ return jsonResponse({
468
+ pushResponse: {
469
+ mutations: [{
470
+ id: {
471
+ clientID: mutation2.clientID,
472
+ id: mutation2.id
473
+ },
474
+ result: {}
475
+ }]
476
+ }
477
+ });
444
478
  });
445
- install(fetch);
446
- createZero();
447
- await eventually(() => (0, import_vitest.expect)(requests.length).toBe(1));
448
- await sleep(150);
449
- (0, import_vitest.expect)(requests.length).toBe(1);
450
- await eventually(() => (0, import_vitest.expect)(requests.length).toBe(2), 1500);
451
- await sleep(150);
452
- (0, import_vitest.expect)(requests.length).toBe(2);
479
+ const transport = (0, import_httpPullTransport.installHttpPullTransport)({
480
+ origin: ORIGIN,
481
+ fetch,
482
+ lifecycle: event => lifecycle.push(event)
483
+ });
484
+ transports.push(transport);
485
+ const zero = createZero({
486
+ logSink: {
487
+ log: (_level, context, ...args) => {
488
+ zeroLogs.push({
489
+ context: context ?? {},
490
+ args
491
+ });
492
+ }
493
+ }
494
+ });
495
+ await eventually(() => (0, import_vitest.expect)(zero.connection.state.current.name).toBe("connected"));
496
+ failPull = true;
497
+ await transport.pull().catch(() => {});
498
+ await eventually(() => (0, import_vitest.expect)(lifecycle.filter(event => event.type === "open")).toHaveLength(2), 5e3);
499
+ failPush = true;
500
+ const mutation = zero.mutate.project.create({
501
+ id: "p1",
502
+ ownerId: "u1",
503
+ name: "after reconnect"
504
+ });
505
+ await mutation.client;
506
+ await mutation.server.catch(() => {});
507
+ await eventually(() => (0, import_vitest.expect)(lifecycle.filter(event => event.type === "open")).toHaveLength(3), 5e3);
508
+ await eventually(() => (0, import_vitest.expect)(zero.connection.state.current.name).toBe("connected"), 5e3);
509
+ const opens = lifecycle.filter(event => event.type === "open");
510
+ (0, import_vitest.expect)(opens.map(({
511
+ generation,
512
+ activeGeneration
513
+ }) => [generation, activeGeneration])).toEqual([[1, 1], [2, 2], [3, 3]]);
514
+ (0, import_vitest.expect)(zeroLogs.some(({
515
+ args
516
+ }) => args.some(arg => String(arg).includes("connect start time is undefined")))).toBe(false);
517
+ });
518
+ (0, import_vitest.test)("a replacement socket supersedes stale open and connected events for the same client", async () => {
519
+ import_vitest.vi.useFakeTimers();
520
+ const lifecycle = [];
521
+ const transport = (0, import_httpPullTransport.installHttpPullTransport)({
522
+ origin: ORIGIN,
523
+ fetch: import_vitest.vi.fn(async () => jsonResponse({
524
+ cookie: null,
525
+ unchanged: true
526
+ })),
527
+ lifecycle: event => lifecycle.push(event)
528
+ });
529
+ transports.push(transport);
530
+ let connectStart = Date.now();
531
+ const errors = [];
532
+ const attachStockLifecycle = socket => {
533
+ socket.addEventListener("open", () => {
534
+ if (connectStart === void 0) {
535
+ errors.push("Got open event but connect start time is undefined.");
536
+ }
537
+ });
538
+ socket.addEventListener("message", event => {
539
+ const message = JSON.parse(String(event.data));
540
+ if (message[0] === "connected") connectStart = void 0;
541
+ });
542
+ };
543
+ const stale = openRawSocketWithMessages({
544
+ wsid: "stale"
545
+ }).socket;
546
+ attachStockLifecycle(stale);
547
+ const current = openRawSocketWithMessages({
548
+ wsid: "current"
549
+ }).socket;
550
+ attachStockLifecycle(current);
551
+ await import_vitest.vi.advanceTimersByTimeAsync(1);
552
+ (0, import_vitest.expect)(lifecycle.filter(event => event.type === "open").map(({
553
+ generation,
554
+ activeGeneration,
555
+ wsid
556
+ }) => [generation, activeGeneration, wsid])).toEqual([[2, 2, "current"]]);
557
+ (0, import_vitest.expect)(lifecycle).toContainEqual(import_vitest.expect.objectContaining({
558
+ type: "superseded",
559
+ generation: 1,
560
+ wsid: "stale"
561
+ }));
562
+ (0, import_vitest.expect)(errors).toEqual([]);
453
563
  });
454
564
  (0, import_vitest.test)("non-origin WebSockets pass through to the native implementation", () => {
455
565
  const previous = globalThis.WebSocket;
@@ -565,7 +675,9 @@ function createZero(options = {}) {
565
675
  storageKey: `zero-http-test-${++storageID}`,
566
676
  mutators: import_fixtureSchema.zeroHttpFixtureMutators,
567
677
  pingTimeoutMs: options.pingTimeoutMs,
568
- onClientStateNotFound: options.onClientStateNotFound
678
+ onClientStateNotFound: options.onClientStateNotFound,
679
+ logLevel: options.logSink ? "debug" : void 0,
680
+ logSink: options.logSink
569
681
  });
570
682
  zeros.push(zero);
571
683
  return zero;
@@ -630,7 +742,7 @@ function openRawSocketWithMessages(opts) {
630
742
  url.searchParams.set("userID", "u1");
631
743
  url.searchParams.set("baseCookie", "");
632
744
  url.searchParams.set("lmid", "0");
633
- url.searchParams.set("wsid", "ws-test");
745
+ url.searchParams.set("wsid", opts?.wsid ?? "ws-test");
634
746
  const messages = [];
635
747
  const socket = new WebSocket(url, encodeSecProtocol(["initConnection", {
636
748
  desiredQueriesPatch: opts?.desiredQueriesPatch ?? []
@@ -512,26 +512,168 @@ var storageID = 0;
512
512
  cleanup();
513
513
  view.destroy();
514
514
  });
515
- (0, import_vitest.test)("transient pull failures back off reconnect attempts", async function () {
516
- var requests = [];
515
+ (0, import_vitest.test)("pull and push 500 reconnects keep socket opens on their current Zero attempt", async function () {
516
+ var lifecycle = [];
517
+ var zeroLogs = [];
518
+ var failPull = false;
519
+ var failPush = false;
517
520
  var fetch = import_vitest.vi.fn(async function (input, init) {
518
521
  var request = recordRequest(input, init);
519
- requests.push(request);
520
- (0, import_vitest.expect)(request.path).toBe("/pull");
521
- throw new TypeError("Failed to fetch");
522
+ if (request.path === "/pull") {
523
+ if (failPull) {
524
+ failPull = false;
525
+ return jsonResponse({
526
+ error: "injected pull outage"
527
+ }, {
528
+ status: 500
529
+ });
530
+ }
531
+ return jsonResponse({
532
+ cookie: request.body.cookie,
533
+ unchanged: true
534
+ });
535
+ }
536
+ if (failPush) {
537
+ failPush = false;
538
+ return jsonResponse({
539
+ error: "injected push outage"
540
+ }, {
541
+ status: 500
542
+ });
543
+ }
544
+ var mutation2 = request.body.mutations[0];
545
+ return jsonResponse({
546
+ pushResponse: {
547
+ mutations: [{
548
+ id: {
549
+ clientID: mutation2.clientID,
550
+ id: mutation2.id
551
+ },
552
+ result: {}
553
+ }]
554
+ }
555
+ });
556
+ });
557
+ var transport = (0, import_httpPullTransport.installHttpPullTransport)({
558
+ origin: ORIGIN,
559
+ fetch,
560
+ lifecycle: function (event) {
561
+ return lifecycle.push(event);
562
+ }
563
+ });
564
+ transports.push(transport);
565
+ var zero = createZero({
566
+ logSink: {
567
+ log: function (_level, context) {
568
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
569
+ args[_key - 2] = arguments[_key];
570
+ }
571
+ zeroLogs.push({
572
+ context: context !== null && context !== void 0 ? context : {},
573
+ args
574
+ });
575
+ }
576
+ }
522
577
  });
523
- install(fetch);
524
- createZero();
525
578
  await eventually(function () {
526
- return (0, import_vitest.expect)(requests.length).toBe(1);
579
+ return (0, import_vitest.expect)(zero.connection.state.current.name).toBe("connected");
527
580
  });
528
- await sleep(150);
529
- (0, import_vitest.expect)(requests.length).toBe(1);
581
+ failPull = true;
582
+ await transport.pull().catch(function () {});
530
583
  await eventually(function () {
531
- return (0, import_vitest.expect)(requests.length).toBe(2);
532
- }, 1500);
533
- await sleep(150);
534
- (0, import_vitest.expect)(requests.length).toBe(2);
584
+ return (0, import_vitest.expect)(lifecycle.filter(function (event) {
585
+ return event.type === "open";
586
+ })).toHaveLength(2);
587
+ }, 5e3);
588
+ failPush = true;
589
+ var mutation = zero.mutate.project.create({
590
+ id: "p1",
591
+ ownerId: "u1",
592
+ name: "after reconnect"
593
+ });
594
+ await mutation.client;
595
+ await mutation.server.catch(function () {});
596
+ await eventually(function () {
597
+ return (0, import_vitest.expect)(lifecycle.filter(function (event) {
598
+ return event.type === "open";
599
+ })).toHaveLength(3);
600
+ }, 5e3);
601
+ await eventually(function () {
602
+ return (0, import_vitest.expect)(zero.connection.state.current.name).toBe("connected");
603
+ }, 5e3);
604
+ var opens = lifecycle.filter(function (event) {
605
+ return event.type === "open";
606
+ });
607
+ (0, import_vitest.expect)(opens.map(function (param) {
608
+ var {
609
+ generation,
610
+ activeGeneration
611
+ } = param;
612
+ return [generation, activeGeneration];
613
+ })).toEqual([[1, 1], [2, 2], [3, 3]]);
614
+ (0, import_vitest.expect)(zeroLogs.some(function (param) {
615
+ var {
616
+ args
617
+ } = param;
618
+ return args.some(function (arg) {
619
+ return String(arg).includes("connect start time is undefined");
620
+ });
621
+ })).toBe(false);
622
+ });
623
+ (0, import_vitest.test)("a replacement socket supersedes stale open and connected events for the same client", async function () {
624
+ import_vitest.vi.useFakeTimers();
625
+ var lifecycle = [];
626
+ var transport = (0, import_httpPullTransport.installHttpPullTransport)({
627
+ origin: ORIGIN,
628
+ fetch: import_vitest.vi.fn(async function () {
629
+ return jsonResponse({
630
+ cookie: null,
631
+ unchanged: true
632
+ });
633
+ }),
634
+ lifecycle: function (event) {
635
+ return lifecycle.push(event);
636
+ }
637
+ });
638
+ transports.push(transport);
639
+ var connectStart = Date.now();
640
+ var errors = [];
641
+ var attachStockLifecycle = function (socket) {
642
+ socket.addEventListener("open", function () {
643
+ if (connectStart === void 0) {
644
+ errors.push("Got open event but connect start time is undefined.");
645
+ }
646
+ });
647
+ socket.addEventListener("message", function (event) {
648
+ var message = JSON.parse(String(event.data));
649
+ if (message[0] === "connected") connectStart = void 0;
650
+ });
651
+ };
652
+ var stale = openRawSocketWithMessages({
653
+ wsid: "stale"
654
+ }).socket;
655
+ attachStockLifecycle(stale);
656
+ var current = openRawSocketWithMessages({
657
+ wsid: "current"
658
+ }).socket;
659
+ attachStockLifecycle(current);
660
+ await import_vitest.vi.advanceTimersByTimeAsync(1);
661
+ (0, import_vitest.expect)(lifecycle.filter(function (event) {
662
+ return event.type === "open";
663
+ }).map(function (param) {
664
+ var {
665
+ generation,
666
+ activeGeneration,
667
+ wsid
668
+ } = param;
669
+ return [generation, activeGeneration, wsid];
670
+ })).toEqual([[2, 2, "current"]]);
671
+ (0, import_vitest.expect)(lifecycle).toContainEqual(import_vitest.expect.objectContaining({
672
+ type: "superseded",
673
+ generation: 1,
674
+ wsid: "stale"
675
+ }));
676
+ (0, import_vitest.expect)(errors).toEqual([]);
535
677
  });
536
678
  (0, import_vitest.test)("non-origin WebSockets pass through to the native implementation", function () {
537
679
  var previous = globalThis.WebSocket;
@@ -653,7 +795,9 @@ function createZero() {
653
795
  storageKey: `zero-http-test-${++storageID}`,
654
796
  mutators: import_fixtureSchema.zeroHttpFixtureMutators,
655
797
  pingTimeoutMs: options.pingTimeoutMs,
656
- onClientStateNotFound: options.onClientStateNotFound
798
+ onClientStateNotFound: options.onClientStateNotFound,
799
+ logLevel: options.logSink ? "debug" : void 0,
800
+ logSink: options.logSink
657
801
  });
658
802
  zeros.push(zero);
659
803
  return zero;
@@ -728,7 +872,8 @@ function openRawSocketWithMessages(opts) {
728
872
  url.searchParams.set("userID", "u1");
729
873
  url.searchParams.set("baseCookie", "");
730
874
  url.searchParams.set("lmid", "0");
731
- url.searchParams.set("wsid", "ws-test");
875
+ var _opts_wsid;
876
+ url.searchParams.set("wsid", (_opts_wsid = opts === null || opts === void 0 ? void 0 : opts.wsid) !== null && _opts_wsid !== void 0 ? _opts_wsid : "ws-test");
732
877
  var messages = [];
733
878
  var _opts_desiredQueriesPatch, _opts_authToken;
734
879
  var socket = new WebSocket(url, encodeSecProtocol(["initConnection", {