@sayrio/public 1.0.2 → 1.0.4
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/LICENSE.md +87 -0
- package/README.md +42 -42
- package/dist/index.cjs +55 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -12
- package/dist/index.d.ts +34 -12
- package/dist/index.js +52 -41
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +62 -54
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +10 -10
- package/dist/react/index.d.ts +10 -10
- package/dist/react/index.js +61 -53
- package/dist/react/index.js.map +1 -1
- package/package.json +2 -2
package/dist/react/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
useComments: () => useComments,
|
|
24
24
|
useOrg: () => useOrg,
|
|
25
|
-
|
|
25
|
+
useSayrSSE: () => useSayrSSE,
|
|
26
26
|
useTask: () => useTask,
|
|
27
27
|
useTasks: () => useTasks
|
|
28
28
|
});
|
|
@@ -355,6 +355,26 @@ var me_default = {
|
|
|
355
355
|
error: err?.message ?? "Failed to fetch organizations"
|
|
356
356
|
};
|
|
357
357
|
}
|
|
358
|
+
},
|
|
359
|
+
async createTask(body, opts) {
|
|
360
|
+
try {
|
|
361
|
+
const r = await request("/v1/me/task", {
|
|
362
|
+
...opts,
|
|
363
|
+
method: "POST",
|
|
364
|
+
body
|
|
365
|
+
});
|
|
366
|
+
return {
|
|
367
|
+
success: true,
|
|
368
|
+
data: r.data,
|
|
369
|
+
error: null
|
|
370
|
+
};
|
|
371
|
+
} catch (err) {
|
|
372
|
+
return {
|
|
373
|
+
success: false,
|
|
374
|
+
data: null,
|
|
375
|
+
error: err?.message ?? "Failed to create task"
|
|
376
|
+
};
|
|
377
|
+
}
|
|
358
378
|
}
|
|
359
379
|
};
|
|
360
380
|
|
|
@@ -365,61 +385,52 @@ var v1 = {
|
|
|
365
385
|
};
|
|
366
386
|
var v1_default = v1;
|
|
367
387
|
|
|
368
|
-
// src/
|
|
369
|
-
|
|
370
|
-
CONNECTION_STATUS: "CONNECTION_STATUS",
|
|
371
|
-
SUBSCRIBED: "SUBSCRIBED",
|
|
372
|
-
ERROR: "ERROR",
|
|
373
|
-
PING: "PING",
|
|
374
|
-
PONG: "PONG",
|
|
375
|
-
UPDATE_ORG: "UPDATE_ORG",
|
|
376
|
-
CREATE_TASK: "CREATE_TASK",
|
|
377
|
-
UPDATE_TASK: "UPDATE_TASK",
|
|
378
|
-
UPDATE_TASK_COMMENTS: "UPDATE_TASK_COMMENTS",
|
|
379
|
-
UPDATE_TASK_VOTE: "UPDATE_TASK_VOTE",
|
|
380
|
-
UPDATE_LABELS: "UPDATE_LABELS",
|
|
381
|
-
UPDATE_VIEWS: "UPDATE_VIEWS",
|
|
382
|
-
UPDATE_CATEGORIES: "UPDATE_CATEGORIES",
|
|
383
|
-
UPDATE_ISSUE_TEMPLATES: "UPDATE_ISSUE_TEMPLATES",
|
|
384
|
-
DISCONNECTED: "DISCONNECTED"
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
// src/ws/index.ts
|
|
388
|
-
function ws(url, handlers = {}) {
|
|
388
|
+
// src/events/index.ts
|
|
389
|
+
function sse(url, handlers = {}) {
|
|
389
390
|
if (!url) {
|
|
390
391
|
throw new Error(
|
|
391
|
-
"[Sayr.
|
|
392
|
+
"[Sayr.sse] SSE URL is required. Did you forget to pass org.eventsUrl?"
|
|
392
393
|
);
|
|
393
394
|
}
|
|
394
|
-
let
|
|
395
|
-
let retry = 0;
|
|
395
|
+
let source = null;
|
|
396
396
|
let closed = false;
|
|
397
397
|
function connect() {
|
|
398
398
|
if (closed) return;
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
source = new EventSource(url);
|
|
400
|
+
source.onmessage = (e) => {
|
|
401
401
|
const msg = JSON.parse(e.data);
|
|
402
|
-
if (msg.type === WS_EVENTS.PING) {
|
|
403
|
-
socket.send(JSON.stringify({ type: WS_EVENTS.PONG }));
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
402
|
handlers[msg.type]?.(msg.data, msg);
|
|
407
403
|
};
|
|
408
|
-
|
|
404
|
+
source.onerror = () => {
|
|
409
405
|
if (closed) return;
|
|
410
|
-
|
|
406
|
+
source?.close();
|
|
407
|
+
setTimeout(connect, 2e3);
|
|
411
408
|
};
|
|
412
|
-
socket.onerror = () => socket.close();
|
|
413
409
|
}
|
|
414
410
|
connect();
|
|
415
411
|
return {
|
|
416
412
|
close() {
|
|
417
413
|
closed = true;
|
|
418
|
-
|
|
414
|
+
source?.close();
|
|
419
415
|
}
|
|
420
416
|
};
|
|
421
417
|
}
|
|
422
418
|
|
|
419
|
+
// src/events/types.ts
|
|
420
|
+
var ServerEvent_EVENTS = {
|
|
421
|
+
CONNECTION_STATUS: "CONNECTION_STATUS",
|
|
422
|
+
ERROR: "ERROR",
|
|
423
|
+
UPDATE_ORG: "UPDATE_ORG",
|
|
424
|
+
CREATE_TASK: "CREATE_TASK",
|
|
425
|
+
UPDATE_TASK: "UPDATE_TASK",
|
|
426
|
+
UPDATE_TASK_COMMENTS: "UPDATE_TASK_COMMENTS",
|
|
427
|
+
UPDATE_TASK_VOTE: "UPDATE_TASK_VOTE",
|
|
428
|
+
UPDATE_LABELS: "UPDATE_LABELS",
|
|
429
|
+
UPDATE_VIEWS: "UPDATE_VIEWS",
|
|
430
|
+
UPDATE_CATEGORIES: "UPDATE_CATEGORIES",
|
|
431
|
+
UPDATE_ISSUE_TEMPLATES: "UPDATE_ISSUE_TEMPLATES"
|
|
432
|
+
};
|
|
433
|
+
|
|
423
434
|
// src/index.ts
|
|
424
435
|
var SayrClient = {
|
|
425
436
|
setToken,
|
|
@@ -436,8 +447,8 @@ var Sayr = {
|
|
|
436
447
|
org: v1_default.org,
|
|
437
448
|
me: v1_default.me,
|
|
438
449
|
// realtime
|
|
439
|
-
|
|
440
|
-
|
|
450
|
+
sse,
|
|
451
|
+
EVENTS: ServerEvent_EVENTS
|
|
441
452
|
};
|
|
442
453
|
var index_default = Sayr;
|
|
443
454
|
|
|
@@ -477,16 +488,16 @@ function useOrg(slug) {
|
|
|
477
488
|
// src/react/useTasks.ts
|
|
478
489
|
var import_react3 = require("react");
|
|
479
490
|
|
|
480
|
-
// src/react/
|
|
491
|
+
// src/react/useSayrSSE.ts
|
|
481
492
|
var import_react2 = require("react");
|
|
482
|
-
function
|
|
493
|
+
function useSayrSSE(eventsUrl, handlers) {
|
|
483
494
|
const connRef = (0, import_react2.useRef)(null);
|
|
484
495
|
const handlersRef = (0, import_react2.useRef)(handlers);
|
|
485
496
|
(0, import_react2.useEffect)(() => {
|
|
486
497
|
handlersRef.current = handlers;
|
|
487
498
|
}, [handlers]);
|
|
488
499
|
(0, import_react2.useEffect)(() => {
|
|
489
|
-
if (!
|
|
500
|
+
if (!eventsUrl) return;
|
|
490
501
|
const proxyHandlers = new Proxy(
|
|
491
502
|
{},
|
|
492
503
|
{
|
|
@@ -500,17 +511,17 @@ function useSayrWS(wsUrl, handlers) {
|
|
|
500
511
|
}
|
|
501
512
|
}
|
|
502
513
|
);
|
|
503
|
-
connRef.current =
|
|
514
|
+
connRef.current = sse(eventsUrl, proxyHandlers);
|
|
504
515
|
return () => {
|
|
505
516
|
connRef.current?.close();
|
|
506
517
|
connRef.current = null;
|
|
507
518
|
};
|
|
508
|
-
}, [
|
|
519
|
+
}, [eventsUrl]);
|
|
509
520
|
return connRef;
|
|
510
521
|
}
|
|
511
522
|
|
|
512
523
|
// src/react/useTasks.ts
|
|
513
|
-
function useTasks(slug,
|
|
524
|
+
function useTasks(slug, eventsUrl) {
|
|
514
525
|
const [tasks, setTasks] = (0, import_react3.useState)([]);
|
|
515
526
|
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
516
527
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
@@ -537,9 +548,9 @@ function useTasks(slug, wsUrl) {
|
|
|
537
548
|
(0, import_react3.useEffect)(() => {
|
|
538
549
|
fetchTasks();
|
|
539
550
|
}, [fetchTasks]);
|
|
540
|
-
|
|
541
|
-
[index_default.
|
|
542
|
-
[index_default.
|
|
551
|
+
useSayrSSE(eventsUrl, {
|
|
552
|
+
[index_default.EVENTS.CREATE_TASK]: fetchTasks,
|
|
553
|
+
[index_default.EVENTS.UPDATE_TASK]: fetchTasks
|
|
543
554
|
});
|
|
544
555
|
return {
|
|
545
556
|
tasks,
|
|
@@ -585,7 +596,7 @@ function useTask(slug, shortId) {
|
|
|
585
596
|
|
|
586
597
|
// src/react/useComments.ts
|
|
587
598
|
var import_react5 = require("react");
|
|
588
|
-
function useComments(slug, shortId,
|
|
599
|
+
function useComments(slug, shortId, eventsUrl) {
|
|
589
600
|
const [comments, setComments] = (0, import_react5.useState)([]);
|
|
590
601
|
const [loading, setLoading] = (0, import_react5.useState)(false);
|
|
591
602
|
const [error, setError] = (0, import_react5.useState)(null);
|
|
@@ -599,10 +610,7 @@ function useComments(slug, shortId, wsUrl) {
|
|
|
599
610
|
if (!slug || shortId == null) return;
|
|
600
611
|
setLoading(true);
|
|
601
612
|
setError(null);
|
|
602
|
-
const res = await index_default.org.comments.list(
|
|
603
|
-
slug,
|
|
604
|
-
shortId
|
|
605
|
-
);
|
|
613
|
+
const res = await index_default.org.comments.list(slug, shortId);
|
|
606
614
|
if (!mountedRef.current) return;
|
|
607
615
|
if (!res.success) {
|
|
608
616
|
setError(res.error);
|
|
@@ -615,8 +623,8 @@ function useComments(slug, shortId, wsUrl) {
|
|
|
615
623
|
(0, import_react5.useEffect)(() => {
|
|
616
624
|
fetchComments();
|
|
617
625
|
}, [fetchComments]);
|
|
618
|
-
|
|
619
|
-
[index_default.
|
|
626
|
+
useSayrSSE(eventsUrl, {
|
|
627
|
+
[index_default.EVENTS.UPDATE_TASK_COMMENTS]: fetchComments
|
|
620
628
|
});
|
|
621
629
|
return {
|
|
622
630
|
comments,
|
|
@@ -629,7 +637,7 @@ function useComments(slug, shortId, wsUrl) {
|
|
|
629
637
|
0 && (module.exports = {
|
|
630
638
|
useComments,
|
|
631
639
|
useOrg,
|
|
632
|
-
|
|
640
|
+
useSayrSSE,
|
|
633
641
|
useTask,
|
|
634
642
|
useTasks
|
|
635
643
|
});
|
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, 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"]}
|
|
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/events/index.ts","../../src/events/types.ts","../../src/index.ts","../../src/react/useTasks.ts","../../src/react/useSayrSSE.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 { useSayrSSE } from \"./useSayrSSE\";\r\n// export { 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, TaskPriority, TaskStatus } from \"../../../types\";\r\n\r\nexport interface TaskCreated {\r\n id: string;\r\n shortId: number;\r\n title: string;\r\n orgSlug: string;\r\n publicPortalUrl: string;\r\n}\r\n\r\nexport interface CreateTaskInput {\r\n title: string;\r\n description?: string;\r\n status?: TaskStatus;\r\n priority?: TaskPriority;\r\n category?: string;\r\n orgId: string;\r\n integration?: {\r\n id: string;\r\n name: string;\r\n platform: string;\r\n };\r\n}\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\r\n async createTask(\r\n body: CreateTaskInput,\r\n opts?: RequestOptions,\r\n ): Promise<ApiResult<TaskCreated>> {\r\n try {\r\n const r = await request<ApiSuccess<TaskCreated>>(\"/v1/me/task\", {\r\n ...opts,\r\n method: \"POST\",\r\n body: body as any,\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 create task\",\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;","import { type ServerEventMessage, type ServerEventMessageType } from \"./types\";\r\n\r\ntype Handlers = Partial<\r\n Record<ServerEventMessageType, (data: any, msg: ServerEventMessage) => void>\r\n>;\r\n\r\nexport function sse(url: string, handlers: Handlers = {}) {\r\n if (!url) {\r\n throw new Error(\r\n \"[Sayr.sse] SSE URL is required. Did you forget to pass org.eventsUrl?\"\r\n );\r\n }\r\n\r\n let source: EventSource | null = null;\r\n let closed = false;\r\n\r\n function connect() {\r\n if (closed) return;\r\n\r\n source = new EventSource(url);\r\n\r\n source.onmessage = (e) => {\r\n const msg = JSON.parse(e.data) as ServerEventMessage;\r\n handlers[msg.type]?.(msg.data, msg);\r\n };\r\n\r\n source.onerror = () => {\r\n if (closed) return;\r\n source?.close();\r\n setTimeout(connect, 2000); // simple retry\r\n };\r\n }\r\n\r\n connect();\r\n\r\n return {\r\n close() {\r\n closed = true;\r\n source?.close();\r\n }\r\n };\r\n}","export type ServerEventMessageType =\r\n | \"CONNECTION_STATUS\"\r\n | \"ERROR\"\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\r\n/**\r\n * String enum replacement for WS event names.\r\n * Use this instead of raw strings.\r\n */\r\nexport const ServerEvent_EVENTS: Record<ServerEventMessageType, ServerEventMessageType> = {\r\n CONNECTION_STATUS: \"CONNECTION_STATUS\",\r\n ERROR: \"ERROR\",\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};\r\n\r\nexport interface ServerEventMessage<T = unknown> {\r\n type: ServerEventMessageType;\r\n scope: \"PUBLIC\";\r\n data: T;\r\n meta?: { ts: number };\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\nimport { sse } from \"./events\";\r\nimport { ServerEvent_EVENTS } from \"./events/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 SayrSSE = sse;\r\n\r\n/**\r\n * Typed WebSocket event constants.\r\n */\r\nexport const SayrServerEvents = ServerEvent_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 sse: typeof sse;\r\n\r\n /**\r\n * WebSocket event constants.\r\n */\r\n EVENTS: typeof ServerEvent_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 sse,\r\n EVENTS: ServerEvent_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\n// export * from \"./ws/types\";\r\nexport * from \"./events/types\";","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { Task } from \"../types\";\r\nimport { useSayrSSE } from \"./useSayrSSE\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useTasks(slug?: string, eventsUrl?: string) {\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 // SSE instead of WebSockets\r\n useSayrSSE(eventsUrl, {\r\n [Sayr.EVENTS.CREATE_TASK]: fetchTasks,\r\n [Sayr.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 { ServerEventMessageType } from \"../events/types\";\r\nimport { sse } from \"../events\";\r\nimport type { ServerEventMessage } from \"../events/types\";\r\n\r\ntype Handler = (data: any, msg: ServerEventMessage) => void;\r\n\r\ntype Handlers = Partial<Record<ServerEventMessageType, Handler>>;\r\n\r\nexport function useSayrSSE(eventsUrl?: string, handlers?: Handlers) {\r\n const connRef = useRef<ReturnType<typeof sse> | null>(null);\r\n const handlersRef = useRef<Handlers | undefined>(handlers);\r\n\r\n // keep latest handlers\r\n useEffect(() => {\r\n handlersRef.current = handlers;\r\n }, [handlers]);\r\n\r\n useEffect(() => {\r\n if (!eventsUrl) return;\r\n\r\n // proxy: stable keys, dynamic handler resolution\r\n const proxyHandlers: Handlers = new Proxy(\r\n {},\r\n {\r\n get: (_, type: string) => {\r\n return (data: any, msg: ServerEventMessage) => {\r\n const handler =\r\n handlersRef.current?.[type as ServerEventMessageType];\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 = sse(eventsUrl, proxyHandlers);\r\n\r\n return () => {\r\n connRef.current?.close();\r\n connRef.current = null;\r\n };\r\n }, [eventsUrl]);\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 { useSayrSSE } from \"./useSayrSSE\";\r\nimport Sayr from \"..\";\r\n\r\nexport function useComments(\r\n slug?: string,\r\n shortId?: number,\r\n eventsUrl?: 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(slug, shortId);\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 // SSE instead of WebSockets\r\n useSayrSSE(eventsUrl, {\r\n [Sayr.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"]}
|
package/dist/react/index.d.cts
CHANGED
|
@@ -23,7 +23,7 @@ interface Organization {
|
|
|
23
23
|
createdAt: string;
|
|
24
24
|
updatedAt: string;
|
|
25
25
|
members: OrganizationMember[];
|
|
26
|
-
|
|
26
|
+
eventsUrl: string;
|
|
27
27
|
}
|
|
28
28
|
type TaskStatus = "backlog" | "todo" | "in-progress" | "done" | "canceled";
|
|
29
29
|
type TaskPriority = "none" | "low" | "medium" | "high" | "urgent";
|
|
@@ -69,9 +69,9 @@ interface Comment {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
type
|
|
73
|
-
interface
|
|
74
|
-
type:
|
|
72
|
+
type ServerEventMessageType = "CONNECTION_STATUS" | "ERROR" | "UPDATE_ORG" | "CREATE_TASK" | "UPDATE_TASK" | "UPDATE_TASK_COMMENTS" | "UPDATE_TASK_VOTE" | "UPDATE_LABELS" | "UPDATE_VIEWS" | "UPDATE_CATEGORIES" | "UPDATE_ISSUE_TEMPLATES";
|
|
73
|
+
interface ServerEventMessage<T = unknown> {
|
|
74
|
+
type: ServerEventMessageType;
|
|
75
75
|
scope: "PUBLIC";
|
|
76
76
|
data: T;
|
|
77
77
|
meta?: {
|
|
@@ -85,7 +85,7 @@ declare function useOrg(slug?: string): {
|
|
|
85
85
|
error: string | null;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
declare function useTasks(slug?: string,
|
|
88
|
+
declare function useTasks(slug?: string, eventsUrl?: string): {
|
|
89
89
|
tasks: Task[];
|
|
90
90
|
loading: boolean;
|
|
91
91
|
error: string | null;
|
|
@@ -98,17 +98,17 @@ declare function useTask(slug?: string, shortId?: number): {
|
|
|
98
98
|
error: string | null;
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
declare function useComments(slug?: string, shortId?: number,
|
|
101
|
+
declare function useComments(slug?: string, shortId?: number, eventsUrl?: string): {
|
|
102
102
|
comments: Comment[];
|
|
103
103
|
loading: boolean;
|
|
104
104
|
error: string | null;
|
|
105
105
|
refetch: () => Promise<void>;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
type Handler = (data: any, msg:
|
|
109
|
-
type Handlers = Partial<Record<
|
|
110
|
-
declare function
|
|
108
|
+
type Handler = (data: any, msg: ServerEventMessage) => void;
|
|
109
|
+
type Handlers = Partial<Record<ServerEventMessageType, Handler>>;
|
|
110
|
+
declare function useSayrSSE(eventsUrl?: string, handlers?: Handlers): react.MutableRefObject<{
|
|
111
111
|
close(): void;
|
|
112
112
|
} | null>;
|
|
113
113
|
|
|
114
|
-
export { useComments, useOrg,
|
|
114
|
+
export { useComments, useOrg, useSayrSSE, useTask, useTasks };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ interface Organization {
|
|
|
23
23
|
createdAt: string;
|
|
24
24
|
updatedAt: string;
|
|
25
25
|
members: OrganizationMember[];
|
|
26
|
-
|
|
26
|
+
eventsUrl: string;
|
|
27
27
|
}
|
|
28
28
|
type TaskStatus = "backlog" | "todo" | "in-progress" | "done" | "canceled";
|
|
29
29
|
type TaskPriority = "none" | "low" | "medium" | "high" | "urgent";
|
|
@@ -69,9 +69,9 @@ interface Comment {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
type
|
|
73
|
-
interface
|
|
74
|
-
type:
|
|
72
|
+
type ServerEventMessageType = "CONNECTION_STATUS" | "ERROR" | "UPDATE_ORG" | "CREATE_TASK" | "UPDATE_TASK" | "UPDATE_TASK_COMMENTS" | "UPDATE_TASK_VOTE" | "UPDATE_LABELS" | "UPDATE_VIEWS" | "UPDATE_CATEGORIES" | "UPDATE_ISSUE_TEMPLATES";
|
|
73
|
+
interface ServerEventMessage<T = unknown> {
|
|
74
|
+
type: ServerEventMessageType;
|
|
75
75
|
scope: "PUBLIC";
|
|
76
76
|
data: T;
|
|
77
77
|
meta?: {
|
|
@@ -85,7 +85,7 @@ declare function useOrg(slug?: string): {
|
|
|
85
85
|
error: string | null;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
declare function useTasks(slug?: string,
|
|
88
|
+
declare function useTasks(slug?: string, eventsUrl?: string): {
|
|
89
89
|
tasks: Task[];
|
|
90
90
|
loading: boolean;
|
|
91
91
|
error: string | null;
|
|
@@ -98,17 +98,17 @@ declare function useTask(slug?: string, shortId?: number): {
|
|
|
98
98
|
error: string | null;
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
declare function useComments(slug?: string, shortId?: number,
|
|
101
|
+
declare function useComments(slug?: string, shortId?: number, eventsUrl?: string): {
|
|
102
102
|
comments: Comment[];
|
|
103
103
|
loading: boolean;
|
|
104
104
|
error: string | null;
|
|
105
105
|
refetch: () => Promise<void>;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
type Handler = (data: any, msg:
|
|
109
|
-
type Handlers = Partial<Record<
|
|
110
|
-
declare function
|
|
108
|
+
type Handler = (data: any, msg: ServerEventMessage) => void;
|
|
109
|
+
type Handlers = Partial<Record<ServerEventMessageType, Handler>>;
|
|
110
|
+
declare function useSayrSSE(eventsUrl?: string, handlers?: Handlers): react.MutableRefObject<{
|
|
111
111
|
close(): void;
|
|
112
112
|
} | null>;
|
|
113
113
|
|
|
114
|
-
export { useComments, useOrg,
|
|
114
|
+
export { useComments, useOrg, useSayrSSE, useTask, useTasks };
|