on-zero 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -146,8 +146,79 @@ function createZeroClientInternal({
146
146
  });
147
147
  (0, import_run.setCustomQueries)(customQueries);
148
148
  const DisabledContext = (0, import_react2.createContext)(false);
149
+ let clientMutators = null;
150
+ function getClientMutators() {
151
+ clientMutators ??= (0, import_createMutators.createMutators)({
152
+ models,
153
+ environment: "client",
154
+ authData: null,
155
+ can: permissionsHelpers.can
156
+ });
157
+ return clientMutators;
158
+ }
159
+ function constructZeroInstance({
160
+ options,
161
+ transport,
162
+ beforeReload,
163
+ scheduleReload,
164
+ guardStorage,
165
+ benignLogPatterns
166
+ }) {
167
+ if (transport) {
168
+ const serverURL = options.cacheURL ?? options.server;
169
+ if (typeof serverURL !== "string") {
170
+ throw new Error(`client transport requires a server URL`);
171
+ }
172
+ transport.install(serverURL);
173
+ }
174
+ const instanceRef = {
175
+ current: null
176
+ };
177
+ const recoveryDeps = {
178
+ deleteLocalState: () => deleteZeroInstance(instanceRef.current),
179
+ zeroEvents,
180
+ beforeReload,
181
+ scheduleReload,
182
+ guardStorage,
183
+ benignLogPatterns: [...(transport?.logClassifications?.benign ?? []), ...(benignLogPatterns ?? [])],
184
+ onRecovery: () => mutationLifecycle.fence()
185
+ };
186
+ const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(recoveryDeps);
187
+ const createdInstance = new import_zero.Zero({
188
+ kvStore: "mem",
189
+ ...options,
190
+ schema,
191
+ // @ts-expect-error same erasure ZeroProvider needed
192
+ mutators: getClientMutators(),
193
+ // when the consumer brings no logSink, install ours: it preserves Zero's
194
+ // console output AND watches for the local-store-lost signature. a
195
+ // consumer with its own logSink owns log-based recovery (no double-fire
196
+ // with e.g. soot's origin-gated recovery).
197
+ logSink: options.logSink ?? (0, import_recoverZeroClient.composeRecoveryLogSink)(recoveryDeps),
198
+ // consumer handlers win; otherwise on-zero's default self-healing
199
+ // recovery covers EVERY reason (drop local state + reload, guarded) —
200
+ // passing these to Zero disables its built-in reload, so any reason we
201
+ // left unhandled would fatal-blank the app forever.
202
+ onUpdateNeeded: options.onUpdateNeeded ?? recovery.onUpdateNeeded,
203
+ onClientStateNotFound: options.onClientStateNotFound ?? recovery.onClientStateNotFound
204
+ });
205
+ instanceRef.current = createdInstance;
206
+ return createdInstance;
207
+ }
149
208
  let latestZeroInstance = null;
150
209
  const zeroReadyWaiters = /* @__PURE__ */new Set();
