@terreno/rtk 0.13.3 → 0.14.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 (144) hide show
  1. package/dist/authSlice.test.js +2 -10
  2. package/dist/authSlice.test.js.map +1 -1
  3. package/dist/authSliceNative.test.js +11 -3
  4. package/dist/authSliceNative.test.js.map +1 -1
  5. package/dist/betterAuthSlice.test.js +1 -25
  6. package/dist/betterAuthSlice.test.js.map +1 -1
  7. package/dist/constants.d.ts +3 -0
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/constants.js +11 -3
  10. package/dist/constants.js.map +1 -1
  11. package/dist/constants.test.js +44 -2
  12. package/dist/constants.test.js.map +1 -1
  13. package/dist/emptyApi.d.ts +2 -0
  14. package/dist/emptyApi.d.ts.map +1 -1
  15. package/dist/emptyApi.js +5 -0
  16. package/dist/emptyApi.js.map +1 -1
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +8 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/isolated/constants.isolated.js +7 -1
  22. package/dist/isolated/constants.isolated.js.map +1 -1
  23. package/dist/isolated/offlineMiddleware.isolated.d.ts +2 -0
  24. package/dist/isolated/offlineMiddleware.isolated.d.ts.map +1 -0
  25. package/dist/isolated/offlineMiddleware.isolated.js +516 -0
  26. package/dist/isolated/offlineMiddleware.isolated.js.map +1 -0
  27. package/dist/isolated/offlineMiddleware.native.isolated.d.ts +2 -0
  28. package/dist/isolated/offlineMiddleware.native.isolated.d.ts.map +1 -0
  29. package/dist/isolated/offlineMiddleware.native.isolated.js +70 -0
  30. package/dist/isolated/offlineMiddleware.native.isolated.js.map +1 -0
  31. package/dist/isolated/useUpgradeCheck.mobile.isolated.d.ts +2 -0
  32. package/dist/isolated/useUpgradeCheck.mobile.isolated.d.ts.map +1 -0
  33. package/dist/{useUpgradeCheck.mobile.test.js → isolated/useUpgradeCheck.mobile.isolated.js} +13 -5
  34. package/dist/isolated/useUpgradeCheck.mobile.isolated.js.map +1 -0
  35. package/dist/isolated/useUpgradeCheck.web.isolated.d.ts +2 -0
  36. package/dist/isolated/useUpgradeCheck.web.isolated.d.ts.map +1 -0
  37. package/dist/{useUpgradeCheck.test.js → isolated/useUpgradeCheck.web.isolated.js} +37 -7
  38. package/dist/isolated/useUpgradeCheck.web.isolated.js.map +1 -0
  39. package/dist/mongooseSlice.test.js +1 -1
  40. package/dist/mongooseSlice.test.js.map +1 -1
  41. package/dist/offlineGate.d.ts +8 -0
  42. package/dist/offlineGate.d.ts.map +1 -0
  43. package/dist/offlineGate.js +20 -0
  44. package/dist/offlineGate.js.map +1 -0
  45. package/dist/offlineGate.test.d.ts +2 -0
  46. package/dist/offlineGate.test.d.ts.map +1 -0
  47. package/dist/offlineGate.test.js +46 -0
  48. package/dist/offlineGate.test.js.map +1 -0
  49. package/dist/offlineMiddleware.d.ts +46 -0
  50. package/dist/offlineMiddleware.d.ts.map +1 -0
  51. package/dist/offlineMiddleware.js +591 -0
  52. package/dist/offlineMiddleware.js.map +1 -0
  53. package/dist/offlineMiddleware.test.d.ts +2 -0
  54. package/dist/offlineMiddleware.test.d.ts.map +1 -0
  55. package/dist/offlineMiddleware.test.js +145 -0
  56. package/dist/offlineMiddleware.test.js.map +1 -0
  57. package/dist/offlineSlice.d.ts +232 -0
  58. package/dist/offlineSlice.d.ts.map +1 -0
  59. package/dist/offlineSlice.js +65 -0
  60. package/dist/offlineSlice.js.map +1 -0
  61. package/dist/offlineSlice.test.d.ts +2 -0
  62. package/dist/offlineSlice.test.d.ts.map +1 -0
  63. package/dist/offlineSlice.test.js +153 -0
  64. package/dist/offlineSlice.test.js.map +1 -0
  65. package/dist/realtime.d.ts +123 -0
  66. package/dist/realtime.d.ts.map +1 -0
  67. package/dist/realtime.js +299 -0
  68. package/dist/realtime.js.map +1 -0
  69. package/dist/realtime.test.d.ts +2 -0
  70. package/dist/realtime.test.d.ts.map +1 -0
  71. package/dist/realtime.test.js +339 -0
  72. package/dist/realtime.test.js.map +1 -0
  73. package/dist/socket.d.ts.map +1 -1
  74. package/dist/socket.js +29 -28
  75. package/dist/socket.js.map +1 -1
  76. package/dist/sync.d.ts +35 -0
  77. package/dist/sync.d.ts.map +1 -0
  78. package/dist/sync.js +205 -0
  79. package/dist/sync.js.map +1 -0
  80. package/dist/tagGenerator.d.ts +20 -1
  81. package/dist/tagGenerator.d.ts.map +1 -1
  82. package/dist/tagGenerator.js +1 -2
  83. package/dist/tagGenerator.js.map +1 -1
  84. package/dist/useOfflineStatus.d.ts +33 -0
  85. package/dist/useOfflineStatus.d.ts.map +1 -0
  86. package/dist/useOfflineStatus.js +43 -0
  87. package/dist/useOfflineStatus.js.map +1 -0
  88. package/dist/useOfflineStatus.test.d.ts +2 -0
  89. package/dist/useOfflineStatus.test.d.ts.map +1 -0
  90. package/dist/useOfflineStatus.test.js +119 -0
  91. package/dist/useOfflineStatus.test.js.map +1 -0
  92. package/dist/useRealtimeDebug.d.ts +6 -0
  93. package/dist/useRealtimeDebug.d.ts.map +1 -0
  94. package/dist/useRealtimeDebug.js +41 -0
  95. package/dist/useRealtimeDebug.js.map +1 -0
  96. package/dist/useServerStatus.d.ts +29 -0
  97. package/dist/useServerStatus.d.ts.map +1 -0
  98. package/dist/useServerStatus.js +89 -0
  99. package/dist/useServerStatus.js.map +1 -0
  100. package/dist/useUpgradeCheck.d.ts +7 -3
  101. package/dist/useUpgradeCheck.d.ts.map +1 -1
  102. package/dist/useUpgradeCheck.js +27 -13
  103. package/dist/useUpgradeCheck.js.map +1 -1
  104. package/package.json +2 -2
  105. package/src/authSlice.test.ts +2 -11
  106. package/src/authSliceNative.test.ts +11 -4
  107. package/src/betterAuthSlice.test.ts +1 -25
  108. package/src/constants.test.ts +54 -1
  109. package/src/constants.ts +14 -3
  110. package/src/emptyApi.ts +8 -0
  111. package/src/index.ts +8 -0
  112. package/src/isolated/constants.isolated.ts +7 -3
  113. package/src/isolated/offlineMiddleware.isolated.ts +696 -0
  114. package/src/isolated/offlineMiddleware.native.isolated.ts +80 -0
  115. package/src/{useUpgradeCheck.mobile.test.ts → isolated/useUpgradeCheck.mobile.isolated.ts} +13 -4
  116. package/src/{useUpgradeCheck.test.ts → isolated/useUpgradeCheck.web.isolated.ts} +48 -6
  117. package/src/mongooseSlice.test.ts +1 -1
  118. package/src/offlineGate.test.ts +55 -0
  119. package/src/offlineGate.ts +25 -0
  120. package/src/offlineMiddleware.test.ts +187 -0
  121. package/src/offlineMiddleware.ts +718 -0
  122. package/src/offlineSlice.test.ts +204 -0
  123. package/src/offlineSlice.ts +130 -0
  124. package/src/realtime.test.ts +404 -0
  125. package/src/realtime.ts +408 -0
  126. package/src/socket.ts +33 -32
  127. package/src/sync.ts +310 -0
  128. package/src/tagGenerator.ts +29 -11
  129. package/src/useOfflineStatus.test.ts +157 -0
  130. package/src/useOfflineStatus.ts +82 -0
  131. package/src/useRealtimeDebug.ts +51 -0
  132. package/src/useServerStatus.ts +122 -0
  133. package/src/useUpgradeCheck.ts +35 -13
  134. package/dist/isolated/useUpgradeCheck.isolated.d.ts +0 -2
  135. package/dist/isolated/useUpgradeCheck.isolated.d.ts.map +0 -1
  136. package/dist/isolated/useUpgradeCheck.isolated.js +0 -153
  137. package/dist/isolated/useUpgradeCheck.isolated.js.map +0 -1
  138. package/dist/useUpgradeCheck.mobile.test.d.ts +0 -2
  139. package/dist/useUpgradeCheck.mobile.test.d.ts.map +0 -1
  140. package/dist/useUpgradeCheck.mobile.test.js.map +0 -1
  141. package/dist/useUpgradeCheck.test.d.ts +0 -2
  142. package/dist/useUpgradeCheck.test.d.ts.map +0 -1
  143. package/dist/useUpgradeCheck.test.js.map +0 -1
  144. package/src/isolated/useUpgradeCheck.isolated.ts +0 -201
