@sayrio/public 1.0.0 → 1.0.2
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 +166 -51
- package/dist/index.cjs +142 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -27
- package/dist/index.d.ts +44 -27
- package/dist/index.js +142 -64
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +264 -79
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +30 -4
- package/dist/react/index.d.ts +30 -4
- package/dist/react/index.js +270 -85
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -34,7 +34,6 @@ var import_react = require("react");
|
|
|
34
34
|
// src/client/index.ts
|
|
35
35
|
var DEFAULT_API = "https://api.sayr.io";
|
|
36
36
|
var config = {
|
|
37
|
-
fetch: globalThis.fetch,
|
|
38
37
|
baseUrl: DEFAULT_API
|
|
39
38
|
};
|
|
40
39
|
var hooks = {};
|
|
@@ -47,9 +46,6 @@ function setHeaders(headers) {
|
|
|
47
46
|
...headers
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
|
-
function setFetch(fn) {
|
|
51
|
-
config.fetch = fn;
|
|
52
|
-
}
|
|
53
49
|
function setBaseUrl(url) {
|
|
54
50
|
config.baseUrl = url.replace(/\/$/, "");
|
|
55
51
|
}
|
|
@@ -140,11 +136,23 @@ var org_default = {
|
|
|
140
136
|
* @since v1.0.0
|
|
141
137
|
*/
|
|
142
138
|
async get(slug, opts) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
try {
|
|
140
|
+
const r = await request(
|
|
141
|
+
`/v1/organization/${slug}`,
|
|
142
|
+
opts
|
|
143
|
+
);
|
|
144
|
+
return {
|
|
145
|
+
success: true,
|
|
146
|
+
data: r.data,
|
|
147
|
+
error: null
|
|
148
|
+
};
|
|
149
|
+
} catch (err) {
|
|
150
|
+
return {
|
|
151
|
+
success: false,
|
|
152
|
+
data: null,
|
|
153
|
+
error: err?.message ?? "Failed to fetch organization"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
148
156
|
}
|
|
149
157
|
};
|
|
150
158
|
|
|
@@ -165,15 +173,27 @@ var tasks_default = {
|
|
|
165
173
|
* @since v1.0.0
|
|
166
174
|
*/
|
|
167
175
|
async list(slug, params, opts) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
try {
|
|
177
|
+
const q = buildPaginationParams(params);
|
|
178
|
+
const r = await request(
|
|
179
|
+
`/v1/organization/${slug}/tasks?${q}`,
|
|
180
|
+
opts
|
|
181
|
+
);
|
|
182
|
+
return {
|
|
183
|
+
success: true,
|
|
184
|
+
data: {
|
|
185
|
+
items: r.data,
|
|
186
|
+
pagination: r.pagination
|
|
187
|
+
},
|
|
188
|
+
error: null
|
|
189
|
+
};
|
|
190
|
+
} catch (err) {
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
data: null,
|
|
194
|
+
error: err?.message ?? "Failed to fetch tasks"
|
|
195
|
+
};
|
|
196
|
+
}
|
|
177
197
|
},
|
|
178
198
|
/**
|
|
179
199
|
* Fetches a single public task by short ID.
|
|
@@ -181,11 +201,23 @@ var tasks_default = {
|
|
|
181
201
|
* @since v1.0.0
|
|
182
202
|
*/
|
|
183
203
|
async get(slug, shortId, opts) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
204
|
+
try {
|
|
205
|
+
const r = await request(
|
|
206
|
+
`/v1/organization/${slug}/tasks/${shortId}`,
|
|
207
|
+
opts
|
|
208
|
+
);
|
|
209
|
+
return {
|
|
210
|
+
success: true,
|
|
211
|
+
data: r.data,
|
|
212
|
+
error: null
|
|
213
|
+
};
|
|
214
|
+
} catch (err) {
|
|
215
|
+
return {
|
|
216
|
+
success: false,
|
|
217
|
+
data: null,
|
|
218
|
+
error: err?.message ?? "Failed to fetch task"
|
|
219
|
+
};
|
|
220
|
+
}
|
|
189
221
|
}
|
|
190
222
|
};
|
|
191
223
|
|
|
@@ -197,15 +229,27 @@ var comments_default = {
|
|
|
197
229
|
* @since v1.0.0
|
|
198
230
|
*/
|
|
199
231
|
async list(slug, shortId, params, opts) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
232
|
+
try {
|
|
233
|
+
const q = buildPaginationParams(params);
|
|
234
|
+
const r = await request(
|
|
235
|
+
`/v1/organization/${slug}/tasks/${shortId}/comments?${q}`,
|
|
236
|
+
opts
|
|
237
|
+
);
|
|
238
|
+
return {
|
|
239
|
+
success: true,
|
|
240
|
+
data: {
|
|
241
|
+
items: r.data,
|
|
242
|
+
pagination: r.pagination
|
|
243
|
+
},
|
|
244
|
+
error: null
|
|
245
|
+
};
|
|
246
|
+
} catch (err) {
|
|
247
|
+
return {
|
|
248
|
+
success: false,
|
|
249
|
+
data: null,
|
|
250
|
+
error: err?.message ?? "Failed to fetch task comments"
|
|
251
|
+
};
|
|
252
|
+
}
|
|
209
253
|
}
|
|
210
254
|
};
|
|
211
255
|
|
|
@@ -217,11 +261,23 @@ var labels_default = {
|
|
|
217
261
|
* @since v1.0.0
|
|
218
262
|
*/
|
|
219
263
|
async list(slug, opts) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
264
|
+
try {
|
|
265
|
+
const r = await request(
|
|
266
|
+
`/v1/organization/${slug}/labels`,
|
|
267
|
+
opts
|
|
268
|
+
);
|
|
269
|
+
return {
|
|
270
|
+
success: true,
|
|
271
|
+
data: r.data,
|
|
272
|
+
error: null
|
|
273
|
+
};
|
|
274
|
+
} catch (err) {
|
|
275
|
+
return {
|
|
276
|
+
success: false,
|
|
277
|
+
data: null,
|
|
278
|
+
error: err?.message ?? "Failed to fetch labels"
|
|
279
|
+
};
|
|
280
|
+
}
|
|
225
281
|
}
|
|
226
282
|
};
|
|
227
283
|
|
|
@@ -233,11 +289,23 @@ var categories_default = {
|
|
|
233
289
|
* @since v1.0.0
|
|
234
290
|
*/
|
|
235
291
|
async list(slug, order = "desc", opts) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
292
|
+
try {
|
|
293
|
+
const r = await request(
|
|
294
|
+
`/v1/organization/${slug}/categories?order=${order}`,
|
|
295
|
+
opts
|
|
296
|
+
);
|
|
297
|
+
return {
|
|
298
|
+
success: true,
|
|
299
|
+
data: r.data,
|
|
300
|
+
error: null
|
|
301
|
+
};
|
|
302
|
+
} catch (err) {
|
|
303
|
+
return {
|
|
304
|
+
success: false,
|
|
305
|
+
data: null,
|
|
306
|
+
error: err?.message ?? "Failed to fetch categories"
|
|
307
|
+
};
|
|
308
|
+
}
|
|
241
309
|
}
|
|
242
310
|
};
|
|
243
311
|
|
|
@@ -253,29 +321,40 @@ var org_default2 = OrgAPI;
|
|
|
253
321
|
|
|
254
322
|
// src/api/v1/me/index.ts
|
|
255
323
|
var me_default = {
|
|
256
|
-
/**
|
|
257
|
-
* Fetches the currently authenticated user.
|
|
258
|
-
*
|
|
259
|
-
* @since v1.0.0
|
|
260
|
-
*/
|
|
261
324
|
async get(opts) {
|
|
262
|
-
|
|
263
|
-
"/me",
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
325
|
+
try {
|
|
326
|
+
const r = await request("/v1/me", opts);
|
|
327
|
+
return {
|
|
328
|
+
success: true,
|
|
329
|
+
data: r.data,
|
|
330
|
+
error: null
|
|
331
|
+
};
|
|
332
|
+
} catch (err) {
|
|
333
|
+
return {
|
|
334
|
+
success: false,
|
|
335
|
+
data: null,
|
|
336
|
+
error: err?.message ?? "Failed to fetch user"
|
|
337
|
+
};
|
|
338
|
+
}
|
|
267
339
|
},
|
|
268
|
-
/**
|
|
269
|
-
* Lists organizations the current user belongs to.
|
|
270
|
-
*
|
|
271
|
-
* @since v1.0.0
|
|
272
|
-
*/
|
|
273
340
|
async organizations(opts) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
341
|
+
try {
|
|
342
|
+
const r = await request(
|
|
343
|
+
"/v1/me/organizations",
|
|
344
|
+
opts
|
|
345
|
+
);
|
|
346
|
+
return {
|
|
347
|
+
success: true,
|
|
348
|
+
data: r.data,
|
|
349
|
+
error: null
|
|
350
|
+
};
|
|
351
|
+
} catch (err) {
|
|
352
|
+
return {
|
|
353
|
+
success: false,
|
|
354
|
+
data: null,
|
|
355
|
+
error: err?.message ?? "Failed to fetch organizations"
|
|
356
|
+
};
|
|
357
|
+
}
|
|
279
358
|
}
|
|
280
359
|
};
|
|
281
360
|
|
|
@@ -347,8 +426,7 @@ var SayrClient = {
|
|
|
347
426
|
setHeaders,
|
|
348
427
|
setBaseUrl,
|
|
349
428
|
resetClient,
|
|
350
|
-
setHooks
|
|
351
|
-
setFetch
|
|
429
|
+
setHooks
|
|
352
430
|
};
|
|
353
431
|
var Sayr = {
|
|
354
432
|
// client configuration
|
|
@@ -368,12 +446,32 @@ function useOrg(slug) {
|
|
|
368
446
|
const [data, setData] = (0, import_react.useState)(null);
|
|
369
447
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
370
448
|
const [error, setError] = (0, import_react.useState)(null);
|
|
449
|
+
const mountedRef = (0, import_react.useRef)(true);
|
|
450
|
+
(0, import_react.useEffect)(() => {
|
|
451
|
+
return () => {
|
|
452
|
+
mountedRef.current = false;
|
|
453
|
+
};
|
|
454
|
+
}, []);
|
|
371
455
|
(0, import_react.useEffect)(() => {
|
|
372
456
|
if (!slug) return;
|
|
373
457
|
setLoading(true);
|
|
374
|
-
|
|
458
|
+
setError(null);
|
|
459
|
+
index_default.org.get(slug).then((res) => {
|
|
460
|
+
if (!mountedRef.current) return;
|
|
461
|
+
if (!res.success) {
|
|
462
|
+
setError(res.error);
|
|
463
|
+
setData(null);
|
|
464
|
+
} else {
|
|
465
|
+
setData(res.data);
|
|
466
|
+
}
|
|
467
|
+
setLoading(false);
|
|
468
|
+
});
|
|
375
469
|
}, [slug]);
|
|
376
|
-
return {
|
|
470
|
+
return {
|
|
471
|
+
data,
|
|
472
|
+
loading,
|
|
473
|
+
error
|
|
474
|
+
};
|
|
377
475
|
}
|
|
378
476
|
|
|
379
477
|
// src/react/useTasks.ts
|
|
@@ -383,9 +481,26 @@ var import_react3 = require("react");
|
|
|
383
481
|
var import_react2 = require("react");
|
|
384
482
|
function useSayrWS(wsUrl, handlers) {
|
|
385
483
|
const connRef = (0, import_react2.useRef)(null);
|
|
484
|
+
const handlersRef = (0, import_react2.useRef)(handlers);
|
|
485
|
+
(0, import_react2.useEffect)(() => {
|
|
486
|
+
handlersRef.current = handlers;
|
|
487
|
+
}, [handlers]);
|
|
386
488
|
(0, import_react2.useEffect)(() => {
|
|
387
489
|
if (!wsUrl) return;
|
|
388
|
-
|
|
490
|
+
const proxyHandlers = new Proxy(
|
|
491
|
+
{},
|
|
492
|
+
{
|
|
493
|
+
get: (_, type) => {
|
|
494
|
+
return (data, msg) => {
|
|
495
|
+
const handler = handlersRef.current?.[type];
|
|
496
|
+
if (handler) {
|
|
497
|
+
handler(data, msg);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
connRef.current = ws(wsUrl, proxyHandlers);
|
|
389
504
|
return () => {
|
|
390
505
|
connRef.current?.close();
|
|
391
506
|
connRef.current = null;
|
|
@@ -398,17 +513,40 @@ function useSayrWS(wsUrl, handlers) {
|
|
|
398
513
|
function useTasks(slug, wsUrl) {
|
|
399
514
|
const [tasks, setTasks] = (0, import_react3.useState)([]);
|
|
400
515
|
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
401
|
-
|
|
516
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
517
|
+
const mountedRef = (0, import_react3.useRef)(true);
|
|
518
|
+
(0, import_react3.useEffect)(() => {
|
|
519
|
+
return () => {
|
|
520
|
+
mountedRef.current = false;
|
|
521
|
+
};
|
|
522
|
+
}, []);
|
|
523
|
+
const fetchTasks = (0, import_react3.useCallback)(async () => {
|
|
402
524
|
if (!slug) return;
|
|
403
525
|
setLoading(true);
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
526
|
+
setError(null);
|
|
527
|
+
const res = await index_default.org.tasks.list(slug);
|
|
528
|
+
if (!mountedRef.current) return;
|
|
529
|
+
if (!res.success) {
|
|
530
|
+
setError(res.error);
|
|
531
|
+
setTasks([]);
|
|
532
|
+
} else {
|
|
533
|
+
setTasks(res.data?.items ?? []);
|
|
534
|
+
}
|
|
535
|
+
setLoading(false);
|
|
536
|
+
}, [slug]);
|
|
537
|
+
(0, import_react3.useEffect)(() => {
|
|
538
|
+
fetchTasks();
|
|
539
|
+
}, [fetchTasks]);
|
|
407
540
|
useSayrWS(wsUrl, {
|
|
408
541
|
[index_default.WS_EVENTS.CREATE_TASK]: fetchTasks,
|
|
409
542
|
[index_default.WS_EVENTS.UPDATE_TASK]: fetchTasks
|
|
410
543
|
});
|
|
411
|
-
return {
|
|
544
|
+
return {
|
|
545
|
+
tasks,
|
|
546
|
+
loading,
|
|
547
|
+
error,
|
|
548
|
+
refetch: fetchTasks
|
|
549
|
+
};
|
|
412
550
|
}
|
|
413
551
|
|
|
414
552
|
// src/react/useTask.ts
|
|
@@ -416,12 +554,33 @@ var import_react4 = require("react");
|
|
|
416
554
|
function useTask(slug, shortId) {
|
|
417
555
|
const [task, setTask] = (0, import_react4.useState)(null);
|
|
418
556
|
const [loading, setLoading] = (0, import_react4.useState)(false);
|
|
557
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
558
|
+
const mountedRef = (0, import_react4.useRef)(true);
|
|
559
|
+
(0, import_react4.useEffect)(() => {
|
|
560
|
+
return () => {
|
|
561
|
+
mountedRef.current = false;
|
|
562
|
+
};
|
|
563
|
+
}, []);
|
|
419
564
|
(0, import_react4.useEffect)(() => {
|
|
420
565
|
if (!slug || shortId == null) return;
|
|
421
566
|
setLoading(true);
|
|
422
|
-
|
|
567
|
+
setError(null);
|
|
568
|
+
index_default.org.tasks.get(slug, shortId).then((res) => {
|
|
569
|
+
if (!mountedRef.current) return;
|
|
570
|
+
if (!res.success) {
|
|
571
|
+
setError(res.error);
|
|
572
|
+
setTask(null);
|
|
573
|
+
} else {
|
|
574
|
+
setTask(res.data);
|
|
575
|
+
}
|
|
576
|
+
setLoading(false);
|
|
577
|
+
});
|
|
423
578
|
}, [slug, shortId]);
|
|
424
|
-
return {
|
|
579
|
+
return {
|
|
580
|
+
task,
|
|
581
|
+
loading,
|
|
582
|
+
error
|
|
583
|
+
};
|
|
425
584
|
}
|
|
426
585
|
|
|
427
586
|
// src/react/useComments.ts
|
|
@@ -429,16 +588,42 @@ var import_react5 = require("react");
|
|
|
429
588
|
function useComments(slug, shortId, wsUrl) {
|
|
430
589
|
const [comments, setComments] = (0, import_react5.useState)([]);
|
|
431
590
|
const [loading, setLoading] = (0, import_react5.useState)(false);
|
|
432
|
-
|
|
591
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
592
|
+
const mountedRef = (0, import_react5.useRef)(true);
|
|
593
|
+
(0, import_react5.useEffect)(() => {
|
|
594
|
+
return () => {
|
|
595
|
+
mountedRef.current = false;
|
|
596
|
+
};
|
|
597
|
+
}, []);
|
|
598
|
+
const fetchComments = (0, import_react5.useCallback)(async () => {
|
|
433
599
|
if (!slug || shortId == null) return;
|
|
434
600
|
setLoading(true);
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
601
|
+
setError(null);
|
|
602
|
+
const res = await index_default.org.comments.list(
|
|
603
|
+
slug,
|
|
604
|
+
shortId
|
|
605
|
+
);
|
|
606
|
+
if (!mountedRef.current) return;
|
|
607
|
+
if (!res.success) {
|
|
608
|
+
setError(res.error);
|
|
609
|
+
setComments([]);
|
|
610
|
+
} else {
|
|
611
|
+
setComments(res.data?.items ?? []);
|
|
612
|
+
}
|
|
613
|
+
setLoading(false);
|
|
614
|
+
}, [slug, shortId]);
|
|
615
|
+
(0, import_react5.useEffect)(() => {
|
|
616
|
+
fetchComments();
|
|
617
|
+
}, [fetchComments]);
|
|
438
618
|
useSayrWS(wsUrl, {
|
|
439
619
|
[index_default.WS_EVENTS.UPDATE_TASK_COMMENTS]: fetchComments
|
|
440
620
|
});
|
|
441
|
-
return {
|
|
621
|
+
return {
|
|
622
|
+
comments,
|
|
623
|
+
loading,
|
|
624
|
+
error,
|
|
625
|
+
refetch: fetchComments
|
|
626
|
+
};
|
|
442
627
|
}
|
|
443
628
|
// Annotate the CommonJS export names for ESM import in node:
|
|
444
629
|
0 && (module.exports = {
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.ts","../../src/react/useOrg.ts","../../src/client/index.ts","../../src/api/v1/org/org.ts","../../src/shared/index.ts","../../src/api/v1/org/tasks.ts","../../src/api/v1/org/comments.ts","../../src/api/v1/org/labels.ts","../../src/api/v1/org/categories.ts","../../src/api/v1/org/index.ts","../../src/api/v1/me/index.ts","../../src/api/v1/index.ts","../../src/ws/types.ts","../../src/ws/index.ts","../../src/index.ts","../../src/react/useTasks.ts","../../src/react/useSayrWS.ts","../../src/react/useTask.ts","../../src/react/useComments.ts"],"sourcesContent":["export { useOrg } from \"./useOrg\";\r\nexport { useTasks } from \"./useTasks\";\r\nexport { useTask } from \"./useTask\";\r\nexport { useComments } from \"./useComments\";\r\nexport { useSayrWS } from \"./useSayrWS\";","import { useEffect, useState } from \"react\";\r\nimport Sayr, { Organization } from \"../index\";\r\n\r\nexport function useOrg(slug?: string) {\r\n const [data, setData] = useState<Organization | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<unknown>(null);\r\n\r\n useEffect(() => {\r\n if (!slug) return;\r\n\r\n setLoading(true);\r\n Sayr.org\r\n .get(slug)\r\n .then(setData)\r\n .catch(setError)\r\n .finally(() => setLoading(false));\r\n }, [slug]);\r\n\r\n return { data, loading, error };\r\n}","import { ApiError } from \"../types\";\r\n\r\n/* ────────────────────────────\r\n Types\r\n──────────────────────────── */\r\nexport type RequestOptions = {\r\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\r\n headers?: Record<string, string>;\r\n body?: Record<string, string>;\r\n signal?: AbortSignal;\r\n};\r\n\r\ntype Hooks = {\r\n onRequest?: (url: string, opts: RequestOptions) => void;\r\n onResponse?: (res: Response) => void;\r\n onError?: (error: ApiError | unknown) => void;\r\n};\r\n\r\ntype ClientConfig = {\r\n token?: string;\r\n headers?: Record<string, string>;\r\n fetch: typeof fetch;\r\n baseUrl: string;\r\n};\r\n\r\n/* ────────────────────────────\r\n Internal state\r\n──────────────────────────── */\r\nconst DEFAULT_API = \"https://api.sayr.io\";\r\n\r\nconst config: ClientConfig = {\r\n fetch: globalThis.fetch,\r\n baseUrl: DEFAULT_API\r\n};\r\n\r\nconst hooks: Hooks = {};\r\n\r\n/* ────────────────────────────\r\n Public config API\r\n──────────────────────────── */\r\nexport function setToken(token?: string) {\r\n config.token = token;\r\n}\r\n\r\nexport function getToken() {\r\n return config.token;\r\n}\r\n\r\nexport function setHeaders(headers?: Record<string, string>) {\r\n config.headers = {\r\n ...config.headers,\r\n ...headers\r\n };\r\n}\r\n\r\nexport function setFetch(fn: typeof fetch) {\r\n config.fetch = fn;\r\n}\r\n\r\nexport function setBaseUrl(url: string) {\r\n config.baseUrl = url.replace(/\\/$/, \"\");\r\n}\r\n\r\nexport function setHooks(h: Hooks) {\r\n Object.assign(hooks, h);\r\n}\r\nexport function resetClient() {\r\n config.token = undefined;\r\n config.headers = undefined;\r\n config.baseUrl = DEFAULT_API;\r\n}\r\n\r\n/* ────────────────────────────\r\n Request helper\r\n──────────────────────────── */\r\nexport async function request<T>(\r\n path: string,\r\n opts: RequestOptions = {}\r\n): Promise<T> {\r\n\r\n let url: string;\r\n try {\r\n url = path.startsWith(\"http\")\r\n ? path\r\n : `${config.baseUrl}${path}`;\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n try {\r\n hooks.onRequest?.(url, opts);\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n let res: Response;\r\n\r\n try {\r\n const method = opts.method ?? \"GET\";\r\n\r\n\r\n // 🔴 Guard: GET must not have body\r\n if (method === \"GET\" && opts.body !== undefined) {\r\n throw new Error(\"GET request cannot have a body\");\r\n }\r\n\r\n res = await fetch(url, {\r\n method,\r\n headers: {\r\n ...(config.token\r\n ? { Authorization: `Bearer ${config.token}` }\r\n : {}),\r\n ...(opts.body && method !== \"GET\"\r\n ? { \"Content-Type\": \"application/json\" }\r\n : {}),\r\n ...config.headers,\r\n ...opts.headers\r\n },\r\n body:\r\n opts.body && method !== \"GET\"\r\n ? JSON.stringify(opts.body)\r\n : undefined,\r\n signal: opts.signal\r\n });\r\n } catch (err) {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"NETWORK_ERROR\",\r\n message: \"Failed to reach Sayr API\",\r\n // 👇 keep raw error so we can see it\r\n // @ts-ignore\r\n raw: err\r\n };\r\n\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n try {\r\n hooks.onResponse?.(res);\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n let json: any;\r\n try {\r\n json = await res.json();\r\n } catch (err) {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"INVALID_RESPONSE\",\r\n message: \"Server returned invalid JSON\",\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n if (!res.ok || !json.success) {\r\n const error: ApiError = {\r\n ...json,\r\n success: false,\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n return json;\r\n}","import { Organization, ApiSuccess } from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization core operations.\r\n */\r\nexport default {\r\n /**\r\n * Fetches a public organization by slug.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n opts?: RequestOptions\r\n ): Promise<Organization> {\r\n const r = await request<ApiSuccess<Organization>>(\r\n `/v1/organization/${slug}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","/* =======================\r\n * Shared params & helpers\r\n * ======================= */\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport interface PaginationParams {\r\n page?: number;\r\n limit?: number;\r\n}\r\n\r\nexport interface OrderedPaginationParams extends PaginationParams {\r\n order?: Order;\r\n}\r\n\r\nexport function buildPaginationParams(\r\n params?: OrderedPaginationParams\r\n): URLSearchParams {\r\n return new URLSearchParams({\r\n order: params?.order ?? \"desc\",\r\n limit: String(params?.limit ?? 5),\r\n page: String(params?.page ?? 1)\r\n });\r\n}","import {\r\n Task,\r\n Pagination,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization tasks.\r\n */\r\nexport default {\r\n /**\r\n * Lists public tasks for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions\r\n ): Promise<{ data: Task[]; pagination: Pagination }> {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Task[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks?${q}`,\r\n opts\r\n );\r\n\r\n return {\r\n data: r.data,\r\n pagination: r.pagination\r\n };\r\n },\r\n\r\n /**\r\n * Fetches a single public task by short ID.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n shortId: number,\r\n opts?: RequestOptions\r\n ): Promise<Task> {\r\n const r = await request<ApiSuccess<Task>>(\r\n `/v1/organization/${slug}/tasks/${shortId}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import {\r\n Comment,\r\n Pagination,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization task comments.\r\n */\r\nexport default {\r\n /**\r\n * Lists public comments for a task.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n shortId: number,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions\r\n ): Promise<{ data: Comment[]; pagination: Pagination }> {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Comment[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks/${shortId}/comments?${q}`,\r\n opts\r\n );\r\n\r\n return {\r\n data: r.data,\r\n pagination: r.pagination\r\n };\r\n }\r\n};","import { Label, ApiSuccess } from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization labels.\r\n */\r\nexport default {\r\n /**\r\n * Lists public labels for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n opts?: RequestOptions\r\n ): Promise<Label[]> {\r\n const r = await request<ApiSuccess<Label[]>>(\r\n `/v1/organization/${slug}/labels`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import {\r\n Category,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport { type Order } from \"../../../shared\";\r\n\r\n/**\r\n * Organization categories.\r\n */\r\nexport default {\r\n /**\r\n * Lists public categories for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n order: Order = \"desc\",\r\n opts?: RequestOptions\r\n ): Promise<Category[]> {\r\n const r = await request<ApiSuccess<Category[]>>(\r\n `/v1/organization/${slug}/categories?order=${order}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import org from \"./org\";\r\nimport tasks from \"./tasks\";\r\nimport comments from \"./comments\";\r\nimport labels from \"./labels\";\r\nimport categories from \"./categories\";\r\n\r\n/**\r\n * Public Sayr Organization API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst OrgAPI = {\r\n ...org,\r\n tasks,\r\n comments,\r\n labels,\r\n categories\r\n};\r\n\r\nexport default OrgAPI;","import { request, type RequestOptions } from \"../../../client\";\r\nimport { ApiSuccess, Organization } from \"../../../types\";\r\n\r\nexport interface Me {\r\n id: string;\r\n name: string | null;\r\n email: string | null;\r\n image: string | null;\r\n createdAt: string;\r\n}\r\n\r\n/**\r\n * Authenticated user API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport default {\r\n /**\r\n * Fetches the currently authenticated user.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(opts?: RequestOptions): Promise<Me> {\r\n const r = await request<ApiSuccess<Me>>(\r\n \"/me\",\r\n opts\r\n );\r\n return r.data;\r\n },\r\n\r\n /**\r\n * Lists organizations the current user belongs to.\r\n *\r\n * @since v1.0.0\r\n */\r\n async organizations(\r\n opts?: RequestOptions\r\n ): Promise<Organization[]> {\r\n const r = await request<ApiSuccess<Organization[]>>(\r\n \"/organizations\",\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import org from \"./org\";\r\nimport me from \"./me\";\r\nexport const v1 = {\r\n org,\r\n me\r\n};\r\n\r\nexport default v1;","export type WSMessageType =\r\n | \"CONNECTION_STATUS\"\r\n | \"SUBSCRIBED\"\r\n | \"ERROR\"\r\n | \"PING\"\r\n | \"PONG\"\r\n | \"UPDATE_ORG\"\r\n | \"CREATE_TASK\"\r\n | \"UPDATE_TASK\"\r\n | \"UPDATE_TASK_COMMENTS\"\r\n | \"UPDATE_TASK_VOTE\"\r\n | \"UPDATE_LABELS\"\r\n | \"UPDATE_VIEWS\"\r\n | \"UPDATE_CATEGORIES\"\r\n | \"UPDATE_ISSUE_TEMPLATES\"\r\n | \"DISCONNECTED\";\r\n\r\n/**\r\n * String enum replacement for WS event names.\r\n * Use this instead of raw strings.\r\n */\r\nexport const WS_EVENTS: Record<WSMessageType, WSMessageType> = {\r\n CONNECTION_STATUS: \"CONNECTION_STATUS\",\r\n SUBSCRIBED: \"SUBSCRIBED\",\r\n ERROR: \"ERROR\",\r\n PING: \"PING\",\r\n PONG: \"PONG\",\r\n UPDATE_ORG: \"UPDATE_ORG\",\r\n CREATE_TASK: \"CREATE_TASK\",\r\n UPDATE_TASK: \"UPDATE_TASK\",\r\n UPDATE_TASK_COMMENTS: \"UPDATE_TASK_COMMENTS\",\r\n UPDATE_TASK_VOTE: \"UPDATE_TASK_VOTE\",\r\n UPDATE_LABELS: \"UPDATE_LABELS\",\r\n UPDATE_VIEWS: \"UPDATE_VIEWS\",\r\n UPDATE_CATEGORIES: \"UPDATE_CATEGORIES\",\r\n UPDATE_ISSUE_TEMPLATES: \"UPDATE_ISSUE_TEMPLATES\",\r\n DISCONNECTED: \"DISCONNECTED\"\r\n};\r\n\r\nexport interface WSMessage<T = unknown> {\r\n type: WSMessageType;\r\n scope: \"PUBLIC\";\r\n data: T;\r\n meta?: { ts: number };\r\n}","import { WS_EVENTS, type WSMessage, type WSMessageType } from \"./types\";\r\n\r\ntype Handlers = Partial<\r\n Record<WSMessageType, (data: any, msg: WSMessage) => void>\r\n>;\r\n\r\nexport function ws(url: string, handlers: Handlers = {}) {\r\n if (!url) {\r\n throw new Error(\r\n \"[Sayr.ws] WebSocket URL is required. \" +\r\n \"Did you forget to pass org.wsUrl?\"\r\n );\r\n }\r\n let socket: WebSocket;\r\n let retry = 0;\r\n let closed = false;\r\n\r\n function connect() {\r\n if (closed) return;\r\n\r\n socket = new WebSocket(url);\r\n\r\n socket.onmessage = (e) => {\r\n const msg = JSON.parse(e.data) as WSMessage;\r\n\r\n if (msg.type === WS_EVENTS.PING) {\r\n socket.send(JSON.stringify({ type: WS_EVENTS.PONG }));\r\n return;\r\n }\r\n\r\n handlers[msg.type]?.(msg.data, msg);\r\n };\r\n\r\n socket.onclose = () => {\r\n if (closed) return;\r\n setTimeout(connect, Math.min(1000 * 2 ** retry++, 30000));\r\n };\r\n\r\n socket.onerror = () => socket.close();\r\n }\r\n\r\n connect();\r\n\r\n return {\r\n close() {\r\n closed = true;\r\n socket?.close();\r\n }\r\n };\r\n}","/* ────────────────────────────\r\n API versions\r\n──────────────────────────── */\r\nimport v1 from \"./api/v1\";\r\n\r\n/* ────────────────────────────\r\n Realtime\r\n──────────────────────────── */\r\nimport { ws } from \"./ws\";\r\nimport { WS_EVENTS } from \"./ws/types\";\r\n\r\n/* ────────────────────────────\r\n Client config\r\n──────────────────────────── */\r\nimport {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n setFetch\r\n} from \"./client\";\r\n\r\n/* ────────────────────────────\r\n Named exports (power users)\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport const SayrV1 = v1;\r\n\r\n\r\n/**\r\n * Create a WebSocket connection for public real‑time updates.\r\n */\r\nexport const SayrWS = ws;\r\n\r\n/**\r\n * Typed WebSocket event constants.\r\n */\r\nexport const SayrWSEvents = WS_EVENTS;\r\n\r\n/**\r\n * Global client configuration helpers.\r\n */\r\nexport const SayrClient = {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n setFetch\r\n};\r\n\r\n/* ────────────────────────────\r\n Default facade\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public SDK.\r\n *\r\n * Read‑only access to public Sayr data via REST and WebSockets.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst Sayr: {\r\n /**\r\n * Client configuration helpers.\r\n */\r\n client: typeof SayrClient;\r\n\r\n /**\r\n * Versioned API namespaces.\r\n */\r\n v1: typeof v1;\r\n\r\n /**\r\n * Alias for the current API version (`v1`).\r\n *\r\n * @since v1.0.0\r\n */\r\n org: typeof v1.org;\r\n me: typeof v1.me;\r\n\r\n /**\r\n * WebSocket helper for real‑time updates.\r\n */\r\n ws: typeof ws;\r\n\r\n /**\r\n * WebSocket event constants.\r\n */\r\n WS_EVENTS: typeof WS_EVENTS;\r\n} = {\r\n // client configuration\r\n client: SayrClient,\r\n\r\n // APIs\r\n v1,\r\n org: v1.org,\r\n me: v1.me,\r\n\r\n // realtime\r\n ws,\r\n WS_EVENTS\r\n};\r\n\r\nexport default Sayr;\r\n\r\n/* ────────────────────────────\r\n Types & shared helpers\r\n──────────────────────────── */\r\nexport * from \"./types\";\r\nexport * from \"./shared\";\r\nexport * from \"./ws/types\";","import { useEffect, useState } from \"react\";\r\nimport type { Task } from \"../types\";\r\nimport { useSayrWS } from \"./useSayrWS\";\r\nimport Sayr from \"..\";\r\nexport function useTasks(\r\n slug?: string,\r\n wsUrl?: string\r\n) {\r\n const [tasks, setTasks] = useState<Task[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n\r\n function fetchTasks() {\r\n if (!slug) return;\r\n setLoading(true);\r\n Sayr.org.tasks.list(slug)\r\n .then((r) => setTasks(r.data))\r\n .finally(() => setLoading(false));\r\n }\r\n\r\n useEffect(fetchTasks, [slug]);\r\n\r\n useSayrWS(wsUrl, {\r\n [Sayr.WS_EVENTS.CREATE_TASK]: fetchTasks,\r\n [Sayr.WS_EVENTS.UPDATE_TASK]: fetchTasks\r\n });\r\n\r\n return { tasks, loading, refetch: fetchTasks };\r\n}","import { useEffect, useRef } from \"react\";\r\nimport { WSMessageType } from \"../ws/types\";\r\nimport { ws } from \"../ws\";\r\n\r\ntype Handlers = Partial<\r\n Record<WSMessageType, (data: any, msg: any) => void>\r\n>;\r\n\r\nexport function useSayrWS(\r\n wsUrl?: string,\r\n handlers?: Handlers\r\n) {\r\n const connRef = useRef<ReturnType<typeof ws> | null>(null);\r\n\r\n useEffect(() => {\r\n if (!wsUrl) return;\r\n\r\n connRef.current = ws(wsUrl, handlers);\r\n\r\n return () => {\r\n connRef.current?.close();\r\n connRef.current = null;\r\n };\r\n }, [wsUrl]);\r\n\r\n return connRef;\r\n}","import { useEffect, useState } from \"react\";\r\nimport type { Task } from \"../types\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useTask(\r\n slug?: string,\r\n shortId?: number\r\n) {\r\n const [task, setTask] = useState<Task | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!slug || shortId == null) return;\r\n\r\n setLoading(true);\r\n Sayr.org.tasks.get(slug, shortId)\r\n .then(setTask)\r\n .finally(() => setLoading(false));\r\n }, [slug, shortId]);\r\n\r\n return { task, loading };\r\n}","import { useEffect, useState } from \"react\";\r\nimport type { Comment } from \"../types\";\r\nimport { useSayrWS } from \"./useSayrWS\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useComments(\r\n slug?: string,\r\n shortId?: number,\r\n wsUrl?: string\r\n) {\r\n const [comments, setComments] = useState<Comment[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n\r\n function fetchComments() {\r\n if (!slug || shortId == null) return;\r\n\r\n setLoading(true);\r\n Sayr.org.comments.list(slug, shortId)\r\n .then((r) => setComments(r.data))\r\n .finally(() => setLoading(false));\r\n }\r\n\r\n useEffect(fetchComments, [slug, shortId]);\r\n\r\n useSayrWS(wsUrl, {\r\n [Sayr.WS_EVENTS.UPDATE_TASK_COMMENTS]: fetchComments\r\n });\r\n\r\n return { comments, loading, refetch: fetchComments };\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAoC;;;AC4BpC,IAAM,cAAc;AAEpB,IAAM,SAAuB;AAAA,EACzB,OAAO,WAAW;AAAA,EAClB,SAAS;AACb;AAEA,IAAM,QAAe,CAAC;AAKf,SAAS,SAAS,OAAgB;AACrC,SAAO,QAAQ;AACnB;AAMO,SAAS,WAAW,SAAkC;AACzD,SAAO,UAAU;AAAA,IACb,GAAG,OAAO;AAAA,IACV,GAAG;AAAA,EACP;AACJ;AAEO,SAAS,SAAS,IAAkB;AACvC,SAAO,QAAQ;AACnB;AAEO,SAAS,WAAW,KAAa;AACpC,SAAO,UAAU,IAAI,QAAQ,OAAO,EAAE;AAC1C;AAEO,SAAS,SAAS,GAAU;AAC/B,SAAO,OAAO,OAAO,CAAC;AAC1B;AACO,SAAS,cAAc;AAC1B,SAAO,QAAQ;AACf,SAAO,UAAU;AACjB,SAAO,UAAU;AACrB;AAKA,eAAsB,QAClB,MACA,OAAuB,CAAC,GACd;AAEV,MAAI;AACJ,MAAI;AACA,UAAM,KAAK,WAAW,MAAM,IACtB,OACA,GAAG,OAAO,OAAO,GAAG,IAAI;AAAA,EAClC,SAAS,KAAK;AACV,UAAM;AAAA,EACV;AAEA,MAAI;AACA,UAAM,YAAY,KAAK,IAAI;AAAA,EAC/B,SAAS,KAAK;AACV,UAAM;AAAA,EACV;AAEA,MAAI;AAEJ,MAAI;AACA,UAAM,SAAS,KAAK,UAAU;AAI9B,QAAI,WAAW,SAAS,KAAK,SAAS,QAAW;AAC7C,YAAM,IAAI,MAAM,gCAAgC;AAAA,IACpD;AAEA,UAAM,MAAM,MAAM,KAAK;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,QACL,GAAI,OAAO,QACL,EAAE,eAAe,UAAU,OAAO,KAAK,GAAG,IAC1C,CAAC;AAAA,QACP,GAAI,KAAK,QAAQ,WAAW,QACtB,EAAE,gBAAgB,mBAAmB,IACrC,CAAC;AAAA,QACP,GAAG,OAAO;AAAA,QACV,GAAG,KAAK;AAAA,MACZ;AAAA,MACA,MACI,KAAK,QAAQ,WAAW,QAClB,KAAK,UAAU,KAAK,IAAI,IACxB;AAAA,MACV,QAAQ,KAAK;AAAA,IACjB,CAAC;AAAA,EACL,SAAS,KAAK;AACV,UAAM,QAAkB;AAAA,MACpB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA;AAAA;AAAA,MAGT,KAAK;AAAA,IACT;AAEA,UAAM,UAAU,KAAK;AACrB,UAAM;AAAA,EACV;AAEA,MAAI;AACA,UAAM,aAAa,GAAG;AAAA,EAC1B,SAAS,KAAK;AACV,UAAM;AAAA,EACV;AAEA,MAAI;AACJ,MAAI;AACA,WAAO,MAAM,IAAI,KAAK;AAAA,EAC1B,SAAS,KAAK;AACV,UAAM,QAAkB;AAAA,MACpB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ,IAAI;AAAA,IAChB;AACA,UAAM,UAAU,KAAK;AACrB,UAAM;AAAA,EACV;AACA,MAAI,CAAC,IAAI,MAAM,CAAC,KAAK,SAAS;AAC1B,UAAM,QAAkB;AAAA,MACpB,GAAG;AAAA,MACH,SAAS;AAAA,MACT,QAAQ,IAAI;AAAA,IAChB;AACA,UAAM,UAAU,KAAK;AACrB,UAAM;AAAA,EACV;AACA,SAAO;AACX;;;ACjKA,IAAO,cAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,IACF,MACA,MACqB;AACrB,UAAM,IAAI,MAAM;AAAA,MACZ,oBAAoB,IAAI;AAAA,MACxB;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AACJ;;;ACPO,SAAS,sBACZ,QACe;AACf,SAAO,IAAI,gBAAgB;AAAA,IACvB,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,OAAO,QAAQ,SAAS,CAAC;AAAA,IAChC,MAAM,OAAO,QAAQ,QAAQ,CAAC;AAAA,EAClC,CAAC;AACL;;;ACTA,IAAO,gBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,KACF,MACA,QACA,MACiD;AACjD,UAAM,IAAI,sBAAsB,MAAM;AAEtC,UAAM,IAAI,MAAM;AAAA,MAGZ,oBAAoB,IAAI,UAAU,CAAC;AAAA,MACnC;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,IAClB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IACF,MACA,SACA,MACa;AACb,UAAM,IAAI,MAAM;AAAA,MACZ,oBAAoB,IAAI,UAAU,OAAO;AAAA,MACzC;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AACJ;;;AC1CA,IAAO,mBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,KACF,MACA,SACA,QACA,MACoD;AACpD,UAAM,IAAI,sBAAsB,MAAM;AAEtC,UAAM,IAAI,MAAM;AAAA,MAGZ,oBAAoB,IAAI,UAAU,OAAO,aAAa,CAAC;AAAA,MACvD;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,IAClB;AAAA,EACJ;AACJ;;;AClCA,IAAO,iBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,KACF,MACA,MACgB;AAChB,UAAM,IAAI,MAAM;AAAA,MACZ,oBAAoB,IAAI;AAAA,MACxB;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AACJ;;;ACZA,IAAO,qBAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,KACF,MACA,QAAe,QACf,MACmB;AACnB,UAAM,IAAI,MAAM;AAAA,MACZ,oBAAoB,IAAI,qBAAqB,KAAK;AAAA,MAClD;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AACJ;;;AChBA,IAAM,SAAS;AAAA,EACX,GAAG;AAAA,EACH;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEA,IAAOA,eAAQ;;;ACHf,IAAO,aAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMX,MAAM,IAAI,MAAoC;AAC1C,UAAM,IAAI,MAAM;AAAA,MACZ;AAAA,MACA;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cACF,MACuB;AACvB,UAAM,IAAI,MAAM;AAAA,MACZ;AAAA,MACA;AAAA,IACJ;AACA,WAAO,EAAE;AAAA,EACb;AACJ;;;AC1CO,IAAM,KAAK;AAAA,EACd,KAAAC;AAAA,EACA;AACJ;AAEA,IAAO,aAAQ;;;ACcR,IAAM,YAAkD;AAAA,EAC3D,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,cAAc;AAClB;;;AC/BO,SAAS,GAAG,KAAa,WAAqB,CAAC,GAAG;AACrD,MAAI,CAAC,KAAK;AACN,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AACA,MAAI;AACJ,MAAI,QAAQ;AACZ,MAAI,SAAS;AAEb,WAAS,UAAU;AACf,QAAI,OAAQ;AAEZ,aAAS,IAAI,UAAU,GAAG;AAE1B,WAAO,YAAY,CAAC,MAAM;AACtB,YAAM,MAAM,KAAK,MAAM,EAAE,IAAI;AAE7B,UAAI,IAAI,SAAS,UAAU,MAAM;AAC7B,eAAO,KAAK,KAAK,UAAU,EAAE,MAAM,UAAU,KAAK,CAAC,CAAC;AACpD;AAAA,MACJ;AAEA,eAAS,IAAI,IAAI,IAAI,IAAI,MAAM,GAAG;AAAA,IACtC;AAEA,WAAO,UAAU,MAAM;AACnB,UAAI,OAAQ;AACZ,iBAAW,SAAS,KAAK,IAAI,MAAO,KAAK,SAAS,GAAK,CAAC;AAAA,IAC5D;AAEA,WAAO,UAAU,MAAM,OAAO,MAAM;AAAA,EACxC;AAEA,UAAQ;AAER,SAAO;AAAA,IACH,QAAQ;AACJ,eAAS;AACT,cAAQ,MAAM;AAAA,IAClB;AAAA,EACJ;AACJ;;;ACDO,IAAM,aAAa;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACH;AAaA,IAAM,OA4BF;AAAA;AAAA,EAED,QAAQ;AAAA;AAAA,EAGR;AAAA,EACA,KAAK,WAAG;AAAA,EACR,IAAI,WAAG;AAAA;AAAA,EAGP;AAAA,EACA;AACH;AAEA,IAAO,gBAAQ;;;Ab3GR,SAAS,OAAO,MAAe;AAClC,QAAM,CAAC,MAAM,OAAO,QAAI,uBAA8B,IAAI;AAC1D,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAkB,IAAI;AAEhD,8BAAU,MAAM;AACZ,QAAI,CAAC,KAAM;AAEX,eAAW,IAAI;AACf,kBAAK,IACA,IAAI,IAAI,EACR,KAAK,OAAO,EACZ,MAAM,QAAQ,EACd,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EACxC,GAAG,CAAC,IAAI,CAAC;AAET,SAAO,EAAE,MAAM,SAAS,MAAM;AAClC;;;AcpBA,IAAAC,gBAAoC;;;ACApC,IAAAC,gBAAkC;AAQ3B,SAAS,UACZ,OACA,UACF;AACE,QAAM,cAAU,sBAAqC,IAAI;AAEzD,+BAAU,MAAM;AACZ,QAAI,CAAC,MAAO;AAEZ,YAAQ,UAAU,GAAG,OAAO,QAAQ;AAEpC,WAAO,MAAM;AACT,cAAQ,SAAS,MAAM;AACvB,cAAQ,UAAU;AAAA,IACtB;AAAA,EACJ,GAAG,CAAC,KAAK,CAAC;AAEV,SAAO;AACX;;;ADtBO,SAAS,SACZ,MACA,OACF;AACE,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAiB,CAAC,CAAC;AAC7C,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAE5C,WAAS,aAAa;AAClB,QAAI,CAAC,KAAM;AACX,eAAW,IAAI;AACf,kBAAK,IAAI,MAAM,KAAK,IAAI,EACnB,KAAK,CAAC,MAAM,SAAS,EAAE,IAAI,CAAC,EAC5B,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EACxC;AAEA,+BAAU,YAAY,CAAC,IAAI,CAAC;AAE5B,YAAU,OAAO;AAAA,IACb,CAAC,cAAK,UAAU,WAAW,GAAG;AAAA,IAC9B,CAAC,cAAK,UAAU,WAAW,GAAG;AAAA,EAClC,CAAC;AAED,SAAO,EAAE,OAAO,SAAS,SAAS,WAAW;AACjD;;;AE3BA,IAAAC,gBAAoC;AAI7B,SAAS,QACZ,MACA,SACF;AACE,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAsB,IAAI;AAClD,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAE5C,+BAAU,MAAM;AACZ,QAAI,CAAC,QAAQ,WAAW,KAAM;AAE9B,eAAW,IAAI;AACf,kBAAK,IAAI,MAAM,IAAI,MAAM,OAAO,EAC3B,KAAK,OAAO,EACZ,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EACxC,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,SAAO,EAAE,MAAM,QAAQ;AAC3B;;;ACrBA,IAAAC,gBAAoC;AAK7B,SAAS,YACZ,MACA,SACA,OACF;AACE,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAoB,CAAC,CAAC;AACtD,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAE5C,WAAS,gBAAgB;AACrB,QAAI,CAAC,QAAQ,WAAW,KAAM;AAE9B,eAAW,IAAI;AACf,kBAAK,IAAI,SAAS,KAAK,MAAM,OAAO,EAC/B,KAAK,CAAC,MAAM,YAAY,EAAE,IAAI,CAAC,EAC/B,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EACxC;AAEA,+BAAU,eAAe,CAAC,MAAM,OAAO,CAAC;AAExC,YAAU,OAAO;AAAA,IACb,CAAC,cAAK,UAAU,oBAAoB,GAAG;AAAA,EAC3C,CAAC;AAED,SAAO,EAAE,UAAU,SAAS,SAAS,cAAc;AACvD;","names":["org_default","org_default","import_react","import_react","import_react","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts","../../src/react/useOrg.ts","../../src/client/index.ts","../../src/api/v1/org/org.ts","../../src/shared/index.ts","../../src/api/v1/org/tasks.ts","../../src/api/v1/org/comments.ts","../../src/api/v1/org/labels.ts","../../src/api/v1/org/categories.ts","../../src/api/v1/org/index.ts","../../src/api/v1/me/index.ts","../../src/api/v1/index.ts","../../src/ws/types.ts","../../src/ws/index.ts","../../src/index.ts","../../src/react/useTasks.ts","../../src/react/useSayrWS.ts","../../src/react/useTask.ts","../../src/react/useComments.ts"],"sourcesContent":["export { useOrg } from \"./useOrg\";\r\nexport { useTasks } from \"./useTasks\";\r\nexport { useTask } from \"./useTask\";\r\nexport { useComments } from \"./useComments\";\r\nexport { useSayrWS } from \"./useSayrWS\";","import { useEffect, useRef, useState } from \"react\";\r\nimport Sayr, { Organization } from \"../index\";\r\n\r\nexport function useOrg(slug?: string) {\r\n const [data, setData] = useState<Organization | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const mountedRef = useRef(true);\r\n\r\n useEffect(() => {\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!slug) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n Sayr.org.get(slug).then((res) => {\r\n if (!mountedRef.current) return;\r\n\r\n if (!res.success) {\r\n setError(res.error);\r\n setData(null);\r\n } else {\r\n setData(res.data);\r\n }\r\n\r\n setLoading(false);\r\n });\r\n }, [slug]);\r\n\r\n return {\r\n data,\r\n loading,\r\n error,\r\n };\r\n}","import { ApiError } from \"../types\";\r\n\r\n/* ────────────────────────────\r\n Types\r\n──────────────────────────── */\r\nexport type RequestOptions = {\r\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\r\n headers?: Record<string, string>;\r\n body?: Record<string, string>;\r\n signal?: AbortSignal;\r\n};\r\n\r\nexport interface ApiResult<T> {\r\n success: boolean;\r\n data: T | null;\r\n error: string | null;\r\n}\r\n\r\ntype Hooks = {\r\n onRequest?: (url: string, opts: RequestOptions) => void;\r\n onResponse?: (res: Response) => void;\r\n onError?: (error: ApiError | unknown) => void;\r\n};\r\n\r\ntype ClientConfig = {\r\n token?: string;\r\n headers?: Record<string, string>;\r\n baseUrl: string;\r\n};\r\n\r\n/* ────────────────────────────\r\n Internal state\r\n──────────────────────────── */\r\nconst DEFAULT_API = \"https://api.sayr.io\";\r\n\r\nconst config: ClientConfig = {\r\n baseUrl: DEFAULT_API\r\n};\r\n\r\nconst hooks: Hooks = {};\r\n\r\n/* ────────────────────────────\r\n Public config API\r\n──────────────────────────── */\r\nexport function setToken(token?: string) {\r\n config.token = token;\r\n}\r\n\r\nexport function getToken() {\r\n return config.token;\r\n}\r\n\r\nexport function setHeaders(headers?: Record<string, string>) {\r\n config.headers = {\r\n ...config.headers,\r\n ...headers\r\n };\r\n}\r\n\r\nexport function setBaseUrl(url: string) {\r\n config.baseUrl = url.replace(/\\/$/, \"\");\r\n}\r\n\r\nexport function setHooks(h: Hooks) {\r\n Object.assign(hooks, h);\r\n}\r\nexport function resetClient() {\r\n config.token = undefined;\r\n config.headers = undefined;\r\n config.baseUrl = DEFAULT_API;\r\n}\r\n\r\n/* ────────────────────────────\r\n Request helper\r\n──────────────────────────── */\r\nexport async function request<T>(\r\n path: string,\r\n opts: RequestOptions = {}\r\n): Promise<T> {\r\n\r\n let url: string;\r\n try {\r\n url = path.startsWith(\"http\")\r\n ? path\r\n : `${config.baseUrl}${path}`;\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n try {\r\n hooks.onRequest?.(url, opts);\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n let res: Response;\r\n\r\n try {\r\n const method = opts.method ?? \"GET\";\r\n\r\n\r\n // 🔴 Guard: GET must not have body\r\n if (method === \"GET\" && opts.body !== undefined) {\r\n throw new Error(\"GET request cannot have a body\");\r\n }\r\n\r\n res = await fetch(url, {\r\n method,\r\n headers: {\r\n ...(config.token\r\n ? { Authorization: `Bearer ${config.token}` }\r\n : {}),\r\n ...(opts.body && method !== \"GET\"\r\n ? { \"Content-Type\": \"application/json\" }\r\n : {}),\r\n ...config.headers,\r\n ...opts.headers\r\n },\r\n body:\r\n opts.body && method !== \"GET\"\r\n ? JSON.stringify(opts.body)\r\n : undefined,\r\n signal: opts.signal\r\n });\r\n } catch (err) {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"NETWORK_ERROR\",\r\n message: \"Failed to reach Sayr API\",\r\n // 👇 keep raw error so we can see it\r\n // @ts-ignore\r\n raw: err\r\n };\r\n\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n try {\r\n hooks.onResponse?.(res);\r\n } catch (err) {\r\n throw err;\r\n }\r\n\r\n let json: any;\r\n try {\r\n json = await res.json();\r\n } catch (err) {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"INVALID_RESPONSE\",\r\n message: \"Server returned invalid JSON\",\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n if (!res.ok || !json.success) {\r\n const error: ApiError = {\r\n ...json,\r\n success: false,\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n return json;\r\n}","import { Organization, ApiSuccess } from \"../../../types\";\r\nimport { ApiResult, request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization core operations.\r\n */\r\nexport default {\r\n /**\r\n * Fetches a public organization by slug.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<Organization>> {\r\n try {\r\n const r = await request<ApiSuccess<Organization>>(\r\n `/v1/organization/${slug}`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error: err?.message ?? \"Failed to fetch organization\",\r\n };\r\n }\r\n },\r\n};","/* =======================\r\n * Shared params & helpers\r\n * ======================= */\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport interface PaginationParams {\r\n page?: number;\r\n limit?: number;\r\n}\r\n\r\nexport interface OrderedPaginationParams extends PaginationParams {\r\n order?: Order;\r\n}\r\n\r\nexport function buildPaginationParams(\r\n params?: OrderedPaginationParams\r\n): URLSearchParams {\r\n return new URLSearchParams({\r\n order: params?.order ?? \"desc\",\r\n limit: String(params?.limit ?? 5),\r\n page: String(params?.page ?? 1)\r\n });\r\n}","import {\r\n Task,\r\n Pagination,\r\n ApiSuccess,\r\n} from \"../../../types\";\r\nimport {\r\n ApiResult,\r\n request,\r\n type RequestOptions,\r\n} from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams,\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization tasks.\r\n */\r\nexport default {\r\n /**\r\n * Lists public tasks for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions,\r\n ): Promise<\r\n ApiResult<{\r\n items: Task[];\r\n pagination: Pagination;\r\n }>\r\n > {\r\n try {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Task[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks?${q}`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: {\r\n items: r.data,\r\n pagination: r.pagination,\r\n },\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error:\r\n err?.message ??\r\n \"Failed to fetch tasks\",\r\n };\r\n }\r\n },\r\n\r\n /**\r\n * Fetches a single public task by short ID.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n shortId: number,\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<Task>> {\r\n try {\r\n const r = await request<ApiSuccess<Task>>(\r\n `/v1/organization/${slug}/tasks/${shortId}`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error:\r\n err?.message ??\r\n \"Failed to fetch task\",\r\n };\r\n }\r\n },\r\n};","import {\r\n Comment,\r\n Pagination,\r\n ApiSuccess,\r\n} from \"../../../types\";\r\nimport {\r\n ApiResult,\r\n request,\r\n type RequestOptions,\r\n} from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams,\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization task comments.\r\n */\r\nexport default {\r\n /**\r\n * Lists public comments for a task.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n shortId: number,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions,\r\n ): Promise<\r\n ApiResult<{\r\n items: Comment[];\r\n pagination: Pagination;\r\n }>\r\n > {\r\n try {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Comment[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks/${shortId}/comments?${q}`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: {\r\n items: r.data,\r\n pagination: r.pagination,\r\n },\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error:\r\n err?.message ??\r\n \"Failed to fetch task comments\",\r\n };\r\n }\r\n },\r\n};","import { Label, ApiSuccess } from \"../../../types\";\r\nimport { ApiResult, request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization labels.\r\n */\r\nexport default {\r\n /**\r\n * Lists public labels for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<Label[]>> {\r\n try {\r\n const r = await request<ApiSuccess<Label[]>>(\r\n `/v1/organization/${slug}/labels`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error: err?.message ?? \"Failed to fetch labels\",\r\n };\r\n }\r\n },\r\n};","import {\r\n Category,\r\n ApiSuccess,\r\n} from \"../../../types\";\r\nimport {\r\n ApiResult,\r\n request,\r\n type RequestOptions,\r\n} from \"../../../client\";\r\nimport { type Order } from \"../../../shared\";\r\n\r\n/**\r\n * Organization categories.\r\n */\r\nexport default {\r\n /**\r\n * Lists public categories for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n order: Order = \"desc\",\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<Category[]>> {\r\n try {\r\n const r = await request<ApiSuccess<Category[]>>(\r\n `/v1/organization/${slug}/categories?order=${order}`,\r\n opts,\r\n );\r\n\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error:\r\n err?.message ??\r\n \"Failed to fetch categories\",\r\n };\r\n }\r\n },\r\n};","import org from \"./org\";\r\nimport tasks from \"./tasks\";\r\nimport comments from \"./comments\";\r\nimport labels from \"./labels\";\r\nimport categories from \"./categories\";\r\n\r\n/**\r\n * Public Sayr Organization API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst OrgAPI = {\r\n ...org,\r\n tasks,\r\n comments,\r\n labels,\r\n categories\r\n};\r\n\r\nexport default OrgAPI;","import { ApiResult, request, type RequestOptions } from \"../../../client\";\r\nimport { ApiSuccess, Organization } from \"../../../types\";\r\n\r\nexport interface Me {\r\n id: string;\r\n name: string | null;\r\n email: string | null;\r\n image: string | null;\r\n createdAt: string;\r\n}\r\n\r\n/**\r\n * Authenticated user API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport default {\r\n async get(opts?: RequestOptions): Promise<ApiResult<Me>> {\r\n try {\r\n const r = await request<ApiSuccess<Me>>(\"/v1/me\", opts);\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error: err?.message ?? \"Failed to fetch user\",\r\n };\r\n }\r\n },\r\n\r\n async organizations(\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<Organization[]>> {\r\n try {\r\n const r = await request<ApiSuccess<Organization[]>>(\r\n \"/v1/me/organizations\",\r\n opts,\r\n );\r\n return {\r\n success: true,\r\n data: r.data,\r\n error: null,\r\n };\r\n } catch (err: any) {\r\n return {\r\n success: false,\r\n data: null,\r\n error: err?.message ?? \"Failed to fetch organizations\",\r\n };\r\n }\r\n },\r\n};","import org from \"./org\";\r\nimport me from \"./me\";\r\nexport const v1 = {\r\n org,\r\n me\r\n};\r\n\r\nexport default v1;","export type WSMessageType =\r\n | \"CONNECTION_STATUS\"\r\n | \"SUBSCRIBED\"\r\n | \"ERROR\"\r\n | \"PING\"\r\n | \"PONG\"\r\n | \"UPDATE_ORG\"\r\n | \"CREATE_TASK\"\r\n | \"UPDATE_TASK\"\r\n | \"UPDATE_TASK_COMMENTS\"\r\n | \"UPDATE_TASK_VOTE\"\r\n | \"UPDATE_LABELS\"\r\n | \"UPDATE_VIEWS\"\r\n | \"UPDATE_CATEGORIES\"\r\n | \"UPDATE_ISSUE_TEMPLATES\"\r\n | \"DISCONNECTED\";\r\n\r\n/**\r\n * String enum replacement for WS event names.\r\n * Use this instead of raw strings.\r\n */\r\nexport const WS_EVENTS: Record<WSMessageType, WSMessageType> = {\r\n CONNECTION_STATUS: \"CONNECTION_STATUS\",\r\n SUBSCRIBED: \"SUBSCRIBED\",\r\n ERROR: \"ERROR\",\r\n PING: \"PING\",\r\n PONG: \"PONG\",\r\n UPDATE_ORG: \"UPDATE_ORG\",\r\n CREATE_TASK: \"CREATE_TASK\",\r\n UPDATE_TASK: \"UPDATE_TASK\",\r\n UPDATE_TASK_COMMENTS: \"UPDATE_TASK_COMMENTS\",\r\n UPDATE_TASK_VOTE: \"UPDATE_TASK_VOTE\",\r\n UPDATE_LABELS: \"UPDATE_LABELS\",\r\n UPDATE_VIEWS: \"UPDATE_VIEWS\",\r\n UPDATE_CATEGORIES: \"UPDATE_CATEGORIES\",\r\n UPDATE_ISSUE_TEMPLATES: \"UPDATE_ISSUE_TEMPLATES\",\r\n DISCONNECTED: \"DISCONNECTED\"\r\n};\r\n\r\nexport interface WSMessage<T = unknown> {\r\n type: WSMessageType;\r\n scope: \"PUBLIC\";\r\n data: T;\r\n meta?: { ts: number };\r\n}","import { WS_EVENTS, type WSMessage, type WSMessageType } from \"./types\";\r\n\r\ntype Handlers = Partial<\r\n Record<WSMessageType, (data: any, msg: WSMessage) => void>\r\n>;\r\n\r\nexport function ws(url: string, handlers: Handlers = {}) {\r\n if (!url) {\r\n throw new Error(\r\n \"[Sayr.ws] WebSocket URL is required. \" +\r\n \"Did you forget to pass org.wsUrl?\"\r\n );\r\n }\r\n let socket: WebSocket;\r\n let retry = 0;\r\n let closed = false;\r\n\r\n function connect() {\r\n if (closed) return;\r\n\r\n socket = new WebSocket(url);\r\n\r\n socket.onmessage = (e) => {\r\n const msg = JSON.parse(e.data) as WSMessage;\r\n\r\n if (msg.type === WS_EVENTS.PING) {\r\n socket.send(JSON.stringify({ type: WS_EVENTS.PONG }));\r\n return;\r\n }\r\n\r\n handlers[msg.type]?.(msg.data, msg);\r\n };\r\n\r\n socket.onclose = () => {\r\n if (closed) return;\r\n setTimeout(connect, Math.min(1000 * 2 ** retry++, 30000));\r\n };\r\n\r\n socket.onerror = () => socket.close();\r\n }\r\n\r\n connect();\r\n\r\n return {\r\n close() {\r\n closed = true;\r\n socket?.close();\r\n }\r\n };\r\n}","/* ────────────────────────────\r\n API versions\r\n──────────────────────────── */\r\nimport v1 from \"./api/v1\";\r\n\r\n/* ────────────────────────────\r\n Realtime\r\n──────────────────────────── */\r\nimport { ws } from \"./ws\";\r\nimport { WS_EVENTS } from \"./ws/types\";\r\n\r\n/* ────────────────────────────\r\n Client config\r\n──────────────────────────── */\r\nimport {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n} from \"./client\";\r\n\r\n/* ────────────────────────────\r\n Named exports (power users)\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport const SayrV1 = v1;\r\n\r\n\r\n/**\r\n * Create a WebSocket connection for public real‑time updates.\r\n */\r\nexport const SayrWS = ws;\r\n\r\n/**\r\n * Typed WebSocket event constants.\r\n */\r\nexport const SayrWSEvents = WS_EVENTS;\r\n\r\n/**\r\n * Global client configuration helpers.\r\n */\r\nexport const SayrClient = {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n};\r\n\r\n/* ────────────────────────────\r\n Default facade\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public SDK.\r\n *\r\n * Read‑only access to public Sayr data via REST and WebSockets.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst Sayr: {\r\n /**\r\n * Client configuration helpers.\r\n */\r\n client: typeof SayrClient;\r\n\r\n /**\r\n * Versioned API namespaces.\r\n */\r\n v1: typeof v1;\r\n\r\n /**\r\n * Alias for the current API version (`v1`).\r\n *\r\n * @since v1.0.0\r\n */\r\n org: typeof v1.org;\r\n me: typeof v1.me;\r\n\r\n /**\r\n * WebSocket helper for real‑time updates.\r\n */\r\n ws: typeof ws;\r\n\r\n /**\r\n * WebSocket event constants.\r\n */\r\n WS_EVENTS: typeof WS_EVENTS;\r\n} = {\r\n // client configuration\r\n client: SayrClient,\r\n\r\n // APIs\r\n v1,\r\n org: v1.org,\r\n me: v1.me,\r\n\r\n // realtime\r\n ws,\r\n WS_EVENTS\r\n};\r\n\r\nexport default Sayr;\r\n\r\n/* ────────────────────────────\r\n Types & shared helpers\r\n──────────────────────────── */\r\nexport * from \"./types\";\r\nexport * from \"./shared\";\r\nexport * from \"./ws/types\";","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { Task } from \"../types\";\r\nimport { useSayrWS } from \"./useSayrWS\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useTasks(\r\n slug?: string,\r\n wsUrl?: string,\r\n) {\r\n const [tasks, setTasks] = useState<Task[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const mountedRef = useRef(true);\r\n\r\n useEffect(() => {\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n const fetchTasks = useCallback(async () => {\r\n if (!slug) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const res = await Sayr.org.tasks.list(slug);\r\n\r\n if (!mountedRef.current) return;\r\n\r\n if (!res.success) {\r\n setError(res.error);\r\n setTasks([]);\r\n } else {\r\n setTasks(res.data?.items ?? []);\r\n }\r\n\r\n setLoading(false);\r\n }, [slug]);\r\n\r\n useEffect(() => {\r\n fetchTasks();\r\n }, [fetchTasks]);\r\n\r\n useSayrWS(wsUrl, {\r\n [Sayr.WS_EVENTS.CREATE_TASK]: fetchTasks,\r\n [Sayr.WS_EVENTS.UPDATE_TASK]: fetchTasks,\r\n });\r\n\r\n return {\r\n tasks,\r\n loading,\r\n error,\r\n refetch: fetchTasks,\r\n };\r\n}","import { useEffect, useRef } from \"react\";\r\nimport { WSMessageType } from \"../ws/types\";\r\nimport { ws } from \"../ws\";\r\nimport type { WSMessage } from \"../ws/types\";\r\n\r\ntype Handler = (data: any, msg: WSMessage<unknown>) => void;\r\n\r\ntype Handlers = Partial<Record<WSMessageType, Handler>>;\r\n\r\nexport function useSayrWS(\r\n wsUrl?: string,\r\n handlers?: Handlers,\r\n) {\r\n const connRef = useRef<ReturnType<typeof ws> | null>(null);\r\n const handlersRef = useRef<Handlers | undefined>(handlers);\r\n\r\n // ✅ Keep latest handlers without reconnecting\r\n useEffect(() => {\r\n handlersRef.current = handlers;\r\n }, [handlers]);\r\n\r\n useEffect(() => {\r\n if (!wsUrl) return;\r\n\r\n // ✅ Adapter object: keys stay stable, functions dispatch dynamically\r\n const proxyHandlers: Handlers = new Proxy(\r\n {},\r\n {\r\n get: (_, type: string) => {\r\n return (data: any, msg: WSMessage<unknown>) => {\r\n const handler =\r\n handlersRef.current?.[type as WSMessageType];\r\n if (handler) {\r\n handler(data, msg);\r\n }\r\n };\r\n },\r\n },\r\n );\r\n\r\n connRef.current = ws(wsUrl, proxyHandlers);\r\n\r\n return () => {\r\n connRef.current?.close();\r\n connRef.current = null;\r\n };\r\n }, [wsUrl]);\r\n\r\n return connRef;\r\n}","import { useEffect, useRef, useState } from \"react\";\r\nimport type { Task } from \"../types\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useTask(\r\n slug?: string,\r\n shortId?: number,\r\n) {\r\n const [task, setTask] = useState<Task | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const mountedRef = useRef(true);\r\n\r\n useEffect(() => {\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!slug || shortId == null) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n Sayr.org.tasks.get(slug, shortId).then((res) => {\r\n if (!mountedRef.current) return;\r\n\r\n if (!res.success) {\r\n setError(res.error);\r\n setTask(null);\r\n } else {\r\n setTask(res.data);\r\n }\r\n\r\n setLoading(false);\r\n });\r\n }, [slug, shortId]);\r\n\r\n return {\r\n task,\r\n loading,\r\n error,\r\n };\r\n}","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { Comment } from \"../types\";\r\nimport { useSayrWS } from \"./useSayrWS\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useComments(\r\n slug?: string,\r\n shortId?: number,\r\n wsUrl?: string,\r\n) {\r\n const [comments, setComments] = useState<Comment[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const mountedRef = useRef(true);\r\n\r\n useEffect(() => {\r\n return () => {\r\n mountedRef.current = false;\r\n };\r\n }, []);\r\n\r\n const fetchComments = useCallback(async () => {\r\n if (!slug || shortId == null) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const res = await Sayr.org.comments.list(\r\n slug,\r\n shortId,\r\n );\r\n\r\n if (!mountedRef.current) return;\r\n\r\n if (!res.success) {\r\n setError(res.error);\r\n setComments([]);\r\n } else {\r\n setComments(res.data?.items ?? []);\r\n }\r\n\r\n setLoading(false);\r\n }, [slug, shortId]);\r\n\r\n useEffect(() => {\r\n fetchComments();\r\n }, [fetchComments]);\r\n\r\n useSayrWS(wsUrl, {\r\n [Sayr.WS_EVENTS.UPDATE_TASK_COMMENTS]: fetchComments,\r\n });\r\n\r\n return {\r\n comments,\r\n loading,\r\n error,\r\n refetch: fetchComments,\r\n };\r\n}"],"mappings":"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","names":["org_default","org_default","import_react","import_react","import_react","import_react"]}
|