210
+ function publishZeroInstance(zeroInstance) {
211
+ if (zeroInstance === latestZeroInstance) return false;
212
+ latestZeroInstance = zeroInstance;
213
+ mutationLifecycle.activate();
214
+ const runner = (query, options) => zeroInstance.run(query, options);
215
+ instance.runner = runner;
216
+ (0, import_zeroRunner.setRunner)(runner);
217
+ const waiters = [...zeroReadyWaiters];
218
+ zeroReadyWaiters.clear();
219
+ for (const onReady of waiters) onReady(zeroInstance);
220
+ return true;
221
+ }
151
222
  function waitForZero({
152
223
  signal
153
224
  } = {}) {
@@ -402,14 +473,6 @@ function createZeroClientInternal({
402
473
  }
403
474
  const authData = authDataIn ?? stableAuthDataRef.current ?? null;
404
475
  (0, import_state.setAuthData)(authData);
405
- const mutators = (0, import_react2.useMemo)(() => {
406
- return (0, import_createMutators.createMutators)({
407
- models,
408
- environment: "client",
409
- authData: null,
410
- can: permissionsHelpers.can
411
- });
412
- }, []);
413
476
  const hostScope = (0, import_hostStorageScope.readHostStorageScope)();
414
477
  const scopedProps = hostScope ? {
415
478
  ...props,
@@ -453,54 +516,22 @@ function createZeroClientInternal({
453
516
  }
454
517
  let cached = cachedZero;
455
518
  const options = scopedProps;
456
- if (transport) {
457
- const serverURL = options.cacheURL ?? options.server;
458
- if (typeof serverURL !== "string") {
459
- throw new Error(`client transport requires a server URL`);
460
- }
461
- transport.install(serverURL);
462
- }
463
519
  if (cached?.key !== instanceKey) {
464
520
  if (cached) {
465
521
  clearZeroInstanceReferences(cached.instance);
466
522
  mutationLifecycle.fence();
467
523
  cached.instance.close();
468
524
  }
469
- const instanceRef = {
470
- current: null
471
- };
472
- const recoveryDeps = {
473
- deleteLocalState: () => deleteZeroInstance(instanceRef.current),
474
- zeroEvents,
475
- beforeReload,
476
- scheduleReload,
477
- guardStorage,
478
- benignLogPatterns: [...(transport?.logClassifications?.benign ?? []), ...(benignLogPatterns ?? [])],
479
- onRecovery: () => mutationLifecycle.fence()
480
- };
481
- const recovery = (0, import_recoverZeroClient.makeZeroRecovery)(recoveryDeps);
482
- const createdInstance = new import_zero.Zero({
483
- kvStore: "mem",
484
- ...options,
485
- schema,
486
- // @ts-expect-error same erasure ZeroProvider needed
487
- mutators,
488
- // when the consumer brings no logSink, install ours: it preserves
489
- // Zero's console output AND watches for the local-store-lost signature.
490
- // a consumer with its own logSink owns log-based recovery (no
491
- // double-fire with e.g. soot's origin-gated recovery).
492
- logSink: options.logSink ?? (0, import_recoverZeroClient.composeRecoveryLogSink)(recoveryDeps),
493
- // consumer handlers win; otherwise on-zero's default self-healing
494
- // recovery covers EVERY reason (drop local state + reload, guarded) —
495
- // passing these to Zero disables its built-in reload, so any reason we
496
- // left unhandled would fatal-blank the app forever.
497
- onUpdateNeeded: options.onUpdateNeeded ?? recovery.onUpdateNeeded,
498
- onClientStateNotFound: options.onClientStateNotFound ?? recovery.onClientStateNotFound
499
- });
500
- instanceRef.current = createdInstance;
501
525
  cached = {
502
526
  key: instanceKey,
503
- instance: createdInstance
527
+ instance: constructZeroInstance({
528
+ options,
529
+ transport,
530
+ beforeReload,
531
+ scheduleReload,
532
+ guardStorage,
533
+ benignLogPatterns
534
+ })
504
535
  };
505
536
  cachedZero = cached;
506
537
  }
@@ -536,21 +567,42 @@ function createZeroClientInternal({
536
567
  const ProvideZero = import_platform.IS_SERVER_RUNTIME ? ProvideZeroServer : ProvideZeroClient;
537
568
  const SetZeroInstance = () => {
538
569
  const zeroInstance = (0, import_react.useZero)();
539
- if (zeroInstance !== latestZeroInstance) {
540
- latestZeroInstance = zeroInstance;
541
- mutationLifecycle.activate();
542
- const runner = (query, options) => zeroInstance.run(query, options);
543
- instance.runner = runner;
544
- (0, import_zeroRunner.setRunner)(runner);
545
- const waiters = [...zeroReadyWaiters];
546
- zeroReadyWaiters.clear();
547
- for (const onReady of waiters) onReady(zeroInstance);
548
- }
570
+ publishZeroInstance(zeroInstance);
549
571
  (0, import_react2.useEffect)(() => {
550
572
  zeroInstanceVersion?.emit(zeroInstanceVersion.value + 1);
551
573
  }, [zeroInstance]);
552
574
  return null;
553
575
  };
576
+ function connectHeadless(props) {
577
+ const {
578
+ authData,
579
+ transport,
580
+ beforeReload,
581
+ scheduleReload,
582
+ guardStorage,
583
+ benignLogPatterns,
584
+ ...options
585
+ } = props;
586
+ (0, import_state.setAuthData)(authData ?? null);
587
+ const zeroInstance = constructZeroInstance({
588
+ options,
589
+ transport,
590
+ beforeReload,
591
+ scheduleReload,
592
+ guardStorage,
593
+ benignLogPatterns
594
+ });
595
+ publishZeroInstance(zeroInstance);
596
+ zeroInstanceVersion?.emit(zeroInstanceVersion.value + 1);
597
+ return {
598
+ zero: zeroInstance,
599
+ close: async () => {
600
+ clearZeroInstanceReferences(zeroInstance);
601
+ mutationLifecycle.fence();
602
+ await zeroInstance.close();
603
+ }
604
+ };
605
+ }
554
606
  const ConnectionMonitor = (0, import_react2.memo)(({
555
607
  zeroEvents: zeroEvents2,
556
608
  refreshAuth,
@@ -686,6 +738,7 @@ function createZeroClientInternal({
686
738
  zeroEvents,
687
739
  reloadPage,
688
740
  ProvideZero,
741
+ connectHeadless,
689
742
  ControlQueries,
690
743
  useQuery,
691
744
  useQueryDirect,
@@ -0,0 +1,33 @@
1
+ var import_zero = require("@rocicorp/zero");
2
+ var import_vitest = require("vitest");
3
+ var import_createZeroClient = require("./createZeroClient.cjs");
4
+ const userTable = (0, import_zero.table)("user").columns({
5
+ id: (0, import_zero.string)(),
6
+ name: (0, import_zero.string)()
7
+ }).primaryKey("id");
8
+ const schema = (0, import_zero.createSchema)({
9
+ tables: [userTable]
10
+ });
11
+ const byId = args => args;
12
+ (0, import_vitest.test)("connectHeadless publishes the instance with no react tree", async () => {
13
+ const client = (0, import_createZeroClient.createZeroClient)({
14
+ schema,
15
+ models: {},
16
+ groupedQueries: {
17
+ headlessTest: {
18
+ byId
19
+ }
20
+ },
21
+ instanceName: "headless-test"
22
+ });
23
+ const pending = /* @__PURE__ */Symbol("pending");
24
+ const before = await Promise.race([client.waitForZero(), Promise.resolve(pending)]);
25
+ (0, import_vitest.expect)(before).toBe(pending);
26
+ const connection = client.connectHeadless({
27
+ userID: "user-headless",
28
+ kvStore: "mem",
29
+ storageKey: "headless-test"
30
+ });
31
+ (0, import_vitest.expect)(await client.waitForZero()).toBe(connection.zero);
32
+ await connection.close();
33
+ });
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ var import_zero = require("@rocicorp/zero");
4
+ var import_vitest = require("vitest");
5
+ var import_createZeroClient = require("./createZeroClient.native.js");
6
+ var userTable = (0, import_zero.table)("user").columns({
7
+ id: (0, import_zero.string)(),
8
+ name: (0, import_zero.string)()
9
+ }).primaryKey("id");
10
+ var schema = (0, import_zero.createSchema)({
11
+ tables: [userTable]
12
+ });
13
+ var byId = function byId2(args) {
14
+ return args;
15
+ };
16
+ (0, import_vitest.test)("connectHeadless publishes the instance with no react tree", async function () {
17
+ var client = (0, import_createZeroClient.createZeroClient)({
18
+ schema,
19
+ models: {},
20
+ groupedQueries: {
21
+ headlessTest: {
22
+ byId
23
+ }
24
+ },
25
+ instanceName: "headless-test"
26
+ });
27
+ var pending = /* @__PURE__ */Symbol("pending");
28
+ var before = await Promise.race([client.waitForZero(), Promise.resolve(pending)]);
29
+ (0, import_vitest.expect)(before).toBe(pending);
30
+ var connection = client.connectHeadless({
31
+ userID: "user-headless",
32
+ kvStore: "mem",
33
+ storageKey: "headless-test"
34
+ });
35
+ (0, import_vitest.expect)(await client.waitForZero()).toBe(connection.zero);
36
+ await connection.close();
37
+ });
38
+ //# sourceMappingURL=createZeroClient.headless.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["import_zero","require","import_vitest","import_createZeroClient","userTable","table","columns","id","string","name","primaryKey","schema","createSchema","tables","byId","byId2","args","test","client","createZeroClient","models","groupedQueries","headlessTest","instanceName"],"sources":["../../src/createZeroClient.headless.test.tsx"],"sourcesContent":[null],"mappings":"AAEA;;AACA,IAAAA,WAAA,GAAAC,OAA6B;AAE7B,IAAAC,aAAA,GAAAD,OAAA,SAAiC;AAIjC,IAAAE,uBAAkB,GAAAF,OAAA,+BAAsB,CAAE;AAC1C,IAAAG,SAAM,OAASJ,WAAA,CAAAK,KAAA,QAAa,EAAEC,OAAA,CAAQ;EAEtCC,EAAA,EAAM,IAAAP,WAAQ,CAAAQ,MAAyB;EAAAC,IAOvC,MAAAT,WAAA,CAAKQ,MAAA;AACH,GAAAE,UAAM;AAA0B,IAC9BC,MAAA,OAAAX,WAAA,CAAAY,YAAA;EAAAC,MACA,GACAT,SAAA;AACc,EAChB;AAKA,IAAAU,IAAM,YAAUC,MAAAC,IAAA;EAChB,OAAMA,IAAA;AAA4B;AACb,IACnBd,aAAQ,CAAAe,IAAQ,6DAA2B;EAC7C,IAACC,MAAA,OAAAf,uBAAA,CAAAgB,gBAAA;IACDR,MAAA;IAEAS,MAAM;IACJC,cAAQ;MACRC,YAAS;QACTR;MACD;IAED;IAEAS,YAAM;EACP","ignoreList":[]}
@@ -251,8 +251,110 @@ function createZeroClientInternal(param) {
251
251
  });
252
252
  (0, import_run.setCustomQueries)(customQueries);
253
253
  var DisabledContext = /* @__PURE__ */(0, import_react2.createContext)(false);
254
+ var clientMutators = null;
255
+ function getClientMutators() {
256
+ clientMutators !== null && clientMutators !== void 0 ? clientMutators : clientMutators = (0, import_createMutators.createMutators)({
257
+ models,
258
+ environment: "client",
259
+ authData: null,
260
+ can: permissionsHelpers.can
261
+ });
262
+ return clientMutators;
263
+ }
264
+ function constructZeroInstance(param2) {
265
+ var {
266
+ options,
267
+ transport,
268
+ beforeReload,
269
+ scheduleReload,
270
+ guardStorage,
271
+ benignLogPatterns
272
+ } = param2;
273
+ var _ref, _options_logSink, _options_onUpdateNeeded, _options_onClientStateNotFound;
274
+ var _transport_logClassifications;
275
+ if (transport) {
276
+ var _options_cacheURL;
277
+ var serverURL = (_options_cacheURL = options.cacheURL) !== null && _options_cacheURL !== void 0 ? _options_cacheURL : options.server;
278
+ if (typeof serverURL !== "string") {
279
+ throw new Error(`client transport requires a server URL`);
280
+ }
281
+ transport.install(serverURL);
282
+ }
283
+ var instanceRef = {
284
+ current: null
285
+ };
286
+ var recoveryDeps = {
287
+ deleteLocalState: function deleteLocalState() {
288
+ return deleteZeroInstance(instanceRef.current);
289
+ },
290
+ zeroEvents,
291
+ beforeReload,
292
+ scheduleReload,
293
+ guardStorage,
294
+ benignLogPatterns: [...((_ref = transport === null || transport === void 0 ? void 0 : (_transport_logClassifications = transport.logClassifications) === null || _transport_logClassifications === void 0 ? void 0 : _transport_logClassifications.benign) !== null && _ref !== void 0 ? _ref : []), ...(benignLogPatterns !== null && benignLogPatterns !== void 0 ? benignLogPatterns : [])],
295
+ onRecovery: function onRecovery() {
296
+ return mutationLifecycle.fence();
297
+ }
298
+ };
299
+ var recovery = (0, import_recoverZeroClient.makeZeroRecovery)(recoveryDeps);
300
+ var createdInstance = new import_zero.Zero({
301
+ kvStore: "mem",
302
+ ...options,
303
+ schema,
304
+ // @ts-expect-error same erasure ZeroProvider needed
305
+ mutators: getClientMutators(),
306
+ // when the consumer brings no logSink, install ours: it preserves Zero's
307
+ // console output AND watches for the local-store-lost signature. a
308
+ // consumer with its own logSink owns log-based recovery (no double-fire
309
+ // with e.g. soot's origin-gated recovery).
310
+ logSink: (_options_logSink = options.logSink) !== null && _options_logSink !== void 0 ? _options_logSink : (0, import_recoverZeroClient.composeRecoveryLogSink)(recoveryDeps),
311
+ // consumer handlers win; otherwise on-zero's default self-healing
312
+ // recovery covers EVERY reason (drop local state + reload, guarded) —
313
+ // passing these to Zero disables its built-in reload, so any reason we
314
+ // left unhandled would fatal-blank the app forever.
315
+ onUpdateNeeded: (_options_onUpdateNeeded = options.onUpdateNeeded) !== null && _options_onUpdateNeeded !== void 0 ? _options_onUpdateNeeded : recovery.onUpdateNeeded,
316
+ onClientStateNotFound: (_options_onClientStateNotFound = options.onClientStateNotFound) !== null && _options_onClientStateNotFound !== void 0 ? _options_onClientStateNotFound : recovery.onClientStateNotFound
317
+ });
318
+ instanceRef.current = createdInstance;
319
+ return createdInstance;
320
+ }
254
321
  var latestZeroInstance = null;
255
322
  var zeroReadyWaiters = /* @__PURE__ */new Set();
323
+ function publishZeroInstance(zeroInstance) {
324
+ if (zeroInstance === latestZeroInstance) return false;
325
+ latestZeroInstance = zeroInstance;
326
+ mutationLifecycle.activate();
327
+ var runner = function runner2(query, options) {
328
+ return zeroInstance.run(query, options);
329
+ };
330
+ instance.runner = runner;
331
+ (0, import_zeroRunner.setRunner)(runner);
332
+ var waiters = [...zeroReadyWaiters];
333
+ zeroReadyWaiters.clear();
334
+ var _iteratorNormalCompletion3 = true,
335
+ _didIteratorError3 = false,
336
+ _iteratorError3 = void 0;
337
+ try {
338
+ for (var _iterator3 = waiters[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
339
+ var onReady = _step3.value;
340
+ onReady(zeroInstance);
341
+ }
342
+ } catch (err) {
343
+ _didIteratorError3 = true;
344
+ _iteratorError3 = err;
345
+ } finally {
346
+ try {
347
+ if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
348
+ _iterator3.return();
349
+ }
350
+ } finally {
351
+ if (_didIteratorError3) {
352
+ throw _iteratorError3;
353
+ }
354
+ }
355
+ }
356
+ return true;
357
+ }
256
358
  function waitForZero() {
257
359
  var {
258
360
  signal
@@ -555,16 +657,6 @@ function createZeroClientInternal(param) {
555
657
  }
556
658
  var authData = (_ref = authDataIn !== null && authDataIn !== void 0 ? authDataIn : stableAuthDataRef.current) !== null && _ref !== void 0 ? _ref : null;
557
659
  (0, import_state.setAuthData)(authData);
558
- var mutators = (0, import_react2.useMemo)(function () {
559
- return (0, import_createMutators.createMutators)({
560
- models,
561
- environment: "client",
562
- authData: null,
563
- can: permissionsHelpers.can
564
- });
565
- },
566
- // eslint-disable-next-line react-hooks/exhaustive-deps
567
- []);
568
660
  var hostScope = (0, import_hostStorageScope.readHostStorageScope)();
569
661
  var scopedProps = hostScope ? {
570
662
  ...props,
@@ -623,61 +715,22 @@ function createZeroClientInternal(param) {
623
715
  }
624
716
  var cached = cachedZero;
625
717
  var options = scopedProps;
626
- if (transport) {
627
- var _options_cacheURL;
628
- var serverURL = (_options_cacheURL = options.cacheURL) !== null && _options_cacheURL !== void 0 ? _options_cacheURL : options.server;
629
- if (typeof serverURL !== "string") {
630
- throw new Error(`client transport requires a server URL`);
631
- }
632
- transport.install(serverURL);
633
- }
634
718
  if ((cached === null || cached === void 0 ? void 0 : cached.key) !== instanceKey) {
635
- var _ref2, _options_logSink, _options_onUpdateNeeded, _options_onClientStateNotFound;
636
- var _transport_logClassifications;
637
719
  if (cached) {
638
720
  clearZeroInstanceReferences(cached.instance);
639
721
  mutationLifecycle.fence();
640
722
  cached.instance.close();
641
723
  }
642
- var instanceRef = {
643
- current: null
644
- };
645
- var recoveryDeps = {
646
- deleteLocalState: function deleteLocalState() {
647
- return deleteZeroInstance(instanceRef.current);
648
- },
649
- zeroEvents,
650
- beforeReload,
651
- scheduleReload,
652
- guardStorage,
653
- benignLogPatterns: [...((_ref2 = transport === null || transport === void 0 ? void 0 : (_transport_logClassifications = transport.logClassifications) === null || _transport_logClassifications === void 0 ? void 0 : _transport_logClassifications.benign) !== null && _ref2 !== void 0 ? _ref2 : []), ...(benignLogPatterns !== null && benignLogPatterns !== void 0 ? benignLogPatterns : [])],
654
- onRecovery: function onRecovery() {
655
- return mutationLifecycle.fence();
656
- }
657
- };
658
- var recovery = (0, import_recoverZeroClient.makeZeroRecovery)(recoveryDeps);
659
- var createdInstance = new import_zero.Zero({
660
- kvStore: "mem",
661
- ...options,
662
- schema,
663
- // @ts-expect-error same erasure ZeroProvider needed
664
- mutators,
665
- // when the consumer brings no logSink, install ours: it preserves
666
- // Zero's console output AND watches for the local-store-lost signature.
667
- // a consumer with its own logSink owns log-based recovery (no
668
- // double-fire with e.g. soot's origin-gated recovery).
669
- logSink: (_options_logSink = options.logSink) !== null && _options_logSink !== void 0 ? _options_logSink : (0, import_recoverZeroClient.composeRecoveryLogSink)(recoveryDeps),
670
- // consumer handlers win; otherwise on-zero's default self-healing
671
- // recovery covers EVERY reason (drop local state + reload, guarded) —
672
- // passing these to Zero disables its built-in reload, so any reason we
673
- // left unhandled would fatal-blank the app forever.
674
- onUpdateNeeded: (_options_onUpdateNeeded = options.onUpdateNeeded) !== null && _options_onUpdateNeeded !== void 0 ? _options_onUpdateNeeded : recovery.onUpdateNeeded,
675
- onClientStateNotFound: (_options_onClientStateNotFound = options.onClientStateNotFound) !== null && _options_onClientStateNotFound !== void 0 ? _options_onClientStateNotFound : recovery.onClientStateNotFound
676
- });
677
- instanceRef.current = createdInstance;
678
724
  cached = {
679
725
  key: instanceKey,
680
- instance: createdInstance
726
+ instance: constructZeroInstance({
727
+ options,
728
+ transport,
729
+ beforeReload,
730
+ scheduleReload,
731
+ guardStorage,
732
+ benignLogPatterns
733
+ })
681
734
  };
682
735
  cachedZero = cached;
683
736
  }
@@ -718,44 +771,42 @@ function createZeroClientInternal(param) {
718
771
  var ProvideZero = import_platform.IS_SERVER_RUNTIME ? ProvideZeroServer : ProvideZeroClient;
719
772
  var SetZeroInstance = function SetZeroInstance2() {
720
773
  var zeroInstance = (0, import_react.useZero)();
721
- if (zeroInstance !== latestZeroInstance) {
722
- latestZeroInstance = zeroInstance;
723
- mutationLifecycle.activate();
724
- var runner = function runner2(query, options) {
725
- return zeroInstance.run(query, options);
726
- };
727
- instance.runner = runner;
728
- (0, import_zeroRunner.setRunner)(runner);
729
- var waiters = [...zeroReadyWaiters];
730
- zeroReadyWaiters.clear();
731
- var _iteratorNormalCompletion3 = true,
732
- _didIteratorError3 = false,
733
- _iteratorError3 = void 0;
734
- try {
735
- for (var _iterator3 = waiters[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
736
- var onReady = _step3.value;
737
- onReady(zeroInstance);
738
- }
739
- } catch (err) {
740
- _didIteratorError3 = true;
741
- _iteratorError3 = err;
742
- } finally {
743
- try {
744
- if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
745
- _iterator3.return();
746
- }
747
- } finally {
748
- if (_didIteratorError3) {
749
- throw _iteratorError3;
750
- }
751
- }
752
- }
753
- }
774
+ publishZeroInstance(zeroInstance);
754
775
  (0, import_react2.useEffect)(function () {
755
776
  zeroInstanceVersion === null || zeroInstanceVersion === void 0 ? void 0 : zeroInstanceVersion.emit(zeroInstanceVersion.value + 1);
756
777
  }, [zeroInstance]);
757
778
  return null;
758
779
  };
780
+ function connectHeadless(props) {
781
+ var {
782
+ authData,
783
+ transport,
784
+ beforeReload,
785
+ scheduleReload,
786
+ guardStorage,
787
+ benignLogPatterns,
788
+ ...options
789
+ } = props;
790
+ (0, import_state.setAuthData)(authData !== null && authData !== void 0 ? authData : null);
791
+ var zeroInstance = constructZeroInstance({
792
+ options,
793
+ transport,
794
+ beforeReload,
795
+ scheduleReload,
796
+ guardStorage,
797
+ benignLogPatterns
798
+ });
799
+ publishZeroInstance(zeroInstance);
800
+ zeroInstanceVersion === null || zeroInstanceVersion === void 0 ? void 0 : zeroInstanceVersion.emit(zeroInstanceVersion.value + 1);
801
+ return {
802
+ zero: zeroInstance,
803
+ close: async function close() {
804
+ clearZeroInstanceReferences(zeroInstance);
805
+ mutationLifecycle.fence();
806
+ await zeroInstance.close();
807
+ }
808
+ };
809
+ }
759
810
  var ConnectionMonitor = /* @__PURE__ */(0, import_react2.memo)(function (param2) {
760
811
  var {
761
812
  zeroEvents: zeroEvents2,
@@ -900,6 +951,7 @@ function createZeroClientInternal(param) {
900
951
  zeroEvents,
901
952
  reloadPage,
902
953
  ProvideZero,
954
+ connectHeadless,
903
955
  ControlQueries,
904
956
  useQuery,
905
957
  useQueryDirect,