gemi 0.129.0 → 0.130.0

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 (60) hide show
  1. package/dist/{chunk-wmkrb1qv.js → chunk-13agap7z.js} +1 -1
  2. package/dist/{chunk-zw5z1k84.js → chunk-7ynnce4b.js} +1 -1
  3. package/dist/{chunk-sbdm4enk.js → chunk-xtqhagxz.js} +2 -2
  4. package/dist/{chunk-sbdm4enk.js.map → chunk-xtqhagxz.js.map} +1 -1
  5. package/dist/chunks/MutationError-DuKqBW8o.js +199 -0
  6. package/dist/chunks/MutationError-DuKqBW8o.js.map +1 -0
  7. package/dist/chunks/{RealtimeClient-CqGve6h8.js → RealtimeClient-DsWbFRC7.js} +11 -3
  8. package/dist/chunks/RealtimeClient-DsWbFRC7.js.map +1 -0
  9. package/dist/chunks/{ThemeProvider-DaX0eyqs.js → ThemeProvider-gWqXjGh-.js} +70 -91
  10. package/dist/chunks/ThemeProvider-gWqXjGh-.js.map +1 -0
  11. package/dist/chunks/channelKey-CIhHpX6x.js +10 -0
  12. package/dist/chunks/channelKey-CIhHpX6x.js.map +1 -0
  13. package/dist/chunks/fetchFileRequest-BSrgYnAy.js +57 -0
  14. package/dist/chunks/fetchFileRequest-BSrgYnAy.js.map +1 -0
  15. package/dist/chunks/{live-DIUDdLrA.js → live-CUdMhXHL.js} +22 -3
  16. package/dist/chunks/live-CUdMhXHL.js.map +1 -0
  17. package/dist/chunks/mutationExtras-CtY-X9m7.js +115 -0
  18. package/dist/chunks/mutationExtras-CtY-X9m7.js.map +1 -0
  19. package/dist/client/MutationError.d.ts +7 -9
  20. package/dist/client/MutationError.d.ts.map +1 -1
  21. package/dist/client/QueryResource.d.ts +3 -11
  22. package/dist/client/QueryResource.d.ts.map +1 -1
  23. package/dist/client/fetchFile.d.ts +4 -7
  24. package/dist/client/fetchFile.d.ts.map +1 -1
  25. package/dist/client/fetchFileRequest.d.ts +14 -0
  26. package/dist/client/fetchFileRequest.d.ts.map +1 -0
  27. package/dist/client/index.js +88 -339
  28. package/dist/client/index.js.map +1 -1
  29. package/dist/client/lazyModule.d.ts +32 -0
  30. package/dist/client/lazyModule.d.ts.map +1 -0
  31. package/dist/client/mutationErrorHelpers.d.ts +11 -0
  32. package/dist/client/mutationErrorHelpers.d.ts.map +1 -0
  33. package/dist/client/mutationExtras.d.ts +3 -0
  34. package/dist/client/mutationExtras.d.ts.map +1 -0
  35. package/dist/client/mutationModules.d.ts +17 -0
  36. package/dist/client/mutationModules.d.ts.map +1 -0
  37. package/dist/client/queryUpdates.d.ts +22 -0
  38. package/dist/client/queryUpdates.d.ts.map +1 -0
  39. package/dist/client/realtime/RealtimeClient.d.ts +5 -0
  40. package/dist/client/realtime/RealtimeClient.d.ts.map +1 -1
  41. package/dist/client/realtime/channelKey.d.ts +4 -0
  42. package/dist/client/realtime/channelKey.d.ts.map +1 -0
  43. package/dist/client/realtime/live.d.ts +6 -0
  44. package/dist/client/realtime/live.d.ts.map +1 -1
  45. package/dist/client/realtime/loader.d.ts +20 -23
  46. package/dist/client/realtime/loader.d.ts.map +1 -1
  47. package/dist/client/realtime/useChannelSubscription.d.ts.map +1 -1
  48. package/dist/client/useMutation.d.ts +1 -1
  49. package/dist/client/useMutation.d.ts.map +1 -1
  50. package/dist/client/useSetQueryData.d.ts +4 -17
  51. package/dist/client/useSetQueryData.d.ts.map +1 -1
  52. package/dist/server/index.js +1 -1
  53. package/dist/testing/index.js +4 -3
  54. package/dist/testing/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/chunks/RealtimeClient-CqGve6h8.js.map +0 -1
  57. package/dist/chunks/ThemeProvider-DaX0eyqs.js.map +0 -1
  58. package/dist/chunks/live-DIUDdLrA.js.map +0 -1
  59. /package/dist/{chunk-wmkrb1qv.js.map → chunk-13agap7z.js.map} +0 -0
  60. /package/dist/{chunk-zw5z1k84.js.map → chunk-7ynnce4b.js.map} +0 -0
