@fitzzero/quickdraw-core 3.6.0 → 3.8.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.
- package/README.md +218 -64
- package/dist/client/index.d.ts +34 -4
- package/dist/client/index.js +57 -65
- package/dist/client/index.js.map +1 -1
- package/dist/client/testing.d.ts +1 -1
- package/dist/client/testing.js.map +1 -1
- package/dist/server/express/index.d.ts +37 -0
- package/dist/server/express/index.js +60 -0
- package/dist/server/express/index.js.map +1 -0
- package/dist/server/index.d.ts +330 -5
- package/dist/server/index.js +593 -144
- package/dist/server/index.js.map +1 -1
- package/dist/server/testing-prisma.d.ts +101 -0
- package/dist/server/testing-prisma.js +172 -0
- package/dist/server/testing-prisma.js.map +1 -0
- package/dist/server/testing.d.ts +1 -1
- package/dist/server/testing.js +87 -22
- package/dist/server/testing.js.map +1 -1
- package/dist/shared/index.d.ts +77 -1
- package/dist/shared/index.js +5 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/{types-DniMxkQs.d.ts → types-ClgSr90l.d.ts} +5 -1
- package/dist/{types-B1z5aXdR.d.ts → types-DUHPIy_5.d.ts} +20 -1
- package/eslint-config/index.mjs +1 -2
- package/eslint-plugin-quickdraw/index.mjs +15 -7
- package/eslint-plugin-quickdraw/rules/no-cross-service-mutations.mjs +31 -32
- package/eslint-plugin-quickdraw/rules/no-direct-prisma-mutations.mjs +17 -18
- package/eslint-plugin-quickdraw/rules/no-raw-button-strings.mjs +52 -0
- package/eslint-plugin-quickdraw/rules/no-raw-service-room-string.mjs +140 -0
- package/eslint-plugin-quickdraw/rules/no-raw-socket-emit.mjs +20 -22
- package/eslint-plugin-quickdraw/rules/no-raw-socket-on.mjs +17 -17
- package/eslint-plugin-quickdraw/rules/no-raw-tooltip-strings.mjs +59 -0
- package/eslint-plugin-quickdraw/rules/no-raw-typography-strings.mjs +52 -0
- package/eslint-plugin-quickdraw/rules/no-service-method-record.mjs +3 -3
- package/eslint-plugin-quickdraw/rules/no-unsafe-payload-cast.mjs +8 -8
- package/eslint-plugin-quickdraw/rules/require-zod-schema.mjs +15 -20
- package/package.json +74 -50
package/dist/client/index.js
CHANGED
|
@@ -115,9 +115,7 @@ var QuickdrawSocketContext = React.createContext(null);
|
|
|
115
115
|
function useQuickdrawSocket() {
|
|
116
116
|
const context = React.useContext(QuickdrawSocketContext);
|
|
117
117
|
if (!context) {
|
|
118
|
-
throw new Error(
|
|
119
|
-
"useQuickdrawSocket must be used within a QuickdrawProvider"
|
|
120
|
-
);
|
|
118
|
+
throw new Error("useQuickdrawSocket must be used within a QuickdrawProvider");
|
|
121
119
|
}
|
|
122
120
|
return context;
|
|
123
121
|
}
|
|
@@ -141,7 +139,8 @@ function QuickdrawProvider({
|
|
|
141
139
|
queryClient,
|
|
142
140
|
authToken,
|
|
143
141
|
autoConnect = !!authToken,
|
|
144
|
-
withCredentials = true
|
|
142
|
+
withCredentials = true,
|
|
143
|
+
socketPath
|
|
145
144
|
}) {
|
|
146
145
|
const [defaultQueryClient] = React.useState(() => createQueryClient());
|
|
147
146
|
const actualQueryClient = queryClient ?? defaultQueryClient;
|
|
@@ -149,9 +148,7 @@ function QuickdrawProvider({
|
|
|
149
148
|
const [isConnected, setIsConnected] = React.useState(false);
|
|
150
149
|
const [userId, setUserId] = React.useState(null);
|
|
151
150
|
const [serviceAccess, setServiceAccess] = React.useState({});
|
|
152
|
-
const subscriptionRegistryRef = React.useRef(
|
|
153
|
-
createSubscriptionRegistry()
|
|
154
|
-
);
|
|
151
|
+
const subscriptionRegistryRef = React.useRef(createSubscriptionRegistry());
|
|
155
152
|
const prevAuthTokenRef = React.useRef(authToken);
|
|
156
153
|
const socketRef = React.useRef(null);
|
|
157
154
|
const subscriptionBatcherRef = React.useRef(
|
|
@@ -167,7 +164,8 @@ function QuickdrawProvider({
|
|
|
167
164
|
auth: authToUse ? { token: authToUse } : void 0,
|
|
168
165
|
withCredentials,
|
|
169
166
|
transports: ["websocket", "polling"],
|
|
170
|
-
autoConnect: true
|
|
167
|
+
autoConnect: true,
|
|
168
|
+
...socketPath ? { path: socketPath } : {}
|
|
171
169
|
});
|
|
172
170
|
newSocket.on("connect", () => {
|
|
173
171
|
setIsConnected(true);
|
|
@@ -189,7 +187,7 @@ function QuickdrawProvider({
|
|
|
189
187
|
socketRef.current = newSocket;
|
|
190
188
|
setSocket(newSocket);
|
|
191
189
|
},
|
|
192
|
-
[serverUrl, withCredentials]
|
|
190
|
+
[serverUrl, withCredentials, socketPath]
|
|
193
191
|
);
|
|
194
192
|
const disconnect = React.useCallback(() => {
|
|
195
193
|
if (socketRef.current) {
|
|
@@ -259,18 +257,14 @@ function useService(serviceName, methodName, options) {
|
|
|
259
257
|
const timeout = setTimeout(() => {
|
|
260
258
|
reject(new Error("Request timeout"));
|
|
261
259
|
}, options?.timeout ?? 1e4);
|
|
262
|
-
socket.emit(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
resolve(response.data);
|
|
269
|
-
} else {
|
|
270
|
-
reject(new Error(response.error));
|
|
271
|
-
}
|
|
260
|
+
socket.emit(eventName, payload, (response) => {
|
|
261
|
+
clearTimeout(timeout);
|
|
262
|
+
if (response.success) {
|
|
263
|
+
resolve(response.data);
|
|
264
|
+
} else {
|
|
265
|
+
reject(new Error(response.error));
|
|
272
266
|
}
|
|
273
|
-
);
|
|
267
|
+
});
|
|
274
268
|
});
|
|
275
269
|
},
|
|
276
270
|
onSuccess: (data) => {
|
|
@@ -334,24 +328,20 @@ function useServiceMethod(serviceName, methodName, options) {
|
|
|
334
328
|
optionsRef.current?.onError?.(errorMsg);
|
|
335
329
|
resolve(null);
|
|
336
330
|
}, options?.timeout ?? 1e4);
|
|
337
|
-
socket.emit(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
(response)
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
setError(response.error);
|
|
350
|
-
optionsRef.current?.onError?.(response.error);
|
|
351
|
-
resolve(null);
|
|
352
|
-
}
|
|
331
|
+
socket.emit(eventName, payload, (response) => {
|
|
332
|
+
clearTimeout(timeout);
|
|
333
|
+
setLoading(false);
|
|
334
|
+
if (response.success) {
|
|
335
|
+
setError(null);
|
|
336
|
+
setData(response.data);
|
|
337
|
+
optionsRef.current?.onSuccess?.(response.data);
|
|
338
|
+
resolve(response.data);
|
|
339
|
+
} else {
|
|
340
|
+
setError(response.error);
|
|
341
|
+
optionsRef.current?.onError?.(response.error);
|
|
342
|
+
resolve(null);
|
|
353
343
|
}
|
|
354
|
-
);
|
|
344
|
+
});
|
|
355
345
|
});
|
|
356
346
|
},
|
|
357
347
|
[socket, isConnected, serviceName, methodName, options?.timeout]
|
|
@@ -402,18 +392,14 @@ function useServiceQuery(serviceName, methodName, payload, options) {
|
|
|
402
392
|
const timeoutId = setTimeout(() => {
|
|
403
393
|
reject(new Error("Request timeout"));
|
|
404
394
|
}, timeout);
|
|
405
|
-
socket.emit(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
resolve(response.data);
|
|
412
|
-
} else {
|
|
413
|
-
reject(new Error(response.error));
|
|
414
|
-
}
|
|
395
|
+
socket.emit(eventName, payload, (response) => {
|
|
396
|
+
clearTimeout(timeoutId);
|
|
397
|
+
if (response.success) {
|
|
398
|
+
resolve(response.data);
|
|
399
|
+
} else {
|
|
400
|
+
reject(new Error(response.error));
|
|
415
401
|
}
|
|
416
|
-
);
|
|
402
|
+
});
|
|
417
403
|
});
|
|
418
404
|
}, [socket, isConnected, serviceName, methodName, payload, timeout]);
|
|
419
405
|
React.useEffect(() => {
|
|
@@ -564,10 +550,7 @@ function useSubscription(serviceName, entryId, options = {}) {
|
|
|
564
550
|
socket.on(updateEvent, handleUpdate);
|
|
565
551
|
const handleBatchResponse = (response) => {
|
|
566
552
|
if (response.success && response.data) {
|
|
567
|
-
queryClient.setQueryData(
|
|
568
|
-
queryKey,
|
|
569
|
-
response.data
|
|
570
|
-
);
|
|
553
|
+
queryClient.setQueryData(queryKey, response.data);
|
|
571
554
|
setIsSubscribed(true);
|
|
572
555
|
setError(null);
|
|
573
556
|
onDataRef.current?.(response.data);
|
|
@@ -577,24 +560,14 @@ function useSubscription(serviceName, entryId, options = {}) {
|
|
|
577
560
|
onErrorRef.current?.(response.error ?? "Subscription failed");
|
|
578
561
|
}
|
|
579
562
|
};
|
|
580
|
-
subscriptionBatcher.enqueue(
|
|
581
|
-
serviceName,
|
|
582
|
-
entryId,
|
|
583
|
-
requiredLevel,
|
|
584
|
-
handleBatchResponse
|
|
585
|
-
);
|
|
563
|
+
subscriptionBatcher.enqueue(serviceName, entryId, requiredLevel, handleBatchResponse);
|
|
586
564
|
let visibilityDebounceTimer = null;
|
|
587
565
|
const handleVisibilityChange = () => {
|
|
588
566
|
if (document.visibilityState !== "visible") return;
|
|
589
567
|
if (visibilityDebounceTimer) clearTimeout(visibilityDebounceTimer);
|
|
590
568
|
visibilityDebounceTimer = setTimeout(() => {
|
|
591
569
|
visibilityDebounceTimer = null;
|
|
592
|
-
subscriptionBatcher.enqueue(
|
|
593
|
-
serviceName,
|
|
594
|
-
entryId,
|
|
595
|
-
requiredLevel,
|
|
596
|
-
handleBatchResponse
|
|
597
|
-
);
|
|
570
|
+
subscriptionBatcher.enqueue(serviceName, entryId, requiredLevel, handleBatchResponse);
|
|
598
571
|
}, 200);
|
|
599
572
|
};
|
|
600
573
|
if (refetchOnWindowFocus) {
|
|
@@ -693,6 +666,25 @@ function useRoomEvents(handlers, options) {
|
|
|
693
666
|
};
|
|
694
667
|
}, [socket, isConnected, enabled, stableEventNames]);
|
|
695
668
|
}
|
|
669
|
+
|
|
670
|
+
// src/shared/types.ts
|
|
671
|
+
function channelEventName(serviceName, channelName) {
|
|
672
|
+
return `channel:${serviceName}:${channelName}`;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// src/client/useChannelSend.ts
|
|
676
|
+
function useChannelSend(serviceName, channelName) {
|
|
677
|
+
const { socket, isConnected } = useQuickdrawSocket();
|
|
678
|
+
const eventName = channelEventName(serviceName, channelName);
|
|
679
|
+
const send = React.useCallback(
|
|
680
|
+
(payload) => {
|
|
681
|
+
if (!socket?.connected) return;
|
|
682
|
+
socket.volatile.emit(eventName, payload);
|
|
683
|
+
},
|
|
684
|
+
[socket, eventName]
|
|
685
|
+
);
|
|
686
|
+
return { send, isReady: isConnected && !!socket };
|
|
687
|
+
}
|
|
696
688
|
function useSocketInput(options) {
|
|
697
689
|
const {
|
|
698
690
|
state,
|
|
@@ -1223,6 +1215,6 @@ function routeRequiresAuth(pathname, navigation, userMenuItems) {
|
|
|
1223
1215
|
return false;
|
|
1224
1216
|
}
|
|
1225
1217
|
|
|
1226
|
-
export { QuickdrawProvider, SocketCheckbox, SocketSelect, SocketSlider, SocketSwitch, SocketTextField, buildBreadcrumbs, clearAuthToken, findNavItemByHref, findParentNavItem, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, getAuthToken, getOAuthUrl, logout, logoutAllDevices, parseJWTPayload, routeRequiresAuth, setAuthToken, truncate, useQuickdrawSocket, useRoomEvents, useService, useServiceMethod, useServiceQuery, useSocketInput, useSubscription };
|
|
1218
|
+
export { QuickdrawProvider, SocketCheckbox, SocketSelect, SocketSlider, SocketSwitch, SocketTextField, buildBreadcrumbs, clearAuthToken, findNavItemByHref, findParentNavItem, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, getAuthToken, getOAuthUrl, logout, logoutAllDevices, parseJWTPayload, routeRequiresAuth, setAuthToken, truncate, useChannelSend, useQuickdrawSocket, useRoomEvents, useService, useServiceMethod, useServiceQuery, useSocketInput, useSubscription };
|
|
1227
1219
|
//# sourceMappingURL=index.js.map
|
|
1228
1220
|
//# sourceMappingURL=index.js.map
|