@exyconn/common 1.0.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 +259 -0
- package/dist/client/http/index.d.mts +85 -0
- package/dist/client/http/index.d.ts +85 -0
- package/dist/client/http/index.js +127 -0
- package/dist/client/http/index.js.map +1 -0
- package/dist/client/http/index.mjs +109 -0
- package/dist/client/http/index.mjs.map +1 -0
- package/dist/client/index.d.mts +7 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +964 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +889 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/client/logger/index.d.mts +53 -0
- package/dist/client/logger/index.d.ts +53 -0
- package/dist/client/logger/index.js +120 -0
- package/dist/client/logger/index.js.map +1 -0
- package/dist/client/logger/index.mjs +116 -0
- package/dist/client/logger/index.mjs.map +1 -0
- package/dist/client/utils/index.d.mts +285 -0
- package/dist/client/utils/index.d.ts +285 -0
- package/dist/client/utils/index.js +403 -0
- package/dist/client/utils/index.js.map +1 -0
- package/dist/client/utils/index.mjs +362 -0
- package/dist/client/utils/index.mjs.map +1 -0
- package/dist/index-BNdT-2X4.d.ts +229 -0
- package/dist/index-CcrANHAQ.d.mts +59 -0
- package/dist/index-ClWtDfwk.d.ts +833 -0
- package/dist/index-DSW6JfD-.d.mts +833 -0
- package/dist/index-Du0LLt9f.d.mts +229 -0
- package/dist/index-iTKxFa78.d.ts +59 -0
- package/dist/index.d.mts +171 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +3806 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3792 -0
- package/dist/index.mjs.map +1 -0
- package/dist/response.types-D--UhLJq.d.mts +67 -0
- package/dist/response.types-D--UhLJq.d.ts +67 -0
- package/dist/server/db/index.d.mts +38 -0
- package/dist/server/db/index.d.ts +38 -0
- package/dist/server/db/index.js +68 -0
- package/dist/server/db/index.js.map +1 -0
- package/dist/server/db/index.mjs +60 -0
- package/dist/server/db/index.mjs.map +1 -0
- package/dist/server/enums/index.d.mts +46 -0
- package/dist/server/enums/index.d.ts +46 -0
- package/dist/server/enums/index.js +48 -0
- package/dist/server/enums/index.js.map +1 -0
- package/dist/server/enums/index.mjs +43 -0
- package/dist/server/enums/index.mjs.map +1 -0
- package/dist/server/index.d.mts +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +569 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +523 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/server/logger/index.d.mts +34 -0
- package/dist/server/logger/index.d.ts +34 -0
- package/dist/server/logger/index.js +125 -0
- package/dist/server/logger/index.js.map +1 -0
- package/dist/server/logger/index.mjs +113 -0
- package/dist/server/logger/index.mjs.map +1 -0
- package/dist/server/middleware/index.d.mts +56 -0
- package/dist/server/middleware/index.d.ts +56 -0
- package/dist/server/middleware/index.js +128 -0
- package/dist/server/middleware/index.js.map +1 -0
- package/dist/server/middleware/index.mjs +118 -0
- package/dist/server/middleware/index.mjs.map +1 -0
- package/dist/server/response/index.d.mts +86 -0
- package/dist/server/response/index.d.ts +86 -0
- package/dist/server/response/index.js +140 -0
- package/dist/server/response/index.js.map +1 -0
- package/dist/server/response/index.mjs +126 -0
- package/dist/server/response/index.mjs.map +1 -0
- package/dist/server/utils/index.d.mts +69 -0
- package/dist/server/utils/index.d.ts +69 -0
- package/dist/server/utils/index.js +114 -0
- package/dist/server/utils/index.js.map +1 -0
- package/dist/server/utils/index.mjs +106 -0
- package/dist/server/utils/index.mjs.map +1 -0
- package/dist/shared/index.d.mts +4 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/index.js +933 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/index.mjs +612 -0
- package/dist/shared/index.mjs.map +1 -0
- package/package.json +202 -0
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var axios = require('axios');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
9
|
+
|
|
10
|
+
// src/client/http/axios-instance.ts
|
|
11
|
+
var createHttpClient = (options) => {
|
|
12
|
+
const {
|
|
13
|
+
baseURL,
|
|
14
|
+
timeout = 3e4,
|
|
15
|
+
withCredentials = true,
|
|
16
|
+
getAuthToken,
|
|
17
|
+
onUnauthorized,
|
|
18
|
+
onServerError
|
|
19
|
+
} = options;
|
|
20
|
+
const instance = axios__default.default.create({
|
|
21
|
+
baseURL,
|
|
22
|
+
timeout,
|
|
23
|
+
withCredentials,
|
|
24
|
+
headers: {
|
|
25
|
+
"Content-Type": "application/json"
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
instance.interceptors.request.use(
|
|
29
|
+
(config) => {
|
|
30
|
+
if (getAuthToken) {
|
|
31
|
+
const token = getAuthToken();
|
|
32
|
+
if (token && config.headers) {
|
|
33
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return config;
|
|
37
|
+
},
|
|
38
|
+
(error) => Promise.reject(error)
|
|
39
|
+
);
|
|
40
|
+
instance.interceptors.response.use(
|
|
41
|
+
(response) => response,
|
|
42
|
+
(error) => {
|
|
43
|
+
if (error.response) {
|
|
44
|
+
const status = error.response.status;
|
|
45
|
+
if (status === 401 && onUnauthorized) {
|
|
46
|
+
onUnauthorized();
|
|
47
|
+
}
|
|
48
|
+
if (status >= 500 && onServerError) {
|
|
49
|
+
onServerError(error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Promise.reject(error);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
return instance;
|
|
56
|
+
};
|
|
57
|
+
var withFormData = () => ({
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "multipart/form-data"
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
var withTimeout = (ms) => ({
|
|
63
|
+
timeout: ms
|
|
64
|
+
});
|
|
65
|
+
var withAbortSignal = (signal) => ({
|
|
66
|
+
signal
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// src/client/http/response-parser.ts
|
|
70
|
+
var parseResponse = (response) => {
|
|
71
|
+
if (response.data?.success && response.data?.data !== void 0) {
|
|
72
|
+
return response.data.data;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
};
|
|
76
|
+
var parseFullResponse = (response) => {
|
|
77
|
+
return response.data;
|
|
78
|
+
};
|
|
79
|
+
var parseError = (error) => {
|
|
80
|
+
if (error.response?.data?.message) {
|
|
81
|
+
return error.response.data.message;
|
|
82
|
+
}
|
|
83
|
+
if (error.response?.data?.error) {
|
|
84
|
+
return error.response.data.error;
|
|
85
|
+
}
|
|
86
|
+
if (error.code === "ERR_NETWORK") {
|
|
87
|
+
return "Network error. Please check your connection.";
|
|
88
|
+
}
|
|
89
|
+
if (error.code === "ECONNABORTED") {
|
|
90
|
+
return "Request timed out. Please try again.";
|
|
91
|
+
}
|
|
92
|
+
return error.message || "An unexpected error occurred.";
|
|
93
|
+
};
|
|
94
|
+
var isSuccess = (response) => {
|
|
95
|
+
return response.data?.success === true;
|
|
96
|
+
};
|
|
97
|
+
var isStatusError = (error, statusCode) => {
|
|
98
|
+
return error.response?.status === statusCode;
|
|
99
|
+
};
|
|
100
|
+
var isUnauthorized = (error) => {
|
|
101
|
+
return isStatusError(error, 401);
|
|
102
|
+
};
|
|
103
|
+
var isForbidden = (error) => {
|
|
104
|
+
return isStatusError(error, 403);
|
|
105
|
+
};
|
|
106
|
+
var isNotFound = (error) => {
|
|
107
|
+
return isStatusError(error, 404);
|
|
108
|
+
};
|
|
109
|
+
var isServerError = (error) => {
|
|
110
|
+
const status = error.response?.status;
|
|
111
|
+
return status !== void 0 && status >= 500;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// src/client/logger/client-logger.ts
|
|
115
|
+
var LOG_LEVELS = {
|
|
116
|
+
debug: 0,
|
|
117
|
+
info: 1,
|
|
118
|
+
warn: 2,
|
|
119
|
+
error: 3
|
|
120
|
+
};
|
|
121
|
+
var ClientLogger = class {
|
|
122
|
+
constructor(config = {}) {
|
|
123
|
+
this.buffer = [];
|
|
124
|
+
this.config = {
|
|
125
|
+
enabled: config.enabled ?? process.env.NODE_ENV !== "production",
|
|
126
|
+
minLevel: config.minLevel ?? "debug",
|
|
127
|
+
prefix: config.prefix ?? "[App]",
|
|
128
|
+
includeTimestamp: config.includeTimestamp ?? true,
|
|
129
|
+
remoteLogging: config.remoteLogging
|
|
130
|
+
};
|
|
131
|
+
if (this.config.remoteLogging?.enabled) {
|
|
132
|
+
const interval = this.config.remoteLogging.flushInterval ?? 3e4;
|
|
133
|
+
this.flushTimer = setInterval(() => this.flush(), interval);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
shouldLog(level) {
|
|
137
|
+
if (!this.config.enabled) return false;
|
|
138
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.config.minLevel];
|
|
139
|
+
}
|
|
140
|
+
formatMessage(level, message) {
|
|
141
|
+
const parts = [];
|
|
142
|
+
if (this.config.includeTimestamp) {
|
|
143
|
+
parts.push(`[${(/* @__PURE__ */ new Date()).toISOString()}]`);
|
|
144
|
+
}
|
|
145
|
+
parts.push(this.config.prefix);
|
|
146
|
+
parts.push(`[${level.toUpperCase()}]`);
|
|
147
|
+
parts.push(message);
|
|
148
|
+
return parts.join(" ");
|
|
149
|
+
}
|
|
150
|
+
log(level, message, data) {
|
|
151
|
+
if (!this.shouldLog(level)) return;
|
|
152
|
+
const formattedMessage = this.formatMessage(level, message);
|
|
153
|
+
const entry = {
|
|
154
|
+
level,
|
|
155
|
+
message,
|
|
156
|
+
data,
|
|
157
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
158
|
+
prefix: this.config.prefix
|
|
159
|
+
};
|
|
160
|
+
switch (level) {
|
|
161
|
+
case "debug":
|
|
162
|
+
console.debug(formattedMessage, data ?? "");
|
|
163
|
+
break;
|
|
164
|
+
case "info":
|
|
165
|
+
console.info(formattedMessage, data ?? "");
|
|
166
|
+
break;
|
|
167
|
+
case "warn":
|
|
168
|
+
console.warn(formattedMessage, data ?? "");
|
|
169
|
+
break;
|
|
170
|
+
case "error":
|
|
171
|
+
console.error(formattedMessage, data ?? "");
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
if (this.config.remoteLogging?.enabled) {
|
|
175
|
+
this.buffer.push(entry);
|
|
176
|
+
const batchSize = this.config.remoteLogging.batchSize ?? 10;
|
|
177
|
+
if (this.buffer.length >= batchSize) {
|
|
178
|
+
this.flush();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
debug(message, data) {
|
|
183
|
+
this.log("debug", message, data);
|
|
184
|
+
}
|
|
185
|
+
info(message, data) {
|
|
186
|
+
this.log("info", message, data);
|
|
187
|
+
}
|
|
188
|
+
warn(message, data) {
|
|
189
|
+
this.log("warn", message, data);
|
|
190
|
+
}
|
|
191
|
+
error(message, data) {
|
|
192
|
+
this.log("error", message, data);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Flush buffered logs to remote endpoint
|
|
196
|
+
*/
|
|
197
|
+
async flush() {
|
|
198
|
+
if (!this.config.remoteLogging?.enabled || this.buffer.length === 0) return;
|
|
199
|
+
const logs = [...this.buffer];
|
|
200
|
+
this.buffer = [];
|
|
201
|
+
try {
|
|
202
|
+
await fetch(this.config.remoteLogging.endpoint, {
|
|
203
|
+
method: "POST",
|
|
204
|
+
headers: { "Content-Type": "application/json" },
|
|
205
|
+
body: JSON.stringify({ logs })
|
|
206
|
+
});
|
|
207
|
+
} catch (error) {
|
|
208
|
+
this.buffer = [...logs, ...this.buffer].slice(0, 100);
|
|
209
|
+
console.error("Failed to send logs to remote endpoint", error);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Cleanup logger (clear intervals)
|
|
214
|
+
*/
|
|
215
|
+
destroy() {
|
|
216
|
+
if (this.flushTimer) {
|
|
217
|
+
clearInterval(this.flushTimer);
|
|
218
|
+
}
|
|
219
|
+
this.flush();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
var createClientLogger = (config) => {
|
|
223
|
+
return new ClientLogger(config);
|
|
224
|
+
};
|
|
225
|
+
var clientLogger = new ClientLogger();
|
|
226
|
+
|
|
227
|
+
// src/client/utils/date.ts
|
|
228
|
+
var formatDate = (date, locale = "en-US") => {
|
|
229
|
+
const dateObj = new Date(date);
|
|
230
|
+
return dateObj.toLocaleDateString(locale, {
|
|
231
|
+
year: "numeric",
|
|
232
|
+
month: "long",
|
|
233
|
+
day: "numeric"
|
|
234
|
+
});
|
|
235
|
+
};
|
|
236
|
+
var formatDateTime = (date, locale = "en-US") => {
|
|
237
|
+
const dateObj = new Date(date);
|
|
238
|
+
return dateObj.toLocaleDateString(locale, {
|
|
239
|
+
year: "numeric",
|
|
240
|
+
month: "short",
|
|
241
|
+
day: "numeric",
|
|
242
|
+
hour: "2-digit",
|
|
243
|
+
minute: "2-digit"
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
var formatRelativeTime = (date) => {
|
|
247
|
+
const dateObj = new Date(date);
|
|
248
|
+
const now = /* @__PURE__ */ new Date();
|
|
249
|
+
const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1e3);
|
|
250
|
+
const intervals = [
|
|
251
|
+
{ label: "year", seconds: 31536e3 },
|
|
252
|
+
{ label: "month", seconds: 2592e3 },
|
|
253
|
+
{ label: "week", seconds: 604800 },
|
|
254
|
+
{ label: "day", seconds: 86400 },
|
|
255
|
+
{ label: "hour", seconds: 3600 },
|
|
256
|
+
{ label: "minute", seconds: 60 },
|
|
257
|
+
{ label: "second", seconds: 1 }
|
|
258
|
+
];
|
|
259
|
+
for (const interval of intervals) {
|
|
260
|
+
const count = Math.floor(diffInSeconds / interval.seconds);
|
|
261
|
+
if (count >= 1) {
|
|
262
|
+
return `${count} ${interval.label}${count !== 1 ? "s" : ""} ago`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return "just now";
|
|
266
|
+
};
|
|
267
|
+
var formatDateForInput = (date) => {
|
|
268
|
+
const dateObj = new Date(date);
|
|
269
|
+
return dateObj.toISOString().split("T")[0];
|
|
270
|
+
};
|
|
271
|
+
var formatDateTimeForInput = (date) => {
|
|
272
|
+
const dateObj = new Date(date);
|
|
273
|
+
return dateObj.toISOString().slice(0, 16);
|
|
274
|
+
};
|
|
275
|
+
var isToday = (date) => {
|
|
276
|
+
const dateObj = new Date(date);
|
|
277
|
+
const today = /* @__PURE__ */ new Date();
|
|
278
|
+
return dateObj.getDate() === today.getDate() && dateObj.getMonth() === today.getMonth() && dateObj.getFullYear() === today.getFullYear();
|
|
279
|
+
};
|
|
280
|
+
var isPast = (date) => {
|
|
281
|
+
return new Date(date).getTime() < Date.now();
|
|
282
|
+
};
|
|
283
|
+
var isFuture = (date) => {
|
|
284
|
+
return new Date(date).getTime() > Date.now();
|
|
285
|
+
};
|
|
286
|
+
var addDays = (date, days) => {
|
|
287
|
+
const dateObj = new Date(date);
|
|
288
|
+
dateObj.setDate(dateObj.getDate() + days);
|
|
289
|
+
return dateObj;
|
|
290
|
+
};
|
|
291
|
+
var startOfDay = (date) => {
|
|
292
|
+
const dateObj = new Date(date);
|
|
293
|
+
dateObj.setHours(0, 0, 0, 0);
|
|
294
|
+
return dateObj;
|
|
295
|
+
};
|
|
296
|
+
var endOfDay = (date) => {
|
|
297
|
+
const dateObj = new Date(date);
|
|
298
|
+
dateObj.setHours(23, 59, 59, 999);
|
|
299
|
+
return dateObj;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// src/client/utils/clipboard.ts
|
|
303
|
+
var copyToClipboard = async (text) => {
|
|
304
|
+
try {
|
|
305
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
306
|
+
await navigator.clipboard.writeText(text);
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
const textArea = document.createElement("textarea");
|
|
310
|
+
textArea.value = text;
|
|
311
|
+
textArea.style.position = "fixed";
|
|
312
|
+
textArea.style.left = "-999999px";
|
|
313
|
+
textArea.style.top = "-999999px";
|
|
314
|
+
document.body.appendChild(textArea);
|
|
315
|
+
textArea.focus();
|
|
316
|
+
textArea.select();
|
|
317
|
+
const success = document.execCommand("copy");
|
|
318
|
+
document.body.removeChild(textArea);
|
|
319
|
+
return success;
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error("Failed to copy to clipboard:", error);
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
var readFromClipboard = async () => {
|
|
326
|
+
try {
|
|
327
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
328
|
+
return await navigator.clipboard.readText();
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error("Failed to read from clipboard:", error);
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
var isClipboardAvailable = () => {
|
|
337
|
+
return !!(navigator.clipboard && window.isSecureContext);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// src/client/utils/slug.ts
|
|
341
|
+
var slugify = (text) => {
|
|
342
|
+
return text.toString().toLowerCase().trim().replace(/\s+/g, "-").replace(/[^\w\-]+/g, "").replace(/\-\-+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
343
|
+
};
|
|
344
|
+
var slugifyUnique = (text) => {
|
|
345
|
+
const baseSlug = slugify(text);
|
|
346
|
+
const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 5);
|
|
347
|
+
return `${baseSlug}-${uniqueSuffix}`;
|
|
348
|
+
};
|
|
349
|
+
var unslugify = (slug) => {
|
|
350
|
+
return slug.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
351
|
+
};
|
|
352
|
+
var truncate = (text, maxLength, suffix = "...") => {
|
|
353
|
+
if (text.length <= maxLength) return text;
|
|
354
|
+
return text.substring(0, maxLength - suffix.length).trim() + suffix;
|
|
355
|
+
};
|
|
356
|
+
var truncateWords = (text, maxWords, suffix = "...") => {
|
|
357
|
+
const words = text.split(/\s+/);
|
|
358
|
+
if (words.length <= maxWords) return text;
|
|
359
|
+
return words.slice(0, maxWords).join(" ") + suffix;
|
|
360
|
+
};
|
|
361
|
+
var capitalizeWords = (text) => {
|
|
362
|
+
return text.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
363
|
+
};
|
|
364
|
+
var capitalize = (text) => {
|
|
365
|
+
if (!text) return "";
|
|
366
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
367
|
+
};
|
|
368
|
+
var camelToKebab = (text) => {
|
|
369
|
+
return text.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
370
|
+
};
|
|
371
|
+
var kebabToCamel = (text) => {
|
|
372
|
+
return text.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// src/client/utils/events.ts
|
|
376
|
+
var EventEmitter = class {
|
|
377
|
+
constructor() {
|
|
378
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Subscribe to an event
|
|
382
|
+
* @returns Unsubscribe function
|
|
383
|
+
*/
|
|
384
|
+
on(event, handler) {
|
|
385
|
+
if (!this.handlers.has(event)) {
|
|
386
|
+
this.handlers.set(event, /* @__PURE__ */ new Set());
|
|
387
|
+
}
|
|
388
|
+
this.handlers.get(event).add(handler);
|
|
389
|
+
return () => this.off(event, handler);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Subscribe to an event once
|
|
393
|
+
*/
|
|
394
|
+
once(event, handler) {
|
|
395
|
+
const wrappedHandler = (data) => {
|
|
396
|
+
this.off(event, wrappedHandler);
|
|
397
|
+
handler(data);
|
|
398
|
+
};
|
|
399
|
+
return this.on(event, wrappedHandler);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Unsubscribe from an event
|
|
403
|
+
*/
|
|
404
|
+
off(event, handler) {
|
|
405
|
+
const eventHandlers = this.handlers.get(event);
|
|
406
|
+
if (eventHandlers) {
|
|
407
|
+
eventHandlers.delete(handler);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Emit an event
|
|
412
|
+
*/
|
|
413
|
+
emit(event, data) {
|
|
414
|
+
const eventHandlers = this.handlers.get(event);
|
|
415
|
+
if (eventHandlers) {
|
|
416
|
+
eventHandlers.forEach((handler) => {
|
|
417
|
+
try {
|
|
418
|
+
handler(data);
|
|
419
|
+
} catch (error) {
|
|
420
|
+
console.error(`Error in event handler for "${String(event)}":`, error);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Remove all handlers for an event (or all events)
|
|
427
|
+
*/
|
|
428
|
+
removeAllListeners(event) {
|
|
429
|
+
if (event) {
|
|
430
|
+
this.handlers.delete(event);
|
|
431
|
+
} else {
|
|
432
|
+
this.handlers.clear();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get count of listeners for an event
|
|
437
|
+
*/
|
|
438
|
+
listenerCount(event) {
|
|
439
|
+
return this.handlers.get(event)?.size ?? 0;
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
var createEventEmitter = () => {
|
|
443
|
+
return new EventEmitter();
|
|
444
|
+
};
|
|
445
|
+
var appEvents = new EventEmitter();
|
|
446
|
+
|
|
447
|
+
// src/client/utils/api-urls.ts
|
|
448
|
+
var ApiUrlBuilder = class {
|
|
449
|
+
constructor(config) {
|
|
450
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
451
|
+
this.version = config.version || "";
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Build full URL from path
|
|
455
|
+
*/
|
|
456
|
+
build(path) {
|
|
457
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
458
|
+
const versionPath = this.version ? `/${this.version}` : "";
|
|
459
|
+
return `${this.baseUrl}${versionPath}${normalizedPath}`;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Build URL with query parameters
|
|
463
|
+
*/
|
|
464
|
+
buildWithParams(path, params) {
|
|
465
|
+
const url = this.build(path);
|
|
466
|
+
const filteredParams = Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
|
|
467
|
+
return filteredParams ? `${url}?${filteredParams}` : url;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Build URL with path parameters
|
|
471
|
+
*/
|
|
472
|
+
buildWithPathParams(template, params) {
|
|
473
|
+
let path = template;
|
|
474
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
475
|
+
path = path.replace(`:${key}`, String(value));
|
|
476
|
+
path = path.replace(`{${key}}`, String(value));
|
|
477
|
+
});
|
|
478
|
+
return this.build(path);
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get base URL
|
|
482
|
+
*/
|
|
483
|
+
getBaseUrl() {
|
|
484
|
+
return this.baseUrl;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Set new base URL
|
|
488
|
+
*/
|
|
489
|
+
setBaseUrl(baseUrl) {
|
|
490
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
var createApiUrlBuilder = (config) => {
|
|
494
|
+
return new ApiUrlBuilder(config);
|
|
495
|
+
};
|
|
496
|
+
var createApiEndpoints = (builder) => ({
|
|
497
|
+
// Auth endpoints
|
|
498
|
+
auth: {
|
|
499
|
+
login: () => builder.build("/auth/login"),
|
|
500
|
+
register: () => builder.build("/auth/register"),
|
|
501
|
+
logout: () => builder.build("/auth/logout"),
|
|
502
|
+
refresh: () => builder.build("/auth/refresh"),
|
|
503
|
+
me: () => builder.build("/auth/me"),
|
|
504
|
+
forgotPassword: () => builder.build("/auth/forgot-password"),
|
|
505
|
+
resetPassword: () => builder.build("/auth/reset-password")
|
|
506
|
+
},
|
|
507
|
+
// User endpoints
|
|
508
|
+
users: {
|
|
509
|
+
list: () => builder.build("/users"),
|
|
510
|
+
get: (id) => builder.buildWithPathParams("/users/:id", { id }),
|
|
511
|
+
create: () => builder.build("/users"),
|
|
512
|
+
update: (id) => builder.buildWithPathParams("/users/:id", { id }),
|
|
513
|
+
delete: (id) => builder.buildWithPathParams("/users/:id", { id })
|
|
514
|
+
},
|
|
515
|
+
// Generic CRUD factory
|
|
516
|
+
crud: (resource) => ({
|
|
517
|
+
list: () => builder.build(`/${resource}`),
|
|
518
|
+
get: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
|
|
519
|
+
create: () => builder.build(`/${resource}`),
|
|
520
|
+
update: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
|
|
521
|
+
delete: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id })
|
|
522
|
+
})
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// src/client/utils/response-parser.ts
|
|
526
|
+
var isSuccessResponse = (response) => {
|
|
527
|
+
return response.success === true;
|
|
528
|
+
};
|
|
529
|
+
var isErrorResponse = (response) => {
|
|
530
|
+
return response.success === false;
|
|
531
|
+
};
|
|
532
|
+
var getResponseData = (response, defaultValue) => {
|
|
533
|
+
if (isSuccessResponse(response) && response.data !== void 0) {
|
|
534
|
+
return response.data;
|
|
535
|
+
}
|
|
536
|
+
return defaultValue;
|
|
537
|
+
};
|
|
538
|
+
var getErrorMessage = (response, defaultMessage = "An error occurred") => {
|
|
539
|
+
if (response.error) {
|
|
540
|
+
return response.error;
|
|
541
|
+
}
|
|
542
|
+
if (response.message) {
|
|
543
|
+
return response.message;
|
|
544
|
+
}
|
|
545
|
+
return defaultMessage;
|
|
546
|
+
};
|
|
547
|
+
var hasData = (response) => {
|
|
548
|
+
return response.data !== null && response.data !== void 0;
|
|
549
|
+
};
|
|
550
|
+
var hasMorePages = (response) => {
|
|
551
|
+
return response.pagination.hasNextPage;
|
|
552
|
+
};
|
|
553
|
+
var getNextPage = (response) => {
|
|
554
|
+
if (response.pagination.hasNextPage) {
|
|
555
|
+
return response.pagination.page + 1;
|
|
556
|
+
}
|
|
557
|
+
return null;
|
|
558
|
+
};
|
|
559
|
+
var getPrevPage = (response) => {
|
|
560
|
+
if (response.pagination.hasPrevPage) {
|
|
561
|
+
return response.pagination.page - 1;
|
|
562
|
+
}
|
|
563
|
+
return null;
|
|
564
|
+
};
|
|
565
|
+
var createEmptyPaginationMeta = () => ({
|
|
566
|
+
total: 0,
|
|
567
|
+
page: 1,
|
|
568
|
+
limit: 10,
|
|
569
|
+
totalPages: 0,
|
|
570
|
+
hasNextPage: false,
|
|
571
|
+
hasPrevPage: false
|
|
572
|
+
});
|
|
573
|
+
var createSuccessResponse = (data, message = "Success") => ({
|
|
574
|
+
success: true,
|
|
575
|
+
message,
|
|
576
|
+
data,
|
|
577
|
+
statusCode: 200
|
|
578
|
+
});
|
|
579
|
+
var createErrorResponse = (message, statusCode = 400, error) => ({
|
|
580
|
+
success: false,
|
|
581
|
+
message,
|
|
582
|
+
error,
|
|
583
|
+
statusCode
|
|
584
|
+
});
|
|
585
|
+
function useLocalStorage(key, initialValue, options = {}) {
|
|
586
|
+
const {
|
|
587
|
+
serializer = JSON.stringify,
|
|
588
|
+
deserializer = JSON.parse,
|
|
589
|
+
syncTabs = true,
|
|
590
|
+
debug = false
|
|
591
|
+
} = options;
|
|
592
|
+
const log = react.useCallback(
|
|
593
|
+
(...args) => {
|
|
594
|
+
if (debug) console.log(`[useLocalStorage:${key}]`, ...args);
|
|
595
|
+
},
|
|
596
|
+
[debug, key]
|
|
597
|
+
);
|
|
598
|
+
const readValue = react.useCallback(() => {
|
|
599
|
+
if (typeof window === "undefined") {
|
|
600
|
+
return initialValue;
|
|
601
|
+
}
|
|
602
|
+
try {
|
|
603
|
+
const item = window.localStorage.getItem(key);
|
|
604
|
+
if (item === null) {
|
|
605
|
+
return initialValue;
|
|
606
|
+
}
|
|
607
|
+
const parsed = deserializer(item);
|
|
608
|
+
log("Read value:", parsed);
|
|
609
|
+
return parsed;
|
|
610
|
+
} catch (error) {
|
|
611
|
+
console.warn(`Error reading localStorage key "${key}":`, error);
|
|
612
|
+
return initialValue;
|
|
613
|
+
}
|
|
614
|
+
}, [key, initialValue, deserializer, log]);
|
|
615
|
+
const [storedValue, setStoredValue] = react.useState(readValue);
|
|
616
|
+
const setValue = react.useCallback(
|
|
617
|
+
(value) => {
|
|
618
|
+
if (typeof window === "undefined") {
|
|
619
|
+
console.warn(`Cannot set localStorage key "${key}" in non-browser environment`);
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
try {
|
|
623
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
624
|
+
setStoredValue(valueToStore);
|
|
625
|
+
window.localStorage.setItem(key, serializer(valueToStore));
|
|
626
|
+
log("Set value:", valueToStore);
|
|
627
|
+
window.dispatchEvent(new StorageEvent("storage", { key, newValue: serializer(valueToStore) }));
|
|
628
|
+
} catch (error) {
|
|
629
|
+
console.warn(`Error setting localStorage key "${key}":`, error);
|
|
630
|
+
}
|
|
631
|
+
},
|
|
632
|
+
[key, storedValue, serializer, log]
|
|
633
|
+
);
|
|
634
|
+
const removeValue = react.useCallback(() => {
|
|
635
|
+
if (typeof window === "undefined") {
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
try {
|
|
639
|
+
window.localStorage.removeItem(key);
|
|
640
|
+
setStoredValue(initialValue);
|
|
641
|
+
log("Removed value");
|
|
642
|
+
window.dispatchEvent(new StorageEvent("storage", { key, newValue: null }));
|
|
643
|
+
} catch (error) {
|
|
644
|
+
console.warn(`Error removing localStorage key "${key}":`, error);
|
|
645
|
+
}
|
|
646
|
+
}, [key, initialValue, log]);
|
|
647
|
+
react.useEffect(() => {
|
|
648
|
+
if (!syncTabs || typeof window === "undefined") {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const handleStorageChange = (event) => {
|
|
652
|
+
if (event.key !== key) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
log("Storage event received:", event.newValue);
|
|
656
|
+
if (event.newValue === null) {
|
|
657
|
+
setStoredValue(initialValue);
|
|
658
|
+
} else {
|
|
659
|
+
try {
|
|
660
|
+
setStoredValue(deserializer(event.newValue));
|
|
661
|
+
} catch {
|
|
662
|
+
console.warn(`Error parsing localStorage change for key "${key}"`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
window.addEventListener("storage", handleStorageChange);
|
|
667
|
+
return () => window.removeEventListener("storage", handleStorageChange);
|
|
668
|
+
}, [key, initialValue, syncTabs, deserializer, log]);
|
|
669
|
+
return [storedValue, setValue, removeValue];
|
|
670
|
+
}
|
|
671
|
+
var useLocalStorage_default = useLocalStorage;
|
|
672
|
+
function useDebounce(value, delay = 500) {
|
|
673
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
674
|
+
react.useEffect(() => {
|
|
675
|
+
const timer = setTimeout(() => {
|
|
676
|
+
setDebouncedValue(value);
|
|
677
|
+
}, delay);
|
|
678
|
+
return () => {
|
|
679
|
+
clearTimeout(timer);
|
|
680
|
+
};
|
|
681
|
+
}, [value, delay]);
|
|
682
|
+
return debouncedValue;
|
|
683
|
+
}
|
|
684
|
+
var useDebounce_default = useDebounce;
|
|
685
|
+
function useCopyToClipboard(resetDelay = 2e3) {
|
|
686
|
+
const [copied, setCopied] = react.useState(false);
|
|
687
|
+
const [error, setError] = react.useState(null);
|
|
688
|
+
const reset = react.useCallback(() => {
|
|
689
|
+
setCopied(false);
|
|
690
|
+
setError(null);
|
|
691
|
+
}, []);
|
|
692
|
+
const copy = react.useCallback(
|
|
693
|
+
async (text) => {
|
|
694
|
+
if (!navigator?.clipboard) {
|
|
695
|
+
try {
|
|
696
|
+
const textarea = document.createElement("textarea");
|
|
697
|
+
textarea.value = text;
|
|
698
|
+
textarea.style.position = "fixed";
|
|
699
|
+
textarea.style.left = "-999999px";
|
|
700
|
+
textarea.style.top = "-999999px";
|
|
701
|
+
document.body.appendChild(textarea);
|
|
702
|
+
textarea.focus();
|
|
703
|
+
textarea.select();
|
|
704
|
+
const successful = document.execCommand("copy");
|
|
705
|
+
document.body.removeChild(textarea);
|
|
706
|
+
if (successful) {
|
|
707
|
+
setCopied(true);
|
|
708
|
+
setError(null);
|
|
709
|
+
setTimeout(reset, resetDelay);
|
|
710
|
+
return true;
|
|
711
|
+
} else {
|
|
712
|
+
throw new Error("execCommand failed");
|
|
713
|
+
}
|
|
714
|
+
} catch (err) {
|
|
715
|
+
const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
|
|
716
|
+
setError(message);
|
|
717
|
+
setCopied(false);
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
try {
|
|
722
|
+
await navigator.clipboard.writeText(text);
|
|
723
|
+
setCopied(true);
|
|
724
|
+
setError(null);
|
|
725
|
+
setTimeout(reset, resetDelay);
|
|
726
|
+
return true;
|
|
727
|
+
} catch (err) {
|
|
728
|
+
const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
|
|
729
|
+
setError(message);
|
|
730
|
+
setCopied(false);
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
[resetDelay, reset]
|
|
735
|
+
);
|
|
736
|
+
return { copy, copied, error, reset };
|
|
737
|
+
}
|
|
738
|
+
var useCopyToClipboard_default = useCopyToClipboard;
|
|
739
|
+
function usePageTitle(title, options = {}) {
|
|
740
|
+
const { suffix, separator = " | ", restoreOnUnmount = true } = options;
|
|
741
|
+
react.useEffect(() => {
|
|
742
|
+
const originalTitle = document.title;
|
|
743
|
+
const newTitle = suffix ? `${title}${separator}${suffix}` : title;
|
|
744
|
+
document.title = newTitle;
|
|
745
|
+
return () => {
|
|
746
|
+
if (restoreOnUnmount) {
|
|
747
|
+
document.title = originalTitle;
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
}, [title, suffix, separator, restoreOnUnmount]);
|
|
751
|
+
}
|
|
752
|
+
var usePageTitle_default = usePageTitle;
|
|
753
|
+
function useInterval(callback, delay) {
|
|
754
|
+
const savedCallback = react.useRef(callback);
|
|
755
|
+
react.useEffect(() => {
|
|
756
|
+
savedCallback.current = callback;
|
|
757
|
+
}, [callback]);
|
|
758
|
+
react.useEffect(() => {
|
|
759
|
+
if (delay === null) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
const tick = () => savedCallback.current();
|
|
763
|
+
const id = setInterval(tick, delay);
|
|
764
|
+
return () => clearInterval(id);
|
|
765
|
+
}, [delay]);
|
|
766
|
+
}
|
|
767
|
+
var useInterval_default = useInterval;
|
|
768
|
+
function useThemeDetector() {
|
|
769
|
+
const getCurrentTheme = () => {
|
|
770
|
+
if (typeof window === "undefined") return "light";
|
|
771
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
772
|
+
};
|
|
773
|
+
const [theme, setTheme] = react.useState(getCurrentTheme);
|
|
774
|
+
react.useEffect(() => {
|
|
775
|
+
if (typeof window === "undefined") return;
|
|
776
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
777
|
+
const handleChange = (e) => {
|
|
778
|
+
setTheme(e.matches ? "dark" : "light");
|
|
779
|
+
};
|
|
780
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
781
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
782
|
+
}, []);
|
|
783
|
+
return theme;
|
|
784
|
+
}
|
|
785
|
+
var useThemeDetector_default = useThemeDetector;
|
|
786
|
+
var DEFAULT_DURATION = 4e3;
|
|
787
|
+
function useSnackbar(defaultDuration = DEFAULT_DURATION) {
|
|
788
|
+
const [state, setState] = react.useState({
|
|
789
|
+
open: false,
|
|
790
|
+
message: "",
|
|
791
|
+
severity: "info",
|
|
792
|
+
autoHideDuration: defaultDuration
|
|
793
|
+
});
|
|
794
|
+
const show = react.useCallback(
|
|
795
|
+
(message, severity = "info", duration) => {
|
|
796
|
+
setState({
|
|
797
|
+
open: true,
|
|
798
|
+
message,
|
|
799
|
+
severity,
|
|
800
|
+
autoHideDuration: duration ?? defaultDuration
|
|
801
|
+
});
|
|
802
|
+
},
|
|
803
|
+
[defaultDuration]
|
|
804
|
+
);
|
|
805
|
+
const success = react.useCallback(
|
|
806
|
+
(message, duration) => show(message, "success", duration),
|
|
807
|
+
[show]
|
|
808
|
+
);
|
|
809
|
+
const error = react.useCallback(
|
|
810
|
+
(message, duration) => show(message, "error", duration),
|
|
811
|
+
[show]
|
|
812
|
+
);
|
|
813
|
+
const warning = react.useCallback(
|
|
814
|
+
(message, duration) => show(message, "warning", duration),
|
|
815
|
+
[show]
|
|
816
|
+
);
|
|
817
|
+
const info = react.useCallback(
|
|
818
|
+
(message, duration) => show(message, "info", duration),
|
|
819
|
+
[show]
|
|
820
|
+
);
|
|
821
|
+
const close = react.useCallback(() => {
|
|
822
|
+
setState((prev) => ({ ...prev, open: false }));
|
|
823
|
+
}, []);
|
|
824
|
+
return { state, show, success, error, warning, info, close };
|
|
825
|
+
}
|
|
826
|
+
var useSnackbar_default = useSnackbar;
|
|
827
|
+
function useMediaQuery(query) {
|
|
828
|
+
const getMatches = (query2) => {
|
|
829
|
+
if (typeof window === "undefined") return false;
|
|
830
|
+
return window.matchMedia(query2).matches;
|
|
831
|
+
};
|
|
832
|
+
const [matches, setMatches] = react.useState(getMatches(query));
|
|
833
|
+
react.useEffect(() => {
|
|
834
|
+
if (typeof window === "undefined") return;
|
|
835
|
+
const mediaQuery = window.matchMedia(query);
|
|
836
|
+
const handleChange = () => setMatches(mediaQuery.matches);
|
|
837
|
+
handleChange();
|
|
838
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
839
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
840
|
+
}, [query]);
|
|
841
|
+
return matches;
|
|
842
|
+
}
|
|
843
|
+
var useIsMobile = () => useMediaQuery("(max-width: 767px)");
|
|
844
|
+
var useIsTablet = () => useMediaQuery("(min-width: 768px) and (max-width: 1023px)");
|
|
845
|
+
var useIsDesktop = () => useMediaQuery("(min-width: 1024px)");
|
|
846
|
+
var useIsMobileOrTablet = () => useMediaQuery("(max-width: 1023px)");
|
|
847
|
+
var useMediaQuery_default = useMediaQuery;
|
|
848
|
+
function useOnClickOutside(ref, handler, enabled = true) {
|
|
849
|
+
react.useEffect(() => {
|
|
850
|
+
if (!enabled) return;
|
|
851
|
+
const listener = (event) => {
|
|
852
|
+
const el = ref?.current;
|
|
853
|
+
if (!el || el.contains(event.target)) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
handler(event);
|
|
857
|
+
};
|
|
858
|
+
document.addEventListener("mousedown", listener);
|
|
859
|
+
document.addEventListener("touchstart", listener);
|
|
860
|
+
return () => {
|
|
861
|
+
document.removeEventListener("mousedown", listener);
|
|
862
|
+
document.removeEventListener("touchstart", listener);
|
|
863
|
+
};
|
|
864
|
+
}, [ref, handler, enabled]);
|
|
865
|
+
}
|
|
866
|
+
var useOnClickOutside_default = useOnClickOutside;
|
|
867
|
+
function useWindowSize(debounceMs = 100) {
|
|
868
|
+
const getSize = () => ({
|
|
869
|
+
width: typeof window !== "undefined" ? window.innerWidth : 0,
|
|
870
|
+
height: typeof window !== "undefined" ? window.innerHeight : 0
|
|
871
|
+
});
|
|
872
|
+
const [windowSize, setWindowSize] = react.useState(getSize);
|
|
873
|
+
react.useEffect(() => {
|
|
874
|
+
if (typeof window === "undefined") return;
|
|
875
|
+
let timeoutId;
|
|
876
|
+
const handleResize = () => {
|
|
877
|
+
clearTimeout(timeoutId);
|
|
878
|
+
timeoutId = setTimeout(() => {
|
|
879
|
+
setWindowSize(getSize());
|
|
880
|
+
}, debounceMs);
|
|
881
|
+
};
|
|
882
|
+
setWindowSize(getSize());
|
|
883
|
+
window.addEventListener("resize", handleResize);
|
|
884
|
+
return () => {
|
|
885
|
+
clearTimeout(timeoutId);
|
|
886
|
+
window.removeEventListener("resize", handleResize);
|
|
887
|
+
};
|
|
888
|
+
}, [debounceMs]);
|
|
889
|
+
return windowSize;
|
|
890
|
+
}
|
|
891
|
+
var useWindowSize_default = useWindowSize;
|
|
892
|
+
|
|
893
|
+
exports.ApiUrlBuilder = ApiUrlBuilder;
|
|
894
|
+
exports.ClientLogger = ClientLogger;
|
|
895
|
+
exports.EventEmitter = EventEmitter;
|
|
896
|
+
exports.addDays = addDays;
|
|
897
|
+
exports.appEvents = appEvents;
|
|
898
|
+
exports.camelToKebab = camelToKebab;
|
|
899
|
+
exports.capitalize = capitalize;
|
|
900
|
+
exports.capitalizeWords = capitalizeWords;
|
|
901
|
+
exports.clientLogger = clientLogger;
|
|
902
|
+
exports.copyToClipboard = copyToClipboard;
|
|
903
|
+
exports.createApiEndpoints = createApiEndpoints;
|
|
904
|
+
exports.createApiUrlBuilder = createApiUrlBuilder;
|
|
905
|
+
exports.createClientLogger = createClientLogger;
|
|
906
|
+
exports.createEmptyPaginationMeta = createEmptyPaginationMeta;
|
|
907
|
+
exports.createErrorResponse = createErrorResponse;
|
|
908
|
+
exports.createEventEmitter = createEventEmitter;
|
|
909
|
+
exports.createHttpClient = createHttpClient;
|
|
910
|
+
exports.createSuccessResponse = createSuccessResponse;
|
|
911
|
+
exports.endOfDay = endOfDay;
|
|
912
|
+
exports.formatDate = formatDate;
|
|
913
|
+
exports.formatDateForInput = formatDateForInput;
|
|
914
|
+
exports.formatDateTime = formatDateTime;
|
|
915
|
+
exports.formatDateTimeForInput = formatDateTimeForInput;
|
|
916
|
+
exports.formatRelativeTime = formatRelativeTime;
|
|
917
|
+
exports.getErrorMessage = getErrorMessage;
|
|
918
|
+
exports.getNextPage = getNextPage;
|
|
919
|
+
exports.getPrevPage = getPrevPage;
|
|
920
|
+
exports.getResponseData = getResponseData;
|
|
921
|
+
exports.hasData = hasData;
|
|
922
|
+
exports.hasMorePages = hasMorePages;
|
|
923
|
+
exports.isClipboardAvailable = isClipboardAvailable;
|
|
924
|
+
exports.isErrorResponse = isErrorResponse;
|
|
925
|
+
exports.isForbidden = isForbidden;
|
|
926
|
+
exports.isFuture = isFuture;
|
|
927
|
+
exports.isNotFound = isNotFound;
|
|
928
|
+
exports.isPast = isPast;
|
|
929
|
+
exports.isServerError = isServerError;
|
|
930
|
+
exports.isStatusError = isStatusError;
|
|
931
|
+
exports.isSuccess = isSuccess;
|
|
932
|
+
exports.isSuccessResponse = isSuccessResponse;
|
|
933
|
+
exports.isToday = isToday;
|
|
934
|
+
exports.isUnauthorized = isUnauthorized;
|
|
935
|
+
exports.kebabToCamel = kebabToCamel;
|
|
936
|
+
exports.parseError = parseError;
|
|
937
|
+
exports.parseFullResponse = parseFullResponse;
|
|
938
|
+
exports.parseResponse = parseResponse;
|
|
939
|
+
exports.readFromClipboard = readFromClipboard;
|
|
940
|
+
exports.slugify = slugify;
|
|
941
|
+
exports.slugifyUnique = slugifyUnique;
|
|
942
|
+
exports.startOfDay = startOfDay;
|
|
943
|
+
exports.truncate = truncate;
|
|
944
|
+
exports.truncateWords = truncateWords;
|
|
945
|
+
exports.unslugify = unslugify;
|
|
946
|
+
exports.useCopyToClipboard = useCopyToClipboard_default;
|
|
947
|
+
exports.useDebounce = useDebounce_default;
|
|
948
|
+
exports.useInterval = useInterval_default;
|
|
949
|
+
exports.useIsDesktop = useIsDesktop;
|
|
950
|
+
exports.useIsMobile = useIsMobile;
|
|
951
|
+
exports.useIsMobileOrTablet = useIsMobileOrTablet;
|
|
952
|
+
exports.useIsTablet = useIsTablet;
|
|
953
|
+
exports.useLocalStorage = useLocalStorage_default;
|
|
954
|
+
exports.useMediaQuery = useMediaQuery_default;
|
|
955
|
+
exports.useOnClickOutside = useOnClickOutside_default;
|
|
956
|
+
exports.usePageTitle = usePageTitle_default;
|
|
957
|
+
exports.useSnackbar = useSnackbar_default;
|
|
958
|
+
exports.useThemeDetector = useThemeDetector_default;
|
|
959
|
+
exports.useWindowSize = useWindowSize_default;
|
|
960
|
+
exports.withAbortSignal = withAbortSignal;
|
|
961
|
+
exports.withFormData = withFormData;
|
|
962
|
+
exports.withTimeout = withTimeout;
|
|
963
|
+
//# sourceMappingURL=index.js.map
|
|
964
|
+
//# sourceMappingURL=index.js.map
|