gitxp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/assets/index-BGHvBNtP.js +11 -0
  3. package/.output/public/assets/routes-DuE8S6pX.js +60 -0
  4. package/.output/public/assets/styles-D5xbQNYu.css +1 -0
  5. package/.output/server/_chunks/ssr-renderer.mjs +26 -0
  6. package/.output/server/_libs/@floating-ui/core+[...].mjs +671 -0
  7. package/.output/server/_libs/@floating-ui/dom+[...].mjs +649 -0
  8. package/.output/server/_libs/@floating-ui/react-dom+[...].mjs +856 -0
  9. package/.output/server/_libs/@radix-ui/react-arrow+[...].mjs +258 -0
  10. package/.output/server/_libs/@radix-ui/react-dialog+[...].mjs +1862 -0
  11. package/.output/server/_libs/@radix-ui/react-popper+[...].mjs +320 -0
  12. package/.output/server/_libs/@radix-ui/react-tooltip+[...].mjs +534 -0
  13. package/.output/server/_libs/@tanstack/db+[...].mjs +14680 -0
  14. package/.output/server/_libs/@tanstack/react-router+[...].mjs +14563 -0
  15. package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +126 -0
  16. package/.output/server/_libs/@tanstack/router-core+[...].mjs +3636 -0
  17. package/.output/server/_libs/class-variance-authority+clsx.mjs +69 -0
  18. package/.output/server/_libs/cmdk.mjs +504 -0
  19. package/.output/server/_libs/h3+rou3+srvx.mjs +1361 -0
  20. package/.output/server/_libs/h3-v2.mjs +285 -0
  21. package/.output/server/_libs/lucide-react.mjs +158 -0
  22. package/.output/server/_libs/radix-ui__primitive.mjs +44 -0
  23. package/.output/server/_libs/radix-ui__react-context.mjs +108 -0
  24. package/.output/server/_libs/tailwind-merge.mjs +3380 -0
  25. package/.output/server/_libs/tanstack__history.mjs +384 -0
  26. package/.output/server/_libs/tanstack__query-core.mjs +2225 -0
  27. package/.output/server/_libs/tanstack__react-db.mjs +242 -0
  28. package/.output/server/_libs/tanstack__react-query.mjs +140 -0
  29. package/.output/server/_libs/ufo.mjs +64 -0
  30. package/.output/server/_runtime.mjs +35 -0
  31. package/.output/server/_ssr/empty-plugin-adapters-D9UWiqvJ.mjs +5 -0
  32. package/.output/server/_ssr/events-BNrmOvgU.mjs +13 -0
  33. package/.output/server/_ssr/notifications-DUoENv6E.mjs +514 -0
  34. package/.output/server/_ssr/router-DsUHD4bT.mjs +179 -0
  35. package/.output/server/_ssr/routes-DIFfr242.mjs +982 -0
  36. package/.output/server/_ssr/ssr.mjs +1854 -0
  37. package/.output/server/_ssr/start-5Z2QO8AU.mjs +4 -0
  38. package/.output/server/_tanstack-start-manifest_v-CrD0YpZr.mjs +20 -0
  39. package/.output/server/index.mjs +310 -0
  40. package/.output/server/node_modules/tslib/modules/index.js +70 -0
  41. package/.output/server/node_modules/tslib/modules/package.json +3 -0
  42. package/.output/server/node_modules/tslib/package.json +47 -0
  43. package/.output/server/node_modules/tslib/tslib.js +484 -0
  44. package/.output/server/package.json +9 -0
  45. package/LICENSE +21 -0
  46. package/README.md +325 -0
  47. package/bin/gitxp.js +85 -0
  48. package/package.json +92 -0