package/dist/sync.js ADDED
@@ -0,0 +1,205 @@
1
+ import { DateTime } from "luxon";
2
+ import { useEffect, useRef } from "react";
3
+ import { useDispatch, useStore } from "react-redux";
4
+ import { isWebsocketsDebugEnabled, logSocket } from "./constants";
5
+ /**
6
+ * Hook that connects WebSocket sync events to RTK Query's cache.
7
+ *
8
+ * For **create** events: invalidates cache tags to trigger refetch of list queries.
9
+ * For **update** events: patches entities in-place in cached queries, falling back to tag invalidation.
10
+ * For **delete** events: removes entities from cached list queries, falling back to tag invalidation.
11
+ *
12
+ * Automatically subscribes to model rooms for each tagType when the socket connects,
13
+ * so models using `roomStrategy: "model"` will work without additional setup.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const { socket } = useSocketConnection({ ... });
18
+ *
19
+ * useSyncConnection({
20
+ * socket,
21
+ * api: terrenoApi,
22
+ * tagTypes: ['todos', 'users'],
23
+ * });
24
+ * ```
25
+ */
26
+ export const useSyncConnection = ({ socket, api, tagTypes, debug = false, }) => {
27
+ const dispatch = useDispatch();
28
+ const store = useStore();
29
+ const tagTypesRef = useRef(tagTypes);
30
+ const apiRef = useRef(api);
31
+ tagTypesRef.current = tagTypes;
32
+ apiRef.current = api;
33
+ // Auto-subscribe to model rooms for each tagType when socket connects
34
+ useEffect(() => {
35
+ if (!socket) {
36
+ return;
37
+ }
38
+ const subscribeToModels = () => {
39
+ for (const tag of tagTypesRef.current) {
40
+ socket.emit("subscribe:model", tag);
41
+ }
42
+ };
43
+ // Subscribe on connect and when already connected
44
+ if (socket.connected) {
45
+ subscribeToModels();
46
+ }
47
+ socket.on("connect", subscribeToModels);
48
+ return () => {
49
+ socket.off("connect", subscribeToModels);
50
+ // Unsubscribe from model rooms on cleanup
51
+ if (socket.connected) {
52
+ for (const tag of tagTypesRef.current) {
53
+ socket.emit("unsubscribe:model", tag);
54
+ }
55
+ }
56
+ };
57
+ }, [socket]);
58
+ // Listen for sync events and update RTK Query cache
59
+ useEffect(() => {
60
+ if (!socket) {
61
+ return;
62
+ }
63
+ const log = (message) => {
64
+ if (isDebug) {
65
+ logSocket(true, message);
66
+ }
67
+ };
68
+ const logEvent = (event) => {
69
+ if (!isDebug) {
70
+ return;
71
+ }
72
+ logSocket(true, `sync event: ${JSON.stringify(event)}`);
73
+ };
74
+ const isDebug = debug ?? isWebsocketsDebugEnabled();
75
+ const getApiQueries = () => {
76
+ try {
77
+ const state = store.getState();
78
+ return state?.[apiRef.current.reducerPath]?.queries ?? null;
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ };
84
+ const handleSync = (event) => {
85
+ const { collection, method, id, data } = event;
86
+ const currentApi = apiRef.current;
87
+ // Only process events for collections we care about
88
+ if (!tagTypesRef.current.includes(collection)) {
89
+ log(`Ignoring event for collection: ${collection}`);
90
+ return;
91
+ }
92
+ log(`Received ${method} event for ${collection}/${id}`);
93
+ logEvent(event);
94
+ switch (method) {
95
+ case "update": {
96
+ if (!data) {
97
+ dispatch(currentApi.util.invalidateTags([collection]));
98
+ break;
99
+ }
100
+ const queries = getApiQueries();
101
+ if (!queries) {
102
+ dispatch(currentApi.util.invalidateTags([collection]));
103
+ break;
104
+ }
105
+ let patched = false;
106
+ for (const [_cacheKey, queryEntry] of Object.entries(queries)) {
107
+ const entry = queryEntry;
108
+ if (entry?.status !== "fulfilled" || !entry?.data) {
109
+ continue;
110
+ }
111
+ const { endpointName, originalArgs } = entry;
112
+ // List response: {data: [...], total, page, more}
113
+ if (entry.data?.data && Array.isArray(entry.data.data)) {
114
+ const hasEntity = entry.data.data.some((item) => item._id === id || item.id === id);
115
+ if (hasEntity) {
116
+ dispatch(currentApi.util.updateQueryData(endpointName, originalArgs, (draft) => {
117
+ if (draft?.data && Array.isArray(draft.data)) {
118
+ const index = draft.data.findIndex((item) => item._id === id || item.id === id);
119
+ if (index !== -1) {
120
+ // Stale event check via updated timestamp
121
+ const cachedUpdated = draft.data[index].updated;
122
+ if (cachedUpdated &&
123
+ data.updated &&
124
+ DateTime.fromISO(cachedUpdated) > DateTime.fromISO(data.updated)) {
125
+ log(`Skipping stale update for ${collection}/${id}`);
126
+ return;
127
+ }
128
+ Object.assign(draft.data[index], data);
129
+ }
130
+ }
131
+ }));
132
+ patched = true;
133
+ }
134
+ }
135
+ // Single entity response: {_id, ...fields}
136
+ else if (entry.data?._id === id || entry.data?.id === id) {
137
+ const cachedUpdated = entry.data.updated;
138
+ if (cachedUpdated &&
139
+ data.updated &&
140
+ DateTime.fromISO(cachedUpdated) > DateTime.fromISO(data.updated)) {
141
+ log(`Skipping stale update for ${collection}/${id}`);
142
+ continue;
143
+ }
144
+ dispatch(currentApi.util.updateQueryData(endpointName, originalArgs, (draft) => {
145
+ Object.assign(draft, data);
146
+ }));
147
+ patched = true;
148
+ }
149
+ }
150
+ if (!patched) {
151
+ dispatch(currentApi.util.invalidateTags([collection]));
152
+ }
153
+ break;
154
+ }
155
+ case "delete": {
156
+ const queries = getApiQueries();
157
+ if (!queries) {
158
+ dispatch(currentApi.util.invalidateTags([collection]));
159
+ break;
160
+ }
161
+ let patched = false;
162
+ for (const [_cacheKey, queryEntry] of Object.entries(queries)) {
163
+ const entry = queryEntry;
164
+ if (entry?.status !== "fulfilled" || !entry?.data) {
165
+ continue;
166
+ }
167
+ const { endpointName, originalArgs } = entry;
168
+ // List response with data array
169
+ if (entry.data?.data && Array.isArray(entry.data.data)) {
170
+ const hasEntity = entry.data.data.some((item) => item._id === id || item.id === id);
171
+ if (hasEntity) {
172
+ dispatch(currentApi.util.updateQueryData(endpointName, originalArgs, (draft) => {
173
+ if (draft?.data && Array.isArray(draft.data)) {
174
+ draft.data = draft.data.filter((item) => item._id !== id && item.id !== id);
175
+ if (typeof draft.total === "number") {
176
+ draft.total = Math.max(0, draft.total - 1);
177
+ }
178
+ }
179
+ }));
180
+ patched = true;
181
+ }
182
+ }
183
+ }
184
+ if (!patched) {
185
+ dispatch(currentApi.util.invalidateTags([collection]));
186
+ }
187
+ break;
188
+ }
189
+ case "create": {
190
+ // For creates, we can't determine filter match client-side,
191
+ // so invalidate tags to trigger refetch of list queries
192
+ dispatch(currentApi.util.invalidateTags([collection]));
193
+ break;
194
+ }
195
+ }
196
+ };
197
+ socket.on("sync", handleSync);
198
+ log("Listening for sync events");
199
+ return () => {
200
+ socket.off("sync", handleSync);
201
+ log("Stopped listening for sync events");
202
+ };
203
+ }, [socket, dispatch, store, debug]);
204
+ };
205
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,21 @@
1
- export declare const generateTags: (api: any, tagTypes: string[]) => any;
1
+ interface TagProviderResult {
2
+ data?: Array<{
3
+ _id: string;
4
+ }>;
5
+ _id?: string;
6
+ }
7
+ type TagEntry = string | {
8
+ type: string;
9
+ id?: string;
10
+ };
11
+ type TagProviderFn = (result: TagProviderResult | null | undefined) => TagEntry[];
12
+ interface EndpointTagConfig {
13
+ providesTags: TagProviderFn;
14
+ invalidatesTags: TagProviderFn;
15
+ }
16
+ interface ApiWithEndpoints {
17
+ endpoints: Record<string, unknown>;
18
+ }
19
+ export declare const generateTags: (api: ApiWithEndpoints, tagTypes: string[]) => Record<string, EndpointTagConfig>;
20
+ export {};
2
21
  //# sourceMappingURL=tagGenerator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tagGenerator.d.ts","sourceRoot":"","sources":["../src/tagGenerator.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,YAAY,GAAI,KAAK,GAAG,EAAE,UAAU,MAAM,EAAE,KAAG,GA4C3D,CAAC"}
1
+ {"version":3,"file":"tagGenerator.d.ts","sourceRoot":"","sources":["../src/tagGenerator.ts"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,IAAI,CAAC,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,QAAQ,GAAG,MAAM,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AACrD,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;AAElF,UAAU,iBAAiB;IACzB,YAAY,EAAE,aAAa,CAAC;IAC5B,eAAe,EAAE,aAAa,CAAC;CAChC;AAED,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAgCD,eAAO,MAAM,YAAY,GACvB,KAAK,gBAAgB,EACrB,UAAU,MAAM,EAAE,KACjB,MAAM,CAAC,MAAM,EAAE,iBAAiB,CA4ClC,CAAC"}
@@ -1,4 +1,3 @@
1
- // biome-ignore-all lint/suspicious/noExplicitAny: Generics
2
1
  // use this with enhanceEndpoints since the code generator doesn't invalidate by individual ids,
3
2
  // only at the full collection level
4
3
  const providesIdTags = (path) => (result) => result ? [...(result?.data?.map(({ _id }) => ({ id: _id, type: path })) ?? []), path] : [path];
@@ -24,7 +23,7 @@ export const generateTags = (api, tagTypes) => {
24
23
  const tags = {};
25
24
  Object.keys(endpoints).forEach((endpoint) => {
26
25
  if (endpoint === "getConversations") {
27
- tags[endpoint] = { invalidatesTags: ["conversations", "messages"] };
26
+ tags[endpoint] = { invalidatesTags: () => ["conversations", "messages"] };
28
27
  }
29
28
  if (endpoint.toLowerCase().includes("get")) {
30
29
  // List endpoints
@@ -1 +1 @@
1
- {"version":3,"file":"tagGenerator.js","sourceRoot":"","sources":["../src/tagGenerator.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,gGAAgG;AAChG,oCAAoC;AAEpC,MAAM,cAAc,GAClB,CAAC,IAAY,EAAE,EAAE,CACjB,CAAC,MAAW,EAA4C,EAAE,CACxD,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,EAAC,GAAG,EAAM,EAAE,EAAE,CAAC,CAAC,EAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAEpG,MAAM,aAAa,GACjB,CAAC,IAAY,EAAE,EAAE,CACjB,CAAC,MAAW,EAA4C,EAAE;IACxD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEJ,MAAM,iBAAiB,GACrB,CAAC,IAAY,EAAE,EAAE,CACjB,CAAC,MAAW,EAA4C,EAAE,CACxD,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,EAAC,GAAG,EAAM,EAAE,EAAE,CAAC,CAAC,EAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAEpG,MAAM,gCAAgC,GAAG,CAAC,MAAc,EAAU,EAAE;IAClE,iCAAiC;IACjC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,CAAC;IAEtB,+DAA+D;IAC/D,MAAM,aAAa,GAAG,KAAK,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACjD,MAAM,aAAa,GAAG,GAAG,MAAM,GAAG,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,aAAa,IAAI,aAAa,EAAE,EAAE,IAAI,CAAC,CAAC;IAEpE,qDAAqD;IACrD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,QAAkB,EAAO,EAAE;IAChE,kGAAkG;IAClG,2BAA2B;IAC3B,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAChC,MAAM,IAAI,GAAQ,EAAE,CAAC;IACrB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC1C,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAC,eAAe,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC,EAAC,CAAC;QACpE,CAAC;QACD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,iBAAiB;YACjB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE;gBACtC,wEAAwE;gBACxE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC,QAAQ,CAAC,CAAC,CACrE,CAAC;gBACF,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAC,YAAY,EAAE,cAAc,CAAC,GAAG,CAAC,EAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YACD,iBAAiB;iBACZ,CAAC;gBACJ,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CACtC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC,QAAQ,CAAC,CAAC,CACrE,CAAC;gBACF,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAC,YAAY,EAAE,aAAa,CAAC,GAAG,CAAC,EAAC,CAAC;gBACtD,CAAC;YACH,CAAC;QACH,CAAC;QACD,6BAA6B;aACxB,IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YACxC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACzC,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CACtC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC,QAAQ,CAAC,CAAC,CACrE,CAAC;YACF,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAC,eAAe,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
1
+ {"version":3,"file":"tagGenerator.js","sourceRoot":"","sources":["../src/tagGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type ConflictRecord } from "./offlineSlice";
2
+ export interface OfflineStatus {
3
+ /** Whether the device currently has network connectivity */
4
+ isOnline: boolean;
5
+ /** Number of mutations waiting to be synced */
6
+ queueLength: number;
7
+ /** Whether mutations are currently being replayed to the server */
8
+ isSyncing: boolean;
9
+ /** All conflict records (including dismissed) */
10
+ conflicts: ConflictRecord[];
11
+ /** Conflict records the user hasn't dismissed yet */
12
+ undismissedConflicts: ConflictRecord[];
13
+ /** Dismiss a single conflict notification by ID */
14
+ dismissConflict: (id: string) => void;
15
+ /** Clear all conflict records */
16
+ clearConflicts: () => void;
17
+ /** Returns true if the item exists only locally (not yet synced to server) */
18
+ isLocalOnly: (id: string) => boolean;
19
+ }
20
+ /**
21
+ * Hook for consuming offline state, sync status, and conflict notifications.
22
+ *
23
+ * Usage:
24
+ * ```typescript
25
+ * const {isOnline, queueLength, isSyncing, undismissedConflicts, dismissConflict} = useOfflineStatus();
26
+ *
27
+ * if (!isOnline) {
28
+ * return <Banner text={`Offline. ${queueLength} changes pending.`} />;
29
+ * }
30
+ * ```
31
+ */
32
+ export declare const useOfflineStatus: () => OfflineStatus;
33
+ //# sourceMappingURL=useOfflineStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOfflineStatus.d.ts","sourceRoot":"","sources":["../src/useOfflineStatus.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EASpB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,qDAAqD;IACrD,oBAAoB,EAAE,cAAc,EAAE,CAAC;IACvC,mDAAmD;IACnD,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,iCAAiC;IACjC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,8EAA8E;IAC9E,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,QAAO,aAmCnC,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { useCallback } from "react";
2
+ import { useDispatch, useSelector } from "react-redux";
3
+ import { clearConflicts, dismissConflict, selectConflicts, selectIsOnline, selectIsSyncing, selectQueueLength, selectUndismissedConflicts, } from "./offlineSlice";
4
+ /**
5
+ * Hook for consuming offline state, sync status, and conflict notifications.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * const {isOnline, queueLength, isSyncing, undismissedConflicts, dismissConflict} = useOfflineStatus();
10
+ *
11
+ * if (!isOnline) {
12
+ * return <Banner text={`Offline. ${queueLength} changes pending.`} />;
13
+ * }
14
+ * ```
15
+ */
16
+ export const useOfflineStatus = () => {
17
+ const dispatch = useDispatch();
18
+ const isOnline = useSelector((state) => selectIsOnline(state));
19
+ const queueLength = useSelector((state) => selectQueueLength(state));
20
+ const isSyncing = useSelector((state) => selectIsSyncing(state));
21
+ const conflicts = useSelector((state) => selectConflicts(state));
22
+ const undismissedConflicts = useSelector((state) => selectUndismissedConflicts(state));
23
+ const handleDismissConflict = useCallback((id) => {
24
+ dispatch(dismissConflict(id));
25
+ }, [dispatch]);
26
+ const handleClearConflicts = useCallback(() => {
27
+ dispatch(clearConflicts());
28
+ }, [dispatch]);
29
+ const isLocalOnly = useCallback((id) => {
30
+ return typeof id === "string" && id.startsWith("temp-");
31
+ }, []);
32
+ return {
33
+ clearConflicts: handleClearConflicts,
34
+ conflicts,
35
+ dismissConflict: handleDismissConflict,
36
+ isLocalOnly,
37
+ isOnline,
38
+ isSyncing,
39
+ queueLength,
40
+ undismissedConflicts,
41
+ };
42
+ };
43
+ //# sourceMappingURL=useOfflineStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOfflineStatus.js","sourceRoot":"","sources":["../src/useOfflineStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,OAAO,CAAC;AAClC,OAAO,EAAC,WAAW,EAAE,WAAW,EAAC,MAAM,aAAa,CAAC;AAErD,OAAO,EAEL,cAAc,EACd,eAAe,EAEf,eAAe,EACf,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AAqBxB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAkB,EAAE;IAClD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,KAA8B,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IACxF,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAA8B,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9F,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,KAA8B,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1F,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,KAA8B,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1F,MAAM,oBAAoB,GAAG,WAAW,CAAC,CAAC,KAA8B,EAAE,EAAE,CAC1E,0BAA0B,CAAC,KAAK,CAAC,CAClC,CAAC;IAEF,MAAM,qBAAqB,GAAG,WAAW,CACvC,CAAC,EAAU,EAAE,EAAE;QACb,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7B,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,EAAU,EAAW,EAAE;QACtD,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,cAAc,EAAE,oBAAoB;QACpC,SAAS;QACT,eAAe,EAAE,qBAAqB;QACtC,WAAW;QACX,QAAQ;QACR,SAAS;QACT,WAAW;QACX,oBAAoB;KACrB,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useOfflineStatus.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOfflineStatus.test.d.ts","sourceRoot":"","sources":["../src/useOfflineStatus.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import { beforeEach, describe, expect, it } from "bun:test";
2
+ import { configureStore } from "@reduxjs/toolkit";
3
+ import { act, renderHook } from "@testing-library/react-native";
4
+ import React from "react";
5
+ import { Provider } from "react-redux";
6
+ import { addConflict, enqueue, offlineReducer, setOnlineStatus, setSyncing, } from "./offlineSlice";
7
+ import { useOfflineStatus } from "./useOfflineStatus";
8
+ const createTestStore = () => configureStore({
9
+ reducer: { offline: offlineReducer },
10
+ });
11
+ const createWrapper = (store) => {
12
+ const Wrapper = ({ children }) => React.createElement(Provider, { children, store });
13
+ return Wrapper;
14
+ };
15
+ describe("useOfflineStatus", () => {
16
+ let store;
17
+ beforeEach(() => {
18
+ store = createTestStore();
19
+ });
20
+ it("returns initial online state", () => {
21
+ const { result } = renderHook(() => useOfflineStatus(), {
22
+ wrapper: createWrapper(store),
23
+ });
24
+ expect(result.current.isOnline).toBe(true);
25
+ expect(result.current.queueLength).toBe(0);
26
+ expect(result.current.isSyncing).toBe(false);
27
+ expect(result.current.conflicts).toEqual([]);
28
+ expect(result.current.undismissedConflicts).toEqual([]);
29
+ });
30
+ it("reflects offline state", () => {
31
+ store.dispatch(setOnlineStatus(false));
32
+ const { result } = renderHook(() => useOfflineStatus(), {
33
+ wrapper: createWrapper(store),
34
+ });
35
+ expect(result.current.isOnline).toBe(false);
36
+ });
37
+ it("reports queue length", () => {
38
+ const mutation = {
39
+ args: { body: { title: "Test" } },
40
+ endpointName: "postTodos",
41
+ id: "test-1",
42
+ timestamp: "2026-01-01T00:00:00.000Z",
43
+ type: "create",
44
+ };
45
+ store.dispatch(enqueue(mutation));
46
+ const { result } = renderHook(() => useOfflineStatus(), {
47
+ wrapper: createWrapper(store),
48
+ });
49
+ expect(result.current.queueLength).toBe(1);
50
+ });
51
+ it("reports syncing state", () => {
52
+ store.dispatch(setSyncing(true));
53
+ const { result } = renderHook(() => useOfflineStatus(), {
54
+ wrapper: createWrapper(store),
55
+ });
56
+ expect(result.current.isSyncing).toBe(true);
57
+ });
58
+ it("filters undismissed conflicts", () => {
59
+ const conflict = {
60
+ args: { id: "abc" },
61
+ dismissed: false,
62
+ endpointName: "patchTodosById",
63
+ id: "conflict-1",
64
+ serverDocument: { title: "Server" },
65
+ timestamp: "2026-01-01T00:00:00.000Z",
66
+ };
67
+ store.dispatch(addConflict(conflict));
68
+ const { result } = renderHook(() => useOfflineStatus(), {
69
+ wrapper: createWrapper(store),
70
+ });
71
+ expect(result.current.conflicts).toHaveLength(1);
72
+ expect(result.current.undismissedConflicts).toHaveLength(1);
73
+ });
74
+ it("dismissConflict dispatches the action", () => {
75
+ const conflict = {
76
+ args: { id: "abc" },
77
+ dismissed: false,
78
+ endpointName: "patchTodosById",
79
+ id: "conflict-to-dismiss",
80
+ serverDocument: { title: "Server" },
81
+ timestamp: "2026-01-01T00:00:00.000Z",
82
+ };
83
+ store.dispatch(addConflict(conflict));
84
+ const { result } = renderHook(() => useOfflineStatus(), {
85
+ wrapper: createWrapper(store),
86
+ });
87
+ act(() => {
88
+ result.current.dismissConflict("conflict-to-dismiss");
89
+ });
90
+ expect(result.current.undismissedConflicts).toHaveLength(0);
91
+ expect(result.current.conflicts[0].dismissed).toBe(true);
92
+ });
93
+ it("clearConflicts removes all conflicts", () => {
94
+ const conflict = {
95
+ args: { id: "abc" },
96
+ dismissed: false,
97
+ endpointName: "patchTodosById",
98
+ id: "conflict-clear",
99
+ serverDocument: { title: "Server" },
100
+ timestamp: "2026-01-01T00:00:00.000Z",
101
+ };
102
+ store.dispatch(addConflict(conflict));
103
+ const { result } = renderHook(() => useOfflineStatus(), {
104
+ wrapper: createWrapper(store),
105
+ });
106
+ act(() => {
107
+ result.current.clearConflicts();
108
+ });
109
+ expect(result.current.conflicts).toHaveLength(0);
110
+ });
111
+ it("isLocalOnly returns true for temp-prefixed IDs", () => {
112
+ const { result } = renderHook(() => useOfflineStatus(), {
113
+ wrapper: createWrapper(store),
114
+ });
115
+ expect(result.current.isLocalOnly("temp-abc123")).toBe(true);
116
+ expect(result.current.isLocalOnly("507f1f77bcf86cd799439011")).toBe(false);
117
+ });
118
+ });
119
+ //# sourceMappingURL=useOfflineStatus.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOfflineStatus.test.js","sourceRoot":"","sources":["../src/useOfflineStatus.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Syncs websocket debug logging with the backend RealtimeApp debug flag.
3
+ * Also respects WEBSOCKETS_DEBUG from app config via isWebsocketsDebugEnabled().
4
+ */
5
+ export declare const useRealtimeDebug: (baseUrl: string, refreshKey?: unknown) => boolean;
6
+ //# sourceMappingURL=useRealtimeDebug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRealtimeDebug.d.ts","sourceRoot":"","sources":["../src/useRealtimeDebug.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,aAAa,OAAO,KAAG,OAoCxE,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useSelector } from "react-redux";
3
+ import { isWebsocketsDebugEnabled, setRealtimeDebug } from "./constants";
4
+ import { selectIsOnlineSafe } from "./offlineSlice";
5
+ /**
6
+ * Syncs websocket debug logging with the backend RealtimeApp debug flag.
7
+ * Also respects WEBSOCKETS_DEBUG from app config via isWebsocketsDebugEnabled().
8
+ */
9
+ export const useRealtimeDebug = (baseUrl, refreshKey) => {
10
+ const [debugEnabled, setDebugEnabled] = useState(isWebsocketsDebugEnabled);
11
+ const isOnline = useSelector(selectIsOnlineSafe);
12
+ useEffect(() => {
13
+ if (!isOnline) {
14
+ return;
15
+ }
16
+ let cancelled = false;
17
+ const loadDebugFlag = async () => {
18
+ try {
19
+ const response = await fetch(`${baseUrl}/realtime/health`);
20
+ if (!response.ok) {
21
+ return;
22
+ }
23
+ const data = (await response.json());
24
+ if (cancelled) {
25
+ return;
26
+ }
27
+ setRealtimeDebug(data.debug === true);
28
+ setDebugEnabled(isWebsocketsDebugEnabled());
29
+ }
30
+ catch {
31
+ // Health endpoint unavailable — keep env-based debug only
32
+ }
33
+ };
34
+ void loadDebugFlag();
35
+ return () => {
36
+ cancelled = true;
37
+ };
38
+ }, [baseUrl, refreshKey, isOnline]);
39
+ return debugEnabled;
40
+ };
41
+ //# sourceMappingURL=useRealtimeDebug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRealtimeDebug.js","sourceRoot":"","sources":["../src/useRealtimeDebug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,EAAC,wBAAwB,EAAE,gBAAgB,EAAC,MAAM,aAAa,CAAC;AACvE,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAMlD;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,UAAoB,EAAW,EAAE;IACjF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,wBAAwB,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;YAC9C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,CAAC,CAAC;gBAC3D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;gBAC/D,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,gBAAgB,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;gBACtC,eAAe,CAAC,wBAAwB,EAAE,CAAC,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,aAAa,EAAE,CAAC;QAErB,OAAO,GAAS,EAAE;YAChB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEpC,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type OfflineStatus } from "./useOfflineStatus";
2
+ export interface ServerStatusOptions {
3
+ /** URL to poll for server health. Defaults to `${baseUrl}/health`. */
4
+ healthUrl?: string;
5
+ /** Polling interval in ms while online. Default 5000. */
6
+ pollIntervalMs?: number;
7
+ /** Polling interval in ms while offline. Default 3000. */
8
+ offlinePollIntervalMs?: number;
9
+ /** Skip polling entirely (e.g. when not authenticated). */
10
+ skip?: boolean;
11
+ }
12
+ export type ServerStatus = OfflineStatus;
13
+ /**
14
+ * Polls the API server health endpoint to determine actual server reachability.
15
+ * Dispatches setOnlineStatus(true/false) into the offline slice so the rest
16
+ * of the offline middleware (queue, optimistic updates, replay) reacts.
17
+ *
18
+ * Use this instead of useOfflineStatus when you want real server-connectivity
19
+ * detection rather than just browser navigator.onLine.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const {isOnline, queueLength, isSyncing, isLocalOnly} = useServerStatus({
24
+ * skip: !userId,
25
+ * });
26
+ * ```
27
+ */
28
+ export declare const useServerStatus: (options?: ServerStatusOptions) => ServerStatus;
29
+ //# sourceMappingURL=useServerStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useServerStatus.d.ts","sourceRoot":"","sources":["../src/useServerStatus.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,KAAK,aAAa,EAAmB,MAAM,oBAAoB,CAAC;AAKxE,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,UAAS,mBAAwB,KAAG,YAmFnE,CAAC"}