@@ -178,18 +178,7 @@ var QueryResource = class {
178
178
  const current = store.get(variantKey);
179
179
  if (current?.loading) continue;
180
180
  if (current?.hasData && current.data === data) continue;
181
- store.set(variantKey, {
182
- loading: false,
183
- data,
184
- hasData: true,
185
- error: null,
186
- version: now
187
- });
188
- this.staleVariants.delete(variantKey);
189
- this.lastFetchRecord.set(variantKey, now);
190
- this.failures.delete(variantKey);
191
- this.cancelRetry(variantKey);
192
- this.settle(variantKey);
181
+ this.fill(store, variantKey, data, now);
193
182
  changed = true;
194
183
  }
195
184
  if (changed) this.store.next(store);
@@ -463,30 +452,18 @@ var QueryResource = class {
463
452
  }));
464
453
  this.resolveVariant(variantKey, false, false);
465
454
  }
466
- /**
467
- * Write data the server just produced (a mutation's answer) into a
468
- * variant, with no refetch: unlike `mutate`, the value is not a guess to
469
- * reconcile. The variant counts as freshly fetched, so its `staleTime`
470
- * starts again, and a GET already on the wire for it is dropped when it
471
- * lands, since it may carry the data from before the write. A reader
472
- * suspended on the variant wakes up with it (#897).
473
- */
474
- set(variantKey, data) {
475
- this.dropHttpCache(variantKey);
476
- const now = Date.now();
477
- this.markApplied(variantKey);
478
- this.staleVariants.delete(variantKey);
479
- this.lastFetchRecord.set(variantKey, now);
480
- this.failures.delete(variantKey);
481
- this.cancelRetry(variantKey);
482
- const store = this.store.getValue();
483
- this.store.next(store.set(variantKey, {
455
+ fill(store, variantKey, data, now) {
456
+ store.set(variantKey, {
484
457
  loading: false,
485
458
  data,
486
459
  hasData: true,
487
460
  error: null,
488
461
  version: now
489
- }));
462
+ });
463
+ this.staleVariants.delete(variantKey);
464
+ this.lastFetchRecord.set(variantKey, now);
465
+ this.failures.delete(variantKey);
466
+ this.cancelRetry(variantKey);
490
467
  this.settle(variantKey);
491
468
  }
492
469
  refetch(variantKey) {
@@ -752,44 +729,65 @@ function toVariantKey(search) {
752
729
  return searchParams.toString();
753
730
  }
754
731
  //#endregion
755
- //#region client/realtime/loader.ts
756
- /** `pattern` and its params, canonical: two hooks on one channel share a `sub`. */
757
- function channelKey(pattern, params) {
758
- const sorted = Object.keys(params).sort().map((key) => [key, String(params[key])]);
759
- return `${pattern}\u0000${JSON.stringify(sorted)}`;
732
+ //#region client/lazyModule.ts
733
+ /**
734
+ * What a lazy `import()` resolved to, or a thrown error when it is missing.
735
+ * Vite's preload helper resolves the `import()` to `undefined` instead of
736
+ * rejecting when a `vite:preloadError` listener handled the failure (`init`'s
737
+ * chunk-load recovery does, as it starts a reload): treated as a failed load.
738
+ */
739
+ function loadedModule(module) {
740
+ if (!module) throw new Error("[gemi] A lazily loaded chunk is unavailable.");
741
+ return module;
760
742
  }
761
- var configured = {};
762
- var instance = null;
763
- var loading = null;
743
+ /**
744
+ * The module, loading it if it is not there yet. Callers while it loads share
745
+ * one load, so their callbacks run in call order. A failed load is not kept:
746
+ * the next call runs `import()` again.
747
+ */
748
+ function loadLazy(lazy) {
749
+ if (lazy.current) return Promise.resolve(lazy.current);
750
+ return lazy.loading ??= lazy.load().then((module) => {
751
+ lazy.loading = null;
752
+ return lazy.current = loadedModule(module);
753
+ }, (error) => {
754
+ lazy.loading = null;
755
+ throw error;
756
+ });
757
+ }
758
+ //#endregion
759
+ //#region client/realtime/loader.ts
760
+ /**
761
+ * The tab's client, once loaded and created (`tabClient` in
762
+ * `./RealtimeClient` creates it), and the options it is created with.
763
+ */
764
+ var realtime = {
765
+ client: null,
766
+ options: {}
767
+ };
764
768
  /**
765
769
  * Sets the socket options (`init({ realtime })` calls it). Takes effect on
766
770
  * the next connection.
767
771
  */
768
772
  function configureRealtime(options = {}) {
769
- configured = {
770
- ...configured,
771
- ...options
772
- };
773
- instance?.configure(configured);
773
+ Object.assign(realtime.options, options);
774
+ realtime.client?.configure(realtime.options);
774
775
  }
775
776
  /** The tab's client if it is already loaded, else `null`. Never loads it. */
776
777
  function loadedRealtimeClient() {
777
- return instance;
778
+ return realtime.client;
778
779
  }
780
+ var loading = null;
781
+ /** The lazily loaded client. Replaceable in tests, to simulate a failed load. */
782
+ var lazyModules = { client: () => import("./RealtimeClient-DsWbFRC7.js") };
779
783
  /**
780
- * What a lazy `import()` resolved to, or a thrown error when it is missing.
781
- * Vite's preload helper resolves the `import()` to `undefined` instead of
782
- * rejecting when a `vite:preloadError` listener handled the failure (`init`'s
783
- * chunk-load recovery does, as it starts a reload): treated as a failed load.
784
+ * `./live`, loaded by the first live query. `<Page>` in `gemi/testing` sets
785
+ * `current` up front, so a live query on a provided socket subscribes during
786
+ * its effect, as it did before the module was split out.
784
787
  */
785
- function loadedModule(module) {
786
- if (!module) throw new Error("[gemi] A lazily loaded chunk is unavailable.");
787
- return module;
788
- }
789
- /** The lazily loaded modules. Replaceable in tests, to simulate a failed load. */
790
- var lazyModules = {
791
- client: () => import("./RealtimeClient-CqGve6h8.js"),
792
- live: () => import("./live-DIUDdLrA.js").then((n) => n.t)
788
+ var liveModule = {
789
+ current: null,
790
+ load: () => import("./live-CUdMhXHL.js").then((n) => n.n)
793
791
  };
794
792
  /**
795
793
  * The tab's client, loading its module and creating it on first use. `null`
@@ -800,41 +798,29 @@ var lazyModules = {
800
798
  */
801
799
  function loadRealtimeClient() {
802
800
  if (typeof window === "undefined") return null;
803
- if (instance) return Promise.resolve(instance);
804
- loading ??= lazyModules.client().then((module) => instance ??= new (loadedModule(module)).RealtimeClient(configured)).catch((error) => {
801
+ if (realtime.client) return Promise.resolve(realtime.client);
802
+ loading ??= lazyModules.client().then((module) => loadedModule(module).tabClient()).catch((error) => {
805
803
  loading = null;
806
804
  throw error;
807
805
  });
808
806
  return loading;
809
807
  }
810
- var liveModule = null;
811
- /**
812
- * Makes `./live` available without loading it: `<Page>` in `gemi/testing`
813
- * passes it, so a live query on a provided socket subscribes during its
814
- * effect, as it did before the module was split out.
815
- */
816
- function provideLiveModule(module) {
817
- liveModule = module;
818
- }
819
808
  /**
820
809
  * Follows `useQuery`'s `live` channel until the returned function is called.
821
- * `./live` and the socket client are loaded on first use, so `useQuery`
822
- * carries only this; once both are loaded later queries subscribe at once.
823
- * `setOpen` reports `false` until the channel is open.
810
+ * `./live` loads on first use and does the rest, loading the socket client
811
+ * in turn, so `useQuery` carries only this. `setOpen` reports `false` until
812
+ * the channel is open.
824
813
  */
825
814
  function followLive(provided, live, resource, setOpen) {
826
- let cancelled = false;
827
- let stop = null;
828
- const start = (module, socket) => {
829
- liveModule = module;
830
- if (!cancelled && socket) stop = module.subscribeLive(socket, live, resource, setOpen);
815
+ let stop;
816
+ const start = (module) => {
817
+ if (stop === void 0) stop = module.followLive(provided, live, resource, setOpen);
831
818
  };
832
- const socket = provided ?? instance;
833
- if (liveModule && socket) start(liveModule, socket);
834
- else Promise.all([liveModule ?? lazyModules.live(), socket ?? loadRealtimeClient()]).then(([module, socket]) => start(loadedModule(module), socket)).catch(() => {});
819
+ if (liveModule.current) start(liveModule.current);
820
+ else loadLazy(liveModule).then(start).catch(() => {});
835
821
  return () => {
836
- cancelled = true;
837
822
  stop?.();
823
+ stop = null;
838
824
  setOpen(false);
839
825
  };
840
826
  }
@@ -844,14 +830,7 @@ function followLive(provided, live, resource, setOpen) {
844
830
  * Never loads or creates the client.
845
831
  */
846
832
  function reconnectRealtime() {
847
- instance?.reconnect();
848
- }
849
- /**
850
- * The open socket's id, for the `X-Gemi-Socket` header, or `null`. Never
851
- * loads or creates the client.
852
- */
853
- function currentSocketId() {
854
- return instance?.socketId ?? null;
833
+ realtime.client?.reconnect();
855
834
  }
856
835
  //#endregion
857
836
  //#region client/realtime/RealtimeContext.ts
@@ -3473,7 +3452,7 @@ function useChannelSubscription(pattern, params, handlers, enabled) {
3473
3452
  };
3474
3453
  }, [
3475
3454
  provided,
3476
- pattern === null ? null : channelKey(pattern, params),
3455
+ pattern === null ? null : JSON.stringify([pattern, params]),
3477
3456
  active
3478
3457
  ]);
3479
3458
  if (typeof window === "undefined") return active ? CLOSED : IDLE;
@@ -3629,6 +3608,6 @@ function useTheme() {
3629
3608
  return context;
3630
3609
  }
3631
3610
  //#endregion
3632
- export { DEFAULT_STALE_TIME as $, ServerDataContext as A, configureRealtime as B, readRoutePayload as C, useNavigate as D, useSearchParams as E, ProgressManager as F, reconnectRealtime as G, followLive as H, Action as I, QueryConfigContext as J, toVariantKey as K, createMemoryHistory as L, useLocation as M, domainUrl as N, I18nContext as O, isAbsoluteUrl as P, pickDefined as Q, RealtimeContext as R, setActiveLocale as S, useRoute as T, loadedModule as U, currentSocketId as V, provideLiveModule as W, QueryManagerProvider as X, QueryManagerContext as Y, USER_QUERY_CONFIG_KEYS as Z, isChunkLoadError as _, useRouteTransition as a, Subject as at, loadDictionaryForRender as b, ClientRouterContext as c, ComponentsProvider as d, isRetryableQueryError as et, initialViewModulesReady as f, configureChunkLoadRecovery as g, CHUNK_RELOAD_MARKER as h, RouteTransitionProvider as i, QueryError as it, ServerDataProvider as j, I18nProvider as k, ClientRouterProvider as l, subscribeViewModules as m, useTheme as n, retryDelayFor as nt, useChannelSubscription as o, loadViewModule as p, applyParams as q, m as r, shouldRetryQuery as rt, useCoalesced as s, ThemeProvider as t, parseRetryAfter as tt, ComponentsContext as u, recoverFromChunkLoadError as v, routeDataUrl as w, registerDictionary as x, loadDictionary as y, channelKey as z };
3611
+ export { DEFAULT_STALE_TIME as $, ServerDataContext as A, followLive as B, readRoutePayload as C, useNavigate as D, useSearchParams as E, ProgressManager as F, loadedModule as G, realtime as H, Action as I, QueryConfigContext as J, toVariantKey as K, createMemoryHistory as L, useLocation as M, domainUrl as N, I18nContext as O, isAbsoluteUrl as P, pickDefined as Q, RealtimeContext as R, setActiveLocale as S, useRoute as T, reconnectRealtime as U, liveModule as V, loadLazy as W, QueryManagerProvider as X, QueryManagerContext as Y, USER_QUERY_CONFIG_KEYS as Z, isChunkLoadError as _, useRouteTransition as a, Subject as at, loadDictionaryForRender as b, ClientRouterContext as c, ComponentsProvider as d, isRetryableQueryError as et, initialViewModulesReady as f, configureChunkLoadRecovery as g, CHUNK_RELOAD_MARKER as h, RouteTransitionProvider as i, QueryError as it, ServerDataProvider as j, I18nProvider as k, ClientRouterProvider as l, subscribeViewModules as m, useTheme as n, retryDelayFor as nt, useChannelSubscription as o, loadViewModule as p, applyParams as q, m as r, shouldRetryQuery as rt, useCoalesced as s, ThemeProvider as t, parseRetryAfter as tt, ComponentsContext as u, recoverFromChunkLoadError as v, routeDataUrl as w, registerDictionary as x, loadDictionary as y, configureRealtime as z };
3633
3612
 
3634
- //# sourceMappingURL=ThemeProvider-DaX0eyqs.js.map
3613
+ //# sourceMappingURL=ThemeProvider-gWqXjGh-.js.map