@@ -0,0 +1,514 @@
1
+ import { n as TSS_SERVER_FUNCTION, t as createServerFn } from "./ssr.mjs";
2
+ import { t as emitChange } from "./events-BNrmOvgU.mjs";
3
+ import { mkdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { homedir } from "node:os";
6
+ import { DatabaseSync } from "node:sqlite";
7
+ import { execFile } from "node:child_process";
8
+ import { promisify } from "node:util";
9
+ //#region node_modules/.nitro/vite/services/ssr/assets/notifications-DUoENv6E.js
10
+ var createServerRpc = (serverFnMeta, splitImportFn) => {
11
+ const url = "/_serverFn/" + serverFnMeta.id;
12
+ return Object.assign(splitImportFn, {
13
+ url,
14
+ serverFnMeta,
15
+ [TSS_SERVER_FUNCTION]: true
16
+ });
17
+ };
18
+ var migrations = [{
19
+ id: 1,
20
+ up: (db) => {
21
+ db.exec(`
22
+ CREATE TABLE settings (
23
+ key TEXT PRIMARY KEY,
24
+ value TEXT NOT NULL
25
+ ) STRICT;
26
+
27
+ CREATE TABLE mutation_queue (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ kind TEXT NOT NULL,
30
+ payload TEXT NOT NULL,
31
+ status TEXT NOT NULL DEFAULT 'pending',
32
+ attempts INTEGER NOT NULL DEFAULT 0,
33
+ last_error TEXT,
34
+ created_at TEXT NOT NULL,
35
+ updated_at TEXT NOT NULL
36
+ ) STRICT;
37
+
38
+ CREATE INDEX mutation_queue_pending ON mutation_queue (status, id);
39
+
40
+ CREATE TABLE sync_state (
41
+ resource TEXT PRIMARY KEY,
42
+ etag TEXT,
43
+ last_modified TEXT,
44
+ poll_interval INTEGER,
45
+ last_polled_at TEXT,
46
+ last_status INTEGER
47
+ ) STRICT;
48
+
49
+ CREATE TABLE notifications (
50
+ thread_id TEXT PRIMARY KEY,
51
+ raw TEXT NOT NULL,
52
+ reason TEXT NOT NULL,
53
+ unread INTEGER NOT NULL,
54
+ updated_at TEXT NOT NULL,
55
+ last_read_at TEXT,
56
+ subject_title TEXT NOT NULL,
57
+ subject_type TEXT NOT NULL,
58
+ subject_url TEXT,
59
+ repo_full_name TEXT NOT NULL
60
+ ) STRICT;
61
+
62
+ CREATE INDEX notifications_recent ON notifications (updated_at DESC);
63
+ `);
64
+ }
65
+ }, {
66
+ id: 2,
67
+ up: (db) => {
68
+ db.exec("ALTER TABLE sync_state ADD COLUMN request_url TEXT");
69
+ }
70
+ }];
71
+ function migrate(db) {
72
+ for (const migration of migrations) {
73
+ if (migration.id <= readVersion(db)) continue;
74
+ db.exec("BEGIN");
75
+ try {
76
+ migration.up(db);
77
+ db.exec(`PRAGMA user_version = ${migration.id}`);
78
+ db.exec("COMMIT");
79
+ } catch (error) {
80
+ db.exec("ROLLBACK");
81
+ throw error;
82
+ }
83
+ }
84
+ }
85
+ function readVersion(db) {
86
+ return db.prepare("PRAGMA user_version").get().user_version;
87
+ }
88
+ var handle;
89
+ function gitxpHome() {
90
+ return process.env.GITXP_HOME ?? join(homedir(), ".gitxp");
91
+ }
92
+ function getDb() {
93
+ if (handle) return handle;
94
+ const home = gitxpHome();
95
+ mkdirSync(home, { recursive: true });
96
+ const db = new DatabaseSync(join(home, "gitxp.db"));
97
+ db.exec("PRAGMA journal_mode = WAL");
98
+ db.exec("PRAGMA foreign_keys = ON");
99
+ db.exec("PRAGMA busy_timeout = 5000");
100
+ migrate(db);
101
+ handle = db;
102
+ return handle;
103
+ }
104
+ var upsert = `
105
+ INSERT INTO notifications (
106
+ thread_id, raw, reason, unread, updated_at, last_read_at,
107
+ subject_title, subject_type, subject_url, repo_full_name
108
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
109
+ ON CONFLICT (thread_id) DO UPDATE SET
110
+ raw = excluded.raw,
111
+ reason = excluded.reason,
112
+ unread = excluded.unread,
113
+ updated_at = excluded.updated_at,
114
+ last_read_at = excluded.last_read_at,
115
+ subject_title = excluded.subject_title,
116
+ subject_type = excluded.subject_type,
117
+ subject_url = excluded.subject_url,
118
+ repo_full_name = excluded.repo_full_name
119
+ `;
120
+ function upsertNotifications(threads) {
121
+ if (threads.length === 0) return [];
122
+ const db = getDb();
123
+ const statement = db.prepare(upsert);
124
+ const seen = [];
125
+ db.exec("BEGIN");
126
+ try {
127
+ for (const thread of threads) {
128
+ statement.run(thread.id, JSON.stringify(thread), thread.reason, thread.unread ? 1 : 0, thread.updated_at, thread.last_read_at, thread.subject.title, thread.subject.type, thread.subject.url, thread.repository.full_name);
129
+ seen.push(thread.id);
130
+ }
131
+ db.exec("COMMIT");
132
+ } catch (error) {
133
+ db.exec("ROLLBACK");
134
+ throw error;
135
+ }
136
+ return seen;
137
+ }
138
+ function listNotifications() {
139
+ return getDb().prepare(`SELECT thread_id, reason, unread, updated_at, last_read_at,
140
+ subject_title, subject_type, subject_url, repo_full_name
141
+ FROM notifications
142
+ ORDER BY updated_at DESC`).all();
143
+ }
144
+ function newestUpdatedAt() {
145
+ return getDb().prepare("SELECT max(updated_at) AS newest FROM notifications").get().newest;
146
+ }
147
+ function setNotificationRead(threadId) {
148
+ getDb().prepare(`UPDATE notifications SET unread = 0, last_read_at = ? WHERE thread_id = ?`).run((/* @__PURE__ */ new Date()).toISOString(), threadId);
149
+ }
150
+ function deleteNotification(threadId) {
151
+ getDb().prepare("DELETE FROM notifications WHERE thread_id = ?").run(threadId);
152
+ }
153
+ function readSyncState(resource) {
154
+ return getDb().prepare("SELECT * FROM sync_state WHERE resource = ?").get(resource);
155
+ }
156
+ function writeSyncState(state) {
157
+ getDb().prepare(`INSERT INTO sync_state
158
+ (resource, etag, last_modified, poll_interval, last_polled_at,
159
+ last_status, request_url)
160
+ VALUES (?, ?, ?, ?, ?, ?, ?)
161
+ ON CONFLICT (resource) DO UPDATE SET
162
+ etag = coalesce(excluded.etag, sync_state.etag),
163
+ last_modified = coalesce(excluded.last_modified, sync_state.last_modified),
164
+ poll_interval = coalesce(excluded.poll_interval, sync_state.poll_interval),
165
+ last_polled_at = excluded.last_polled_at,
166
+ last_status = excluded.last_status,
167
+ request_url = excluded.request_url`).run(state.resource, state.etag ?? null, state.lastModified ?? null, state.pollInterval ?? null, (/* @__PURE__ */ new Date()).toISOString(), state.status, state.requestUrl);
168
+ }
169
+ var run = promisify(execFile);
170
+ var pending;
171
+ function getAuth() {
172
+ if (!pending) pending = readAuth().catch((error) => {
173
+ pending = void 0;
174
+ throw error;
175
+ });
176
+ return pending;
177
+ }
178
+ function forgetAuth() {
179
+ pending = void 0;
180
+ }
181
+ async function readAuth() {
182
+ const host = await readActiveHost();
183
+ const { stdout } = await run("gh", [
184
+ "auth",
185
+ "token",
186
+ "--hostname",
187
+ host
188
+ ]);
189
+ const token = stdout.trim();
190
+ if (!token) throw new Error(`gh returned no token for ${host}. Run \`gh auth login\`.`);
191
+ return {
192
+ host,
193
+ token,
194
+ apiBase: apiBaseFor(host)
195
+ };
196
+ }
197
+ async function readActiveHost() {
198
+ if (process.env.GH_HOST) return process.env.GH_HOST;
199
+ const { stdout } = await run("gh", [
200
+ "auth",
201
+ "status",
202
+ "--json",
203
+ "hosts"
204
+ ]);
205
+ const hosts = JSON.parse(stdout).hosts;
206
+ const active = Object.entries(hosts).find(([, accounts]) => accounts.some((account) => account.active));
207
+ if (!active) throw new Error("gh has no active account. Run `gh auth login`.");
208
+ return active[0];
209
+ }
210
+ function apiBaseFor(host) {
211
+ return host === "github.com" ? "https://api.github.com" : `https://${host}/api/v3`;
212
+ }
213
+ var apiVersion = "2022-11-28";
214
+ var GithubError = class extends Error {
215
+ path;
216
+ status;
217
+ body;
218
+ constructor(path, status, body) {
219
+ super(`GitHub responded ${status} for ${path}`);
220
+ this.name = "GithubError";
221
+ this.path = path;
222
+ this.status = status;
223
+ this.body = body;
224
+ }
225
+ };
226
+ async function githubRequest(path, options = {}) {
227
+ let response = await send(path, options);
228
+ if (response.status === 401) {
229
+ forgetAuth();
230
+ response = await send(path, options);
231
+ }
232
+ recordRateLimit(response);
233
+ if (response.status === 304) return {
234
+ status: 304,
235
+ notModified: true,
236
+ data: void 0,
237
+ ...cacheHeaders(response)
238
+ };
239
+ if (!response.ok) throw new GithubError(path, response.status, await response.text());
240
+ return {
241
+ status: response.status,
242
+ notModified: false,
243
+ data: hasBody(response) ? await response.json() : void 0,
244
+ ...cacheHeaders(response)
245
+ };
246
+ }
247
+ async function send(path, options) {
248
+ const auth = await getAuth();
249
+ const headers = {
250
+ accept: "application/vnd.github+json",
251
+ authorization: `Bearer ${auth.token}`,
252
+ "user-agent": "gitxp",
253
+ "x-github-api-version": apiVersion,
254
+ ...options.headers
255
+ };
256
+ if (options.etag) headers["if-none-match"] = options.etag;
257
+ if (options.lastModified) headers["if-modified-since"] = options.lastModified;
258
+ if (options.body !== void 0) headers["content-type"] = "application/json";
259
+ return fetch(resolve$1(auth.apiBase, path), {
260
+ method: options.method ?? "GET",
261
+ headers,
262
+ body: options.body === void 0 ? void 0 : JSON.stringify(options.body)
263
+ });
264
+ }
265
+ function resolve$1(apiBase, path) {
266
+ if (path.startsWith("https://")) return path;
267
+ return `${apiBase.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
268
+ }
269
+ function hasBody(response) {
270
+ if (response.status === 204 || response.status === 205) return false;
271
+ return response.headers.get("content-length") !== "0";
272
+ }
273
+ function cacheHeaders(response) {
274
+ const pollInterval = response.headers.get("x-poll-interval");
275
+ return {
276
+ etag: response.headers.get("etag") ?? void 0,
277
+ lastModified: response.headers.get("last-modified") ?? void 0,
278
+ pollInterval: pollInterval === null ? void 0 : Number(pollInterval),
279
+ nextPage: nextPageFrom(response.headers.get("link"))
280
+ };
281
+ }
282
+ function nextPageFrom(link) {
283
+ if (link === null) return void 0;
284
+ return /<([^>]+)>;\s*rel="next"/.exec(link)?.[1];
285
+ }
286
+ function recordRateLimit(response) {
287
+ const limit = response.headers.get("x-ratelimit-limit");
288
+ if (limit === null) return;
289
+ Number(limit), Number(response.headers.get("x-ratelimit-remaining")), Number(response.headers.get("x-ratelimit-used")), Number(response.headers.get("x-ratelimit-reset")), response.headers.get("x-ratelimit-resource");
290
+ }
291
+ var resource = "notifications";
292
+ var maxPages = 10;
293
+ async function syncNotifications() {
294
+ const state = readSyncState(resource);
295
+ const since = newestUpdatedAt();
296
+ const url = pathFor(since);
297
+ const first = await githubRequest(url, { etag: state?.request_url === url ? state.etag : void 0 });
298
+ writeSyncState({
299
+ resource,
300
+ etag: first.etag,
301
+ lastModified: first.lastModified,
302
+ pollInterval: first.pollInterval,
303
+ status: first.status,
304
+ requestUrl: url
305
+ });
306
+ if (first.notModified) return {
307
+ notModified: true,
308
+ written: 0,
309
+ pages: 0,
310
+ truncated: false,
311
+ incremental: since !== null,
312
+ pollInterval: first.pollInterval ?? state?.poll_interval ?? void 0
313
+ };
314
+ let written = upsertNotifications(first.data ?? []).length;
315
+ let next = first.nextPage;
316
+ let pages = 1;
317
+ while (next !== void 0 && pages < maxPages) {
318
+ const page = await githubRequest(next);
319
+ written += upsertNotifications(page.data ?? []).length;
320
+ next = page.nextPage;
321
+ pages += 1;
322
+ }
323
+ if (written > 0) emitChange(resource);
324
+ return {
325
+ notModified: false,
326
+ written,
327
+ pages,
328
+ truncated: next !== void 0,
329
+ incremental: since !== null,
330
+ pollInterval: first.pollInterval
331
+ };
332
+ }
333
+ function pathFor(since) {
334
+ const params = new URLSearchParams({
335
+ all: "true",
336
+ per_page: "50"
337
+ });
338
+ if (since !== null) params.set("since", since);
339
+ return `/notifications?${params.toString()}`;
340
+ }
341
+ function enqueueMutation(kind, payload) {
342
+ const now = (/* @__PURE__ */ new Date()).toISOString();
343
+ const result = getDb().prepare(`INSERT INTO mutation_queue (kind, payload, status, attempts, created_at, updated_at)
344
+ VALUES (?, ?, 'pending', 0, ?, ?)`).run(kind, JSON.stringify(payload), now, now);
345
+ return Number(result.lastInsertRowid);
346
+ }
347
+ function pendingMutations(limit = 50) {
348
+ return getDb().prepare(`SELECT * FROM mutation_queue WHERE status = 'pending' ORDER BY id LIMIT ?`).all(limit);
349
+ }
350
+ function failedMutations() {
351
+ return getDb().prepare(`SELECT * FROM mutation_queue WHERE status = 'failed' ORDER BY id`).all();
352
+ }
353
+ function completeMutation(id) {
354
+ getDb().prepare(`UPDATE mutation_queue SET status = 'done', updated_at = ? WHERE id = ?`).run((/* @__PURE__ */ new Date()).toISOString(), id);
355
+ }
356
+ function failMutation(id, message) {
357
+ getDb().prepare(`UPDATE mutation_queue
358
+ SET status = 'failed', attempts = attempts + 1, last_error = ?, updated_at = ?
359
+ WHERE id = ?`).run(message, (/* @__PURE__ */ new Date()).toISOString(), id);
360
+ }
361
+ function retryMutation(id) {
362
+ getDb().prepare(`UPDATE mutation_queue SET status = 'pending', last_error = NULL, updated_at = ?
363
+ WHERE id = ? AND status = 'failed'`).run((/* @__PURE__ */ new Date()).toISOString(), id);
364
+ }
365
+ var handlers = {
366
+ "notification.done": async ({ threadId }) => {
367
+ await githubRequest(`/notifications/threads/${threadId}`, { method: "DELETE" });
368
+ },
369
+ "notification.read": async ({ threadId }) => {
370
+ await githubRequest(`/notifications/threads/${threadId}`, { method: "PATCH" });
371
+ }
372
+ };
373
+ async function runMutation(kind, payload) {
374
+ const id = enqueueMutation(kind, payload);
375
+ try {
376
+ await handlers[kind](payload);
377
+ completeMutation(id);
378
+ } catch (error) {
379
+ failMutation(id, error instanceof Error ? error.message : String(error));
380
+ throw error;
381
+ }
382
+ }
383
+ async function drainPendingMutations() {
384
+ const rows = pendingMutations();
385
+ if (rows.length === 0) return 0;
386
+ let applied = 0;
387
+ for (const row of rows) if (await applyRow(row)) applied += 1;
388
+ if (applied > 0) emitChange("notifications");
389
+ return applied;
390
+ }
391
+ async function applyRow(row) {
392
+ try {
393
+ await handlers[row.kind](JSON.parse(row.payload));
394
+ completeMutation(row.id);
395
+ return true;
396
+ } catch (error) {
397
+ failMutation(row.id, error instanceof Error ? error.message : String(error));
398
+ return false;
399
+ }
400
+ }
401
+ var jobs = [{
402
+ resource: "notifications",
403
+ defaultInterval: 60,
404
+ run: syncNotifications
405
+ }];
406
+ var timers = /* @__PURE__ */ new Map();
407
+ var failures = /* @__PURE__ */ new Map();
408
+ var running = false;
409
+ function startSync() {
410
+ if (running) return;
411
+ running = true;
412
+ drainPendingMutations().catch((error) => {
413
+ console.error("could not drain pending mutations", error);
414
+ });
415
+ for (const job of jobs) schedule(job, 0);
416
+ }
417
+ function schedule(job, delayMs) {
418
+ if (!running) return;
419
+ const timer = setTimeout(() => {
420
+ tick(job);
421
+ }, delayMs);
422
+ timer.unref();
423
+ timers.set(job.resource, timer);
424
+ }
425
+ async function tick(job) {
426
+ try {
427
+ const result = await job.run();
428
+ failures.delete(job.resource);
429
+ schedule(job, (result.pollInterval ?? job.defaultInterval) * 1e3);
430
+ } catch (error) {
431
+ const attempts = (failures.get(job.resource) ?? 0) + 1;
432
+ failures.set(job.resource, attempts);
433
+ console.error(`sync failed for ${job.resource} (attempt ${attempts})`, error);
434
+ schedule(job, backoff(attempts));
435
+ }
436
+ }
437
+ function backoff(attempts) {
438
+ return Math.min(2 ** attempts * 1e3, 3e5);
439
+ }
440
+ var getNotifications_createServerFn_handler = createServerRpc({
441
+ id: "5cfec4c6dee804d3573d611211f1ac5f56628842c036a21f55c9ae92c73dfff0",
442
+ name: "getNotifications",
443
+ filename: "src/functions/notifications.ts"
444
+ }, (opts) => getNotifications.__executeServer(opts));
445
+ var getNotifications = createServerFn({ method: "GET" }).handler(getNotifications_createServerFn_handler, async () => {
446
+ startSync();
447
+ return listNotifications();
448
+ });
449
+ var syncNow_createServerFn_handler = createServerRpc({
450
+ id: "0babd28c77cb1e09ec4d58a288fb1a4e4ea676ad4fb655c65b2949da4de21e51",
451
+ name: "syncNow",
452
+ filename: "src/functions/notifications.ts"
453
+ }, (opts) => syncNow.__executeServer(opts));
454
+ var syncNow = createServerFn({ method: "POST" }).handler(syncNow_createServerFn_handler, async () => {
455
+ return syncNotifications();
456
+ });
457
+ var getSyncStatus_createServerFn_handler = createServerRpc({
458
+ id: "c037beb8cda5c53572baa3bcea8e77650282ca11237e45b8703f106284575801",
459
+ name: "getSyncStatus",
460
+ filename: "src/functions/notifications.ts"
461
+ }, (opts) => getSyncStatus.__executeServer(opts));
462
+ var getSyncStatus = createServerFn({ method: "GET" }).handler(getSyncStatus_createServerFn_handler, async () => {
463
+ const state = readSyncState("notifications");
464
+ return {
465
+ hasSynced: state?.last_polled_at != null,
466
+ lastPolledAt: state?.last_polled_at ?? null,
467
+ lastStatus: state?.last_status ?? null
468
+ };
469
+ });
470
+ var markNotificationDone_createServerFn_handler = createServerRpc({
471
+ id: "9c3c7c75152987d0c0eb6e93398f5ac49bc91adf254a6cb7e7582da1ab9c7b69",
472
+ name: "markNotificationDone",
473
+ filename: "src/functions/notifications.ts"
474
+ }, (opts) => markNotificationDone.__executeServer(opts));
475
+ var markNotificationDone = createServerFn({ method: "POST" }).validator((threadId) => threadId).handler(markNotificationDone_createServerFn_handler, async ({ data }) => {
476
+ await runMutation("notification.done", { threadId: data });
477
+ deleteNotification(data);
478
+ emitChange("notifications");
479
+ });
480
+ var markNotificationRead_createServerFn_handler = createServerRpc({
481
+ id: "ec7cb03fde2349fdcee3000ccfc2f527248df2b7c89c3db9ad0c3ce452363f15",
482
+ name: "markNotificationRead",
483
+ filename: "src/functions/notifications.ts"
484
+ }, (opts) => markNotificationRead.__executeServer(opts));
485
+ var markNotificationRead = createServerFn({ method: "POST" }).validator((threadId) => threadId).handler(markNotificationRead_createServerFn_handler, async ({ data }) => {
486
+ await runMutation("notification.read", { threadId: data });
487
+ setNotificationRead(data);
488
+ emitChange("notifications");
489
+ });
490
+ var getFailedMutations_createServerFn_handler = createServerRpc({
491
+ id: "2360b4abbe0e8d19207ee28b76c335507d4577387d16ff7c5e69d2d1ccf2900b",
492
+ name: "getFailedMutations",
493
+ filename: "src/functions/notifications.ts"
494
+ }, (opts) => getFailedMutations.__executeServer(opts));
495
+ var getFailedMutations = createServerFn({ method: "GET" }).handler(getFailedMutations_createServerFn_handler, async () => {
496
+ return failedMutations().map((row) => ({
497
+ id: row.id,
498
+ kind: row.kind,
499
+ attempts: row.attempts,
500
+ lastError: row.last_error,
501
+ updatedAt: row.updated_at
502
+ }));
503
+ });
504
+ var retryFailedMutations_createServerFn_handler = createServerRpc({
505
+ id: "6e5e9052f4c44bc48d2cacaa624ebc266d94ad8c4f5211de50e7760446323376",
506
+ name: "retryFailedMutations",
507
+ filename: "src/functions/notifications.ts"
508
+ }, (opts) => retryFailedMutations.__executeServer(opts));
509
+ var retryFailedMutations = createServerFn({ method: "POST" }).handler(retryFailedMutations_createServerFn_handler, async () => {
510
+ for (const row of failedMutations()) retryMutation(row.id);
511
+ return drainPendingMutations();
512
+ });
513
+ //#endregion
514
+ export { getFailedMutations_createServerFn_handler, getNotifications_createServerFn_handler, getSyncStatus_createServerFn_handler, markNotificationDone_createServerFn_handler, markNotificationRead_createServerFn_handler, retryFailedMutations_createServerFn_handler, syncNow_createServerFn_handler };
@@ -0,0 +1,179 @@
1
+ import { f as createRouter, h as createRootRouteWithContext, l as Scripts, m as createFileRoute, p as lazyRouteComponent, u as HeadContent } from "../_libs/@tanstack/react-router+[...].mjs";
2
+ import { l as require_jsx_runtime } from "../_libs/@radix-ui/react-arrow+[...].mjs";
3
+ import { n as TSS_SERVER_FUNCTION, r as getServerFnById, t as createServerFn } from "./ssr.mjs";
4
+ import { n as onChange } from "./events-BNrmOvgU.mjs";
5
+ import { t as QueryClient } from "../_libs/tanstack__query-core.mjs";
6
+ import { t as setupRouterSsrQueryIntegration } from "../_libs/@tanstack/react-router-ssr-query+[...].mjs";
7
+ //#region node_modules/.nitro/vite/services/ssr/assets/router-DsUHD4bT.js
8
+ var import_jsx_runtime = require_jsx_runtime();
9
+ var __defProp = Object.defineProperty;
10
+ var __exportAll = (all, no_symbols) => {
11
+ let target = {};
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
+ return target;
18
+ };
19
+ var styles_default = "/assets/styles-D5xbQNYu.css";
20
+ var Route$2 = createRootRouteWithContext()({
21
+ head: () => ({
22
+ meta: [
23
+ { charSet: "utf-8" },
24
+ {
25
+ name: "viewport",
26
+ content: "width=device-width, initial-scale=1"
27
+ },
28
+ { title: "gitxp" }
29
+ ],
30
+ links: [{
31
+ rel: "stylesheet",
32
+ href: styles_default
33
+ }]
34
+ }),
35
+ shellComponent: RootDocument
36
+ });
37
+ function RootDocument({ children }) {
38
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("html", {
39
+ lang: "en",
40
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("head", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HeadContent, {}) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("body", { children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Scripts, {})] })]
41
+ });
42
+ }
43
+ var createSsrRpc = (functionId) => {
44
+ const url = "/_serverFn/" + functionId;
45
+ const serverFnMeta = { id: functionId };
46
+ const fn = async (...args) => {
47
+ return (await getServerFnById(functionId, { origin: "server" }))(...args);
48
+ };
49
+ return Object.assign(fn, {
50
+ url,
51
+ serverFnMeta,
52
+ [TSS_SERVER_FUNCTION]: true
53
+ });
54
+ };
55
+ var getNotifications = createServerFn({ method: "GET" }).handler(createSsrRpc("5cfec4c6dee804d3573d611211f1ac5f56628842c036a21f55c9ae92c73dfff0"));
56
+ var syncNow = createServerFn({ method: "POST" }).handler(createSsrRpc("0babd28c77cb1e09ec4d58a288fb1a4e4ea676ad4fb655c65b2949da4de21e51"));
57
+ var getSyncStatus = createServerFn({ method: "GET" }).handler(createSsrRpc("c037beb8cda5c53572baa3bcea8e77650282ca11237e45b8703f106284575801"));
58
+ var markNotificationDone = createServerFn({ method: "POST" }).validator((threadId) => threadId).handler(createSsrRpc("9c3c7c75152987d0c0eb6e93398f5ac49bc91adf254a6cb7e7582da1ab9c7b69"));
59
+ var markNotificationRead = createServerFn({ method: "POST" }).validator((threadId) => threadId).handler(createSsrRpc("ec7cb03fde2349fdcee3000ccfc2f527248df2b7c89c3db9ad0c3ce452363f15"));
60
+ var getFailedMutations = createServerFn({ method: "GET" }).handler(createSsrRpc("2360b4abbe0e8d19207ee28b76c335507d4577387d16ff7c5e69d2d1ccf2900b"));
61
+ var retryFailedMutations = createServerFn({ method: "POST" }).handler(createSsrRpc("6e5e9052f4c44bc48d2cacaa624ebc266d94ad8c4f5211de50e7760446323376"));
62
+ var viewIds = [
63
+ "inbox",
64
+ "review",
65
+ "mentions",
66
+ "yours",
67
+ "all"
68
+ ];
69
+ var views = [
70
+ {
71
+ id: "inbox",
72
+ label: "Inbox",
73
+ match: (notification) => notification.unread === 1
74
+ },
75
+ {
76
+ id: "review",
77
+ label: "Review requests",
78
+ match: (notification) => notification.unread === 1 && notification.reason === "review_requested"
79
+ },
80
+ {
81
+ id: "mentions",
82
+ label: "Mentions",
83
+ match: (notification) => notification.unread === 1 && (notification.reason === "mention" || notification.reason === "assign")
84
+ },
85
+ {
86
+ id: "yours",
87
+ label: "Yours",
88
+ match: (notification) => notification.reason === "author"
89
+ },
90
+ {
91
+ id: "all",
92
+ label: "All",
93
+ match: () => true
94
+ }
95
+ ];
96
+ function isViewId(value) {
97
+ return viewIds.includes(value);
98
+ }
99
+ function webUrlFor(notification) {
100
+ const repoUrl = `https://github.com/${notification.repo_full_name}`;
101
+ if (notification.subject_url === null) return repoUrl;
102
+ return notification.subject_url.startsWith("https://api.github.com/repos/") ? notification.subject_url.replace("https://api.github.com/repos/", "https://github.com/").replace("/pulls/", "/pull/") : repoUrl;
103
+ }
104
+ function reasonLabel(reason) {
105
+ return reason.replace(/_/g, " ");
106
+ }
107
+ var $$splitComponentImporter = () => import("./routes-DIFfr242.mjs");
108
+ var Route$1 = createFileRoute("/")({
109
+ component: lazyRouteComponent($$splitComponentImporter, "component"),
110
+ loader: () => getNotifications(),
111
+ validateSearch: (search) => ({
112
+ view: isViewId(search.view) ? search.view : "inbox",
113
+ thread: typeof search.thread === "string" ? search.thread : void 0
114
+ })
115
+ });
116
+ var heartbeatMs = 3e4;
117
+ var Route = createFileRoute("/api/events")({ server: { handlers: { GET: () => {
118
+ const encoder = new TextEncoder();
119
+ let unsubscribe;
120
+ let heartbeat;
121
+ const stream = new ReadableStream({
122
+ start(controller) {
123
+ const send = (chunk) => {
124
+ controller.enqueue(encoder.encode(chunk));
125
+ };
126
+ send(": connected\n\n");
127
+ unsubscribe = onChange((resource) => {
128
+ send(`event: change\ndata: ${JSON.stringify({ resource })}\n\n`);
129
+ });
130
+ heartbeat = setInterval(() => {
131
+ send(": ping\n\n");
132
+ }, heartbeatMs);
133
+ heartbeat.unref();
134
+ },
135
+ cancel() {
136
+ unsubscribe?.();
137
+ if (heartbeat) clearInterval(heartbeat);
138
+ }
139
+ });
140
+ return new Response(stream, { headers: {
141
+ "content-type": "text/event-stream",
142
+ "cache-control": "no-cache",
143
+ connection: "keep-alive"
144
+ } });
145
+ } } } });
146
+ var rootRouteChildren = {
147
+ IndexRoute: Route$1.update({
148
+ id: "/",
149
+ path: "/",
150
+ getParentRoute: () => Route$2
151
+ }),
152
+ ApiEventsRoute: Route.update({
153
+ id: "/api/events",
154
+ path: "/api/events",
155
+ getParentRoute: () => Route$2
156
+ })
157
+ };
158
+ var routeTree = Route$2._addFileChildren(rootRouteChildren)._addFileTypes();
159
+ function getContext() {
160
+ return { queryClient: new QueryClient() };
161
+ }
162
+ var router_exports = /* @__PURE__ */ __exportAll({ getRouter: () => getRouter });
163
+ function getRouter() {
164
+ const context = getContext();
165
+ const router = createRouter({
166
+ routeTree,
167
+ context,
168
+ scrollRestoration: true,
169
+ defaultPreload: "intent",
170
+ defaultPreloadStaleTime: 0
171
+ });
172
+ setupRouterSsrQueryIntegration({
173
+ router,
174
+ queryClient: context.queryClient
175
+ });
176
+ return router;
177
+ }
178
+ //#endregion
179
+ export { webUrlFor as a, getSyncStatus as c, retryFailedMutations as d, syncNow as f, views as i, markNotificationDone as l, Route$1 as n, getFailedMutations as o, reasonLabel as r, getNotifications as s, router_exports as t, markNotificationRead as u };