birdclaw 0.9.3 → 0.9.5

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 (72) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli/birdclaw.js +74 -22
  3. package/dist/client/assets/{AvatarChip-C8zELEVt.js → AvatarChip-DsHj3LT7.js} +1 -1
  4. package/dist/client/assets/{ProfilePreview-CsiLpFrb.js → ProfilePreview-CaaMHV2N.js} +1 -1
  5. package/dist/client/assets/{SavedTimelineView-BSnwnujP.js → SavedTimelineView-HNbc1InN.js} +1 -1
  6. package/dist/client/assets/{SmartTimestamp-BypN4KPq.js → SmartTimestamp-CXaNLqN7.js} +1 -1
  7. package/dist/client/assets/{TimelineRouteFrame-H3D4R0Xu.js → TimelineRouteFrame-DUF8ETx2.js} +1 -1
  8. package/dist/client/assets/{blocks-WsAOmHsv.js → blocks-CLV8UyL1.js} +1 -1
  9. package/dist/client/assets/{bookmarks-B2I0kAWY.js → bookmarks-f8mrhE5v.js} +1 -1
  10. package/dist/client/assets/{client-stream-contracts-D1QUdWfh.js → client-stream-contracts-CNz2FSrQ.js} +1 -1
  11. package/dist/client/assets/{data-sources-DI5W9oVq.js → data-sources-obqEq3vx.js} +1 -1
  12. package/dist/client/assets/{discuss-t2QxXK0h.js → discuss-IVQmzPlf.js} +1 -1
  13. package/dist/client/assets/{dms-DjyXURaJ.js → dms-Dz53c2A8.js} +1 -1
  14. package/dist/client/assets/{inbox-CkHVoykL.js → inbox-OtMwyDqg.js} +1 -1
  15. package/dist/client/assets/{index-BR860w88.js → index-gdLl886E.js} +3 -3
  16. package/dist/client/assets/likes-bYLP-Iur.js +1 -0
  17. package/dist/client/assets/{links-lDqy93u8.js → links-Calv868h.js} +1 -1
  18. package/dist/client/assets/{mapbox-CVPXIYUZ.js → mapbox-D8DIktls.js} +2 -2
  19. package/dist/client/assets/{mapbox-gl-DRRiLKWb.js → mapbox-gl-CL_i4VMi.js} +1 -1
  20. package/dist/client/assets/{mentions-B6BXntri.js → mentions-CceV_r9w.js} +1 -1
  21. package/dist/client/assets/{network-map-BCUtBk8G.js → network-map-7r9If3kD.js} +2 -2
  22. package/dist/client/assets/{profile-analyze-YExKd6Lx.js → profile-analyze-BeyDxO7C.js} +1 -1
  23. package/dist/client/assets/{profile-hydration-client-BQyC5--e.js → profile-hydration-client-kffyMcqf.js} +1 -1
  24. package/dist/client/assets/{profiles._handle-idhd3kYo.js → profiles._handle-BH11vR7-.js} +1 -1
  25. package/dist/client/assets/{query-client-DZ5C7UNo.js → query-client-CD880OPj.js} +1 -1
  26. package/dist/client/assets/{rate-limits-jGxIfvUD.js → rate-limits-pf5ibAYx.js} +1 -1
  27. package/dist/client/assets/{routes-6U4Cc79j.js → routes-DYUCTi0s.js} +1 -1
  28. package/dist/client/assets/{schemas-CntsNLmN.js → schemas-CMQMhQXI.js} +1 -1
  29. package/dist/client/assets/{styles-DT4Pxoi-.css → styles-DAoXpgpq.css} +1 -1
  30. package/dist/client/assets/{today-COmNSYaE.js → today-CwzttriK.js} +1 -1
  31. package/dist/client/assets/{useTimelineRouteData-BpQzU16P.js → useTimelineRouteData-BE84vgO5.js} +1 -1
  32. package/dist/server/assets/{AvatarChip-DWag3IzT.js → AvatarChip-B5ASnpQ4.js} +1 -1
  33. package/dist/server/assets/{FeedState-CwzcvP-p.js → FeedState-YrMZ10Gf.js} +1 -1
  34. package/dist/server/assets/{ProfileAnalysisStream-CLjrYzEx.js → ProfileAnalysisStream-1CHrSLNN.js} +2 -2
  35. package/dist/server/assets/{ProfilePreview-Bq-DSUM2.js → ProfilePreview-Dk2CdOOS.js} +2 -2
  36. package/dist/server/assets/{SavedTimelineView-Bk9nfnb-.js → SavedTimelineView-BGZvQIYS.js} +2 -2
  37. package/dist/server/assets/{SmartTimestamp-C06w_f9J.js → SmartTimestamp-sxGoy8Uj.js} +1 -1
  38. package/dist/server/assets/{SyncNowButton-CKuXKYcd.js → SyncNowButton-CsgOFaO_.js} +1 -1
  39. package/dist/server/assets/{TimelineRouteFrame-Bg3e7X_N.js → TimelineRouteFrame-BWWFisJF.js} +3 -3
  40. package/dist/server/assets/{TweetRichText-wzUAtbPS.js → TweetRichText-BEo_OCEM.js} +2 -2
  41. package/dist/server/assets/{_tanstack-start-manifest_v-mm-2VYBo.js → _tanstack-start-manifest_v-AFEKQ2i-.js} +24 -24
  42. package/dist/server/assets/{blocks-CaP_u3mY.js → blocks-DWZAKPAX.js} +3 -3
  43. package/dist/server/assets/{blocks-DKy4yTF-.js → blocks-VXmcBqKD.js} +3 -3
  44. package/dist/server/assets/{bookmarks-CPFq3JVX.js → bookmarks-B-I4ELcA.js} +1 -1
  45. package/dist/server/assets/{client-stream-contracts-gtXEreFY.js → client-stream-contracts-DVzk8DzM.js} +4 -4
  46. package/dist/server/assets/{data-sources-DWwmQqcO.js → data-sources-UEYjgFHD.js} +1 -1
  47. package/dist/server/assets/{discuss-CVGB4_I0.js → discuss-4b2z14mT.js} +3 -3
  48. package/dist/server/assets/{discuss-BB8wFy4L.js → discuss-CJ_vThu8.js} +3 -3
  49. package/dist/server/assets/{dms-7NzdyQZQ.js → dms-BAKB1Mia.js} +6 -6
  50. package/dist/server/assets/{dms-vbEumuuO.js → dms-BCI8W9u2.js} +4 -4
  51. package/dist/server/assets/{inbox-CBeZctFd.js → inbox-BJzEE8Aa.js} +2 -2
  52. package/dist/server/assets/{inbox-UpHhXODd.js → inbox-D607zrwZ.js} +4 -4
  53. package/dist/server/assets/{likes-CDAjYyTm.js → likes-CMQGc5bh.js} +1 -1
  54. package/dist/server/assets/{links-DU-TIHtg.js → links-BU_FRxcz.js} +6 -6
  55. package/dist/server/assets/{links-sQ3q2jvO.js → links-Dz-6bmkg.js} +6 -6
  56. package/dist/server/assets/{mentions-DdndGSRw.js → mentions-B2K8tGvx.js} +1 -1
  57. package/dist/server/assets/{network-map-CcOz-T9O.js → network-map-BLqLL8CR.js} +2 -2
  58. package/dist/server/assets/{network-map-B9iOapuB.js → network-map-DvfpJQy1.js} +2 -2
  59. package/dist/server/assets/{profile-analyze-CUfXmXEH.js → profile-analyze-CyfbGAsL.js} +3 -3
  60. package/dist/server/assets/{profile-analyze-BmDeTif5.js → profile-analyze-Drz-nRl-.js} +1 -1
  61. package/dist/server/assets/{profiles._handle-BAqnghwo.js → profiles._handle-BBXArSJO.js} +5 -5
  62. package/dist/server/assets/{profiles._handle-8snagiR1.js → profiles._handle-CsU6xBVm.js} +4 -4
  63. package/dist/server/assets/{rate-limits-BY2-aQPT.js → rate-limits-3C3mBM3G.js} +1 -1
  64. package/dist/server/assets/{router-B874XqWN.js → router-DeGdUXyx.js} +80 -42
  65. package/dist/server/assets/{routes-D9226vKz.js → routes-C4caR_ZX.js} +1 -1
  66. package/dist/server/assets/{today-DKWphGrC.js → today-CRa6Y-Tg.js} +3 -3
  67. package/dist/server/assets/{today-BmvIMJzI.js → today-CScZDxQx.js} +3 -3
  68. package/dist/server/assets/{ui-rDHeS-cc.js → ui-CL21-Ku0.js} +1 -1
  69. package/dist/server/assets/{useTimelineRouteData-BmDbGvQ8.js → useTimelineRouteData-BWxx9yQl.js} +6 -6
  70. package/dist/server/server.js +2 -2
  71. package/package.json +1 -1
  72. package/dist/client/assets/likes-CenHqxQG.js +0 -1
@@ -1,4 +1,4 @@
1
- import "./ui-rDHeS-cc.js";
1
+ import "./ui-CL21-Ku0.js";
2
2
  import { C as networkMapResponseSchema, a as fetchQueryEnvelope, n as queryKeys, r as fetchJson } from "./query-client-BdauHBgd.js";
3
3
  import { r as useSelectedAccountId } from "./account-selection-CTdFGWRk.js";
4
4
  import { o as validateNetworkMapSearch } from "./route-search-BUlQ5lGM.js";
@@ -215,7 +215,7 @@ function useNetworkMapController(filters, onFiltersChange) {
215
215
  }
216
216
  //#endregion
217
217
  //#region src/routes/network-map.tsx
218
- var $$splitComponentImporter = () => import("./network-map-CcOz-T9O.js");
218
+ var $$splitComponentImporter = () => import("./network-map-BLqLL8CR.js");
219
219
  var Route$1 = createFileRoute("/network-map")({
220
220
  component: lazyRouteComponent($$splitComponentImporter, "component"),
221
221
  validateSearch: validateNetworkMapSearch
@@ -1,6 +1,6 @@
1
- import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Ht as searchFieldInputClass, Mt as primaryButtonClass, Ot as pageTitleClass, Tt as pageHeaderClass, Ut as searchFieldShellClass, Vt as searchFieldIconClass, Wt as secondaryButtonClass, m as cx, wt as pageHeaderActionsClass } from "./ui-rDHeS-cc.js";
2
- import { t as Route$1 } from "./profile-analyze-BmDeTif5.js";
3
- import { a as formatProfileAnalysisCounts, i as cleanProfileHandle, n as ProfileAnalysisStatusLine, r as useProfileAnalysisStream, t as ProfileAnalysisOutput } from "./ProfileAnalysisStream-CLjrYzEx.js";
1
+ import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Ht as searchFieldInputClass, Mt as primaryButtonClass, Ot as pageTitleClass, Tt as pageHeaderClass, Ut as searchFieldShellClass, Vt as searchFieldIconClass, Wt as secondaryButtonClass, m as cx, wt as pageHeaderActionsClass } from "./ui-CL21-Ku0.js";
2
+ import { t as Route$1 } from "./profile-analyze-Drz-nRl-.js";
3
+ import { a as formatProfileAnalysisCounts, i as cleanProfileHandle, n as ProfileAnalysisStatusLine, r as useProfileAnalysisStream, t as ProfileAnalysisOutput } from "./ProfileAnalysisStream-1CHrSLNN.js";
4
4
  import { useEffect, useMemo, useRef, useState } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { Loader2, RefreshCw, Search, UserSearch } from "lucide-react";
@@ -1,6 +1,6 @@
1
1
  import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
2
2
  //#region src/routes/profile-analyze.tsx
3
- var $$splitComponentImporter = () => import("./profile-analyze-CUfXmXEH.js");
3
+ var $$splitComponentImporter = () => import("./profile-analyze-CyfbGAsL.js");
4
4
  var Route = createFileRoute("/profile-analyze")({
5
5
  component: lazyRouteComponent($$splitComponentImporter, "component"),
6
6
  validateSearch: (search) => ({ handle: typeof search.handle === "string" ? search.handle : "" })
@@ -1,8 +1,8 @@
1
- import { r as formatCompactNumber, t as AvatarChip } from "./AvatarChip-DWag3IzT.js";
2
- import { p as profileDescriptionEntitiesFromXurl } from "./ProfilePreview-Bq-DSUM2.js";
3
- import { t as TweetRichText } from "./TweetRichText-wzUAtbPS.js";
4
- import { a as formatProfileAnalysisCounts, i as cleanProfileHandle, n as ProfileAnalysisStatusLine, r as useProfileAnalysisStream, t as ProfileAnalysisOutput } from "./ProfileAnalysisStream-CLjrYzEx.js";
5
- import { t as Route$1 } from "./profiles._handle-8snagiR1.js";
1
+ import { r as formatCompactNumber, t as AvatarChip } from "./AvatarChip-B5ASnpQ4.js";
2
+ import { p as profileDescriptionEntitiesFromXurl } from "./ProfilePreview-Dk2CdOOS.js";
3
+ import { t as TweetRichText } from "./TweetRichText-BEo_OCEM.js";
4
+ import { a as formatProfileAnalysisCounts, i as cleanProfileHandle, n as ProfileAnalysisStatusLine, r as useProfileAnalysisStream, t as ProfileAnalysisOutput } from "./ProfileAnalysisStream-1CHrSLNN.js";
5
+ import { t as Route$1 } from "./profiles._handle-CsU6xBVm.js";
6
6
  import { useEffect, useRef } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { ExternalLink, Loader2, RefreshCw } from "lucide-react";
@@ -1,12 +1,12 @@
1
- import "./AvatarChip-DWag3IzT.js";
2
- import "./TweetRichText-wzUAtbPS.js";
3
- import "./ProfileAnalysisStream-CLjrYzEx.js";
1
+ import "./AvatarChip-B5ASnpQ4.js";
2
+ import "./TweetRichText-BEo_OCEM.js";
3
+ import "./ProfileAnalysisStream-1CHrSLNN.js";
4
4
  import "react";
5
5
  import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
6
6
  import "react/jsx-runtime";
7
7
  import "lucide-react";
8
8
  //#region src/routes/profiles.$handle.tsx
9
- var $$splitComponentImporter = () => import("./profiles._handle-BAqnghwo.js");
9
+ var $$splitComponentImporter = () => import("./profiles._handle-BBXArSJO.js");
10
10
  var Route$1 = createFileRoute("/profiles/$handle")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
11
11
  //#endregion
12
12
  export { Route$1 as t };
@@ -1,4 +1,4 @@
1
- import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Ot as pageTitleClass, Tt as pageHeaderClass, Wt as secondaryButtonClass, m as cx, q as errorCopyClass, sn as statusCopyClass, wt as pageHeaderActionsClass } from "./ui-rDHeS-cc.js";
1
+ import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Ot as pageTitleClass, Tt as pageHeaderClass, Wt as secondaryButtonClass, m as cx, q as errorCopyClass, sn as statusCopyClass, wt as pageHeaderActionsClass } from "./ui-CL21-Ku0.js";
2
2
  import { k as xurlRateLimitSnapshotSchema, n as queryKeys, r as fetchJson } from "./query-client-BdauHBgd.js";
3
3
  import { useMemo } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -1,19 +1,19 @@
1
- import { $t as sidebarBrandMarkClass, Ct as navLinkLabelCompactClass, Qt as sidebarBrandCopyCompactClass, St as navLinkLabelClass, Xt as sidebarBrandClass, Zt as sidebarBrandCopyClass, an as sidebarShellCompactClass, bt as navLinkCompactClass, en as sidebarBrandTaglineClass, gt as mainColumnDmClass, ht as mainColumnClass, in as sidebarShellClass, m as cx, nn as sidebarFooterClass, o as bodyClass, on as siteShellClass, rn as sidebarNavClass, tn as sidebarBrandTitleClass, xt as navLinkIconClass, yt as navLinkClass } from "./ui-rDHeS-cc.js";
1
+ import { $t as sidebarBrandMarkClass, Ct as navLinkLabelCompactClass, Qt as sidebarBrandCopyCompactClass, St as navLinkLabelClass, Xt as sidebarBrandClass, Zt as sidebarBrandCopyClass, an as sidebarShellCompactClass, bt as navLinkCompactClass, en as sidebarBrandTaglineClass, gt as mainColumnDmClass, ht as mainColumnClass, in as sidebarShellClass, m as cx, nn as sidebarFooterClass, o as bodyClass, on as siteShellClass, rn as sidebarNavClass, tn as sidebarBrandTitleClass, xt as navLinkIconClass, yt as navLinkClass } from "./ui-CL21-Ku0.js";
2
2
  import { C as networkMapResponseSchema, D as tweetConversationResponseSchema, E as queryResponseSchema, O as webSyncJobSchema, S as liveDataSourcesResponseSchema, T as queryEnvelopeSchema, _ as blockListResponseSchema, a as fetchQueryEnvelope, b as linkInsightResponseSchema, d as runEffectPromise, f as toError$17, g as actionResponseSchemaFor, h as actionRequestSchema, k as xurlRateLimitSnapshotSchema, l as defaultRuntimeServices, m as trySync$11, n as queryKeys, p as tryPromise, t as BirdclawQueryProvider, u as runEffectBackground, w as profileHydrationResponseSchema, x as linkPreviewResponseSchema, y as inboxResponseSchema } from "./query-client-BdauHBgd.js";
3
- import { t as AvatarChip } from "./AvatarChip-DWag3IzT.js";
3
+ import { t as AvatarChip } from "./AvatarChip-B5ASnpQ4.js";
4
4
  import { n as setStoredAccountId, r as useSelectedAccountId } from "./account-selection-CTdFGWRk.js";
5
- import { c as BirdclawMark } from "./FeedState-CwzcvP-p.js";
6
- import { a as assertSafePreviewUrl, h as tweetEntitiesFromXurl, i as __test__$1, l as displayUrlForLink, o as isBlockedAddress, s as safeHttpUrl, u as enrichFallbackUrlEntities } from "./ProfilePreview-Bq-DSUM2.js";
7
- import { i as searchDiscussionStreamEventSchema, n as periodDigestStreamEventSchema, r as profileAnalysisStreamEventSchema } from "./client-stream-contracts-gtXEreFY.js";
8
- import { t as Route$25 } from "./today-BmvIMJzI.js";
9
- import { t as Route$26 } from "./profile-analyze-BmDeTif5.js";
10
- import { t as Route$27 } from "./network-map-B9iOapuB.js";
11
- import { t as Route$28 } from "./links-DU-TIHtg.js";
12
- import { t as Route$29 } from "./inbox-UpHhXODd.js";
13
- import { t as Route$30 } from "./dms-7NzdyQZQ.js";
14
- import { t as Route$31 } from "./discuss-BB8wFy4L.js";
15
- import { t as Route$32 } from "./blocks-CaP_u3mY.js";
16
- import { t as Route$33 } from "./profiles._handle-8snagiR1.js";
5
+ import { c as BirdclawMark } from "./FeedState-YrMZ10Gf.js";
6
+ import { a as assertSafePreviewUrl, h as tweetEntitiesFromXurl, i as __test__$1, l as displayUrlForLink, o as isBlockedAddress, s as safeHttpUrl, u as enrichFallbackUrlEntities } from "./ProfilePreview-Dk2CdOOS.js";
7
+ import { i as searchDiscussionStreamEventSchema, n as periodDigestStreamEventSchema, r as profileAnalysisStreamEventSchema } from "./client-stream-contracts-DVzk8DzM.js";
8
+ import { t as Route$25 } from "./today-CScZDxQx.js";
9
+ import { t as Route$26 } from "./profile-analyze-Drz-nRl-.js";
10
+ import { t as Route$27 } from "./network-map-DvfpJQy1.js";
11
+ import { t as Route$28 } from "./links-BU_FRxcz.js";
12
+ import { t as Route$29 } from "./inbox-D607zrwZ.js";
13
+ import { t as Route$30 } from "./dms-BAKB1Mia.js";
14
+ import { t as Route$31 } from "./discuss-CJ_vThu8.js";
15
+ import { t as Route$32 } from "./blocks-DWZAKPAX.js";
16
+ import { t as Route$33 } from "./profiles._handle-CsU6xBVm.js";
17
17
  import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
18
18
  import { HeadContent, Link, Scripts, createFileRoute, createRootRoute, createRouter, lazyRouteComponent, useRouterState } from "@tanstack/react-router";
19
19
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -521,7 +521,7 @@ function AppNav({ compact = false }) {
521
521
  }
522
522
  //#endregion
523
523
  //#region src/styles.css?url
524
- var styles_default = "/assets/styles-DT4Pxoi-.css";
524
+ var styles_default = "/assets/styles-DAoXpgpq.css";
525
525
  //#endregion
526
526
  //#region src/routes/__root.tsx
527
527
  var Route$24 = createRootRoute({
@@ -574,27 +574,27 @@ function RootDocument({ children }) {
574
574
  }
575
575
  //#endregion
576
576
  //#region src/routes/rate-limits.tsx
577
- var $$splitComponentImporter$5 = () => import("./rate-limits-BY2-aQPT.js");
577
+ var $$splitComponentImporter$5 = () => import("./rate-limits-3C3mBM3G.js");
578
578
  var Route$23 = createFileRoute("/rate-limits")({ component: lazyRouteComponent($$splitComponentImporter$5, "component") });
579
579
  //#endregion
580
580
  //#region src/routes/mentions.tsx
581
- var $$splitComponentImporter$4 = () => import("./mentions-DdndGSRw.js");
581
+ var $$splitComponentImporter$4 = () => import("./mentions-B2K8tGvx.js");
582
582
  var Route$22 = createFileRoute("/mentions")({ component: lazyRouteComponent($$splitComponentImporter$4, "component") });
583
583
  //#endregion
584
584
  //#region src/routes/likes.tsx
585
- var $$splitComponentImporter$3 = () => import("./likes-CDAjYyTm.js");
585
+ var $$splitComponentImporter$3 = () => import("./likes-CMQGc5bh.js");
586
586
  var Route$21 = createFileRoute("/likes")({ component: lazyRouteComponent($$splitComponentImporter$3, "component") });
587
587
  //#endregion
588
588
  //#region src/routes/data-sources.tsx
589
- var $$splitComponentImporter$2 = () => import("./data-sources-DWwmQqcO.js");
589
+ var $$splitComponentImporter$2 = () => import("./data-sources-UEYjgFHD.js");
590
590
  var Route$20 = createFileRoute("/data-sources")({ component: lazyRouteComponent($$splitComponentImporter$2, "component") });
591
591
  //#endregion
592
592
  //#region src/routes/bookmarks.tsx
593
- var $$splitComponentImporter$1 = () => import("./bookmarks-CPFq3JVX.js");
593
+ var $$splitComponentImporter$1 = () => import("./bookmarks-B-I4ELcA.js");
594
594
  var Route$19 = createFileRoute("/bookmarks")({ component: lazyRouteComponent($$splitComponentImporter$1, "component") });
595
595
  //#endregion
596
596
  //#region src/routes/index.tsx
597
- var $$splitComponentImporter = () => import("./routes-D9226vKz.js");
597
+ var $$splitComponentImporter = () => import("./routes-C4caR_ZX.js");
598
598
  var Route$18 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
599
599
  //#endregion
600
600
  //#region src/lib/http-effect.ts
@@ -8902,9 +8902,10 @@ function getTimelineQualityReason(row, lowQualityThreshold) {
8902
8902
  return "keep:long-text";
8903
8903
  }
8904
8904
  var RECENT_TIMELINE_EDGE_CANDIDATES = 5e3;
8905
- function listTimelineItems({ resource, account, listAccountId, listId, search, replyFilter = "all", since, until, untilId, includeReplies = true, qualityFilter = "all", lowQualityThreshold, includeQualityReason = false, likedOnly = false, bookmarkedOnly = false, limit = 18 }) {
8906
- const db = getReadDb();
8905
+ var FTS_DRIVE_FROM_MATCHES_MAX = 1e4;
8906
+ function buildTimelineItemsQuery({ resource, account, listAccountId, listId, search, replyFilter = "all", since, until, untilId, includeReplies = true, qualityFilter = "all", lowQualityThreshold, likedOnly = false, bookmarkedOnly = false, limit = 18 }, ftsMatchCountHint = 0) {
8907
8907
  const kind = resource === "mentions" ? "mention" : resource;
8908
+ const cteParams = [];
8908
8909
  const params = [];
8909
8910
  const normalizedLowQualityThreshold = normalizeLowQualityThreshold(lowQualityThreshold);
8910
8911
  const shouldDedupeAcrossAccounts = !account || account === "all";
@@ -8917,9 +8918,8 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
8917
8918
  `;
8918
8919
  const unwindowedTimelineEdgesCte = timelineEdgesCte;
8919
8920
  let usedRecentEdgeWindow = false;
8920
- let join = "";
8921
8921
  let where = "where e.kind = ?";
8922
- let searchSnippetSelect = "";
8922
+ const ftsSearch = search?.trim() ? toFtsSearchQuery(search) : "";
8923
8923
  const canUseRecentEdgeWindow = !likedOnly && !bookmarkedOnly && !listId && !account && !search?.trim() && replyFilter === "all" && !since?.trim() && !until?.trim() && includeReplies && qualityFilter === "all";
8924
8924
  if (likedOnly || bookmarkedOnly) {
8925
8925
  if (likedOnly && bookmarkedOnly) timelineEdgesCte = `
@@ -8942,7 +8942,7 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
8942
8942
  where kind = ?
8943
8943
  )
8944
8944
  `;
8945
- params.push(collectionKind);
8945
+ cteParams.push(collectionKind);
8946
8946
  }
8947
8947
  where = "where 1 = 1";
8948
8948
  } else if (canUseRecentEdgeWindow) {
@@ -8961,11 +8961,11 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
8961
8961
  )
8962
8962
  `;
8963
8963
  const candidateLimit = Math.max(RECENT_TIMELINE_EDGE_CANDIDATES, limit * 50);
8964
- params.push(kind, candidateLimit);
8964
+ cteParams.push(kind, candidateLimit);
8965
8965
  where = "where e.kind = ?";
8966
8966
  params.push(kind);
8967
8967
  } else {
8968
- params.push(kind);
8968
+ cteParams.push(kind);
8969
8969
  where = "where e.kind = ?";
8970
8970
  params.push(kind);
8971
8971
  }
@@ -9014,16 +9014,28 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
9014
9014
  `;
9015
9015
  params.push(listAccountId, listId);
9016
9016
  }
9017
- const ftsSearch = search?.trim() ? toFtsSearchQuery(search) : "";
9018
- if (ftsSearch) {
9019
- join += " join tweets_fts on tweets_fts.tweet_id = t.id ";
9020
- where += " and tweets_fts.text match ?";
9021
- searchSnippetSelect = ", snippet(tweets_fts, 1, '<mark>', '</mark>', '...', 16) as search_snippet";
9022
- params.push(ftsSearch);
9023
- }
9017
+ const ftsMatchesCte = ftsSearch ? `, fts_matches as materialized (
9018
+ select tweet_id
9019
+ from tweets_fts
9020
+ where tweets_fts.text match ?
9021
+ )` : "";
9022
+ if (ftsSearch) cteParams.push(ftsSearch);
9023
+ const searchDrivenFrom = ftsMatchCountHint > FTS_DRIVE_FROM_MATCHES_MAX ? `tweets t
9024
+ cross join fts_matches on fts_matches.tweet_id = t.id
9025
+ cross join timeline_edges e on e.tweet_id = t.id` : `fts_matches
9026
+ cross join tweets t on t.id = fts_matches.tweet_id
9027
+ cross join timeline_edges e on e.tweet_id = t.id`;
9024
9028
  params.push(limit);
9029
+ if (ftsSearch) params.push(limit);
9030
+ const searchSelectionCte = ftsSearch ? `, search_selection as materialized (
9031
+ select t.id as tweet_id, e.account_id, e.kind, e.raw_json
9032
+ from ${searchDrivenFrom}
9033
+ ${where}
9034
+ order by t.created_at desc, t.id desc
9035
+ limit ?
9036
+ )` : "";
9025
9037
  const buildTimelineSelectSql = (timelineEdgesSql) => `
9026
- ${timelineEdgesSql}
9038
+ ${timelineEdgesSql}${ftsMatchesCte}${searchSelectionCte}
9027
9039
  select
9028
9040
  t.id,
9029
9041
  e.account_id,
@@ -9100,8 +9112,7 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
9100
9112
  qp.avatar_hue as quoted_avatar_hue,
9101
9113
  qp.avatar_url as quoted_avatar_url,
9102
9114
  qp.created_at as quoted_profile_created_at
9103
- ${searchSnippetSelect}
9104
- from timeline_edges e
9115
+ from ${ftsSearch ? "search_selection e" : "timeline_edges e"}
9105
9116
  join tweets t on t.id = e.tweet_id
9106
9117
  join accounts a on a.id = e.account_id
9107
9118
  join profiles p on p.id = t.author_profile_id
@@ -9109,13 +9120,40 @@ function listTimelineItems({ resource, account, listAccountId, listId, search, r
9109
9120
  left join profiles rp on rp.id = rt.author_profile_id
9110
9121
  left join tweets qt on qt.id = t.quoted_tweet_id
9111
9122
  left join profiles qp on qp.id = qt.author_profile_id
9112
- ${join}
9113
- ${where}
9123
+ ${ftsSearch ? "" : where}
9114
9124
  order by t.created_at desc, t.id desc
9115
9125
  limit ?
9116
9126
  `;
9117
- let rows = db.prepare(buildTimelineSelectSql(timelineEdgesCte)).all(...params);
9118
- if (usedRecentEdgeWindow && rows.length < limit) rows = db.prepare(buildTimelineSelectSql(unwindowedTimelineEdgesCte)).all(kind, kind, limit);
9127
+ return {
9128
+ sql: buildTimelineSelectSql(timelineEdgesCte),
9129
+ params: [...cteParams, ...params],
9130
+ fallbackSql: buildTimelineSelectSql(unwindowedTimelineEdgesCte),
9131
+ fallbackParams: [
9132
+ kind,
9133
+ kind,
9134
+ limit
9135
+ ],
9136
+ usedRecentEdgeWindow,
9137
+ ftsSearch
9138
+ };
9139
+ }
9140
+ var SEARCH_SNIPPET_SQL = "snippet(tweets_fts, 1, '<mark>', '</mark>', '...', 16)";
9141
+ function listTimelineItems(query) {
9142
+ const db = getReadDb();
9143
+ const { includeQualityReason = false, lowQualityThreshold, limit = 18 } = query;
9144
+ const normalizedLowQualityThreshold = normalizeLowQualityThreshold(lowQualityThreshold);
9145
+ const ftsSearch = query.search?.trim() ? toFtsSearchQuery(query.search) : "";
9146
+ const plan = buildTimelineItemsQuery(query, ftsSearch ? Number(db.prepare("select count(*) as match_count from tweets_fts where tweets_fts.text match ?").get(ftsSearch).match_count) : 0);
9147
+ let rows = db.prepare(plan.sql).all(...plan.params);
9148
+ if (plan.usedRecentEdgeWindow && rows.length < limit) rows = db.prepare(plan.fallbackSql).all(...plan.fallbackParams);
9149
+ if (plan.ftsSearch && rows.length > 0) {
9150
+ const snippetRows = db.prepare(`select tweet_id, ${SEARCH_SNIPPET_SQL} as search_snippet
9151
+ from tweets_fts
9152
+ where tweets_fts.text match ?
9153
+ and tweet_id in (${rows.map(() => "?").join(",")})`).all(plan.ftsSearch, ...rows.map((row) => String(row.id)));
9154
+ const snippetByTweetId = new Map(snippetRows.map((row) => [String(row.tweet_id), row.search_snippet]));
9155
+ for (const row of rows) row.search_snippet = snippetByTweetId.get(String(row.id));
9156
+ }
9119
9157
  const urlExpansionCache = /* @__PURE__ */ new Map();
9120
9158
  const profileByHandleCache = /* @__PURE__ */ new Map();
9121
9159
  return rows.map((row) => {
@@ -1,4 +1,4 @@
1
- import { t as TimelineRouteFrame } from "./TimelineRouteFrame-Bg3e7X_N.js";
1
+ import { t as TimelineRouteFrame } from "./TimelineRouteFrame-BWWFisJF.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/routes/index.tsx?tsr-split=component
4
4
  function homeSubtitle(meta) {
@@ -1,8 +1,8 @@
1
- import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Jt as segmentedClass, Ot as pageTitleClass, Tt as pageHeaderClass, Wt as secondaryButtonClass, m as cx, q as errorCopyClass, qt as segmentClass, wt as pageHeaderActionsClass } from "./ui-rDHeS-cc.js";
2
- import { a as useNdjsonRun, n as periodDigestStreamEventSchema, o as MarkdownViewer, t as isTerminalStreamEvent } from "./client-stream-contracts-gtXEreFY.js";
1
+ import { Dt as pageSubtitleClass, Et as pageHeaderRowClass, Jt as segmentedClass, Ot as pageTitleClass, Tt as pageHeaderClass, Wt as secondaryButtonClass, m as cx, q as errorCopyClass, qt as segmentClass, wt as pageHeaderActionsClass } from "./ui-CL21-Ku0.js";
2
+ import { a as useNdjsonRun, n as periodDigestStreamEventSchema, o as MarkdownViewer, t as isTerminalStreamEvent } from "./client-stream-contracts-DVzk8DzM.js";
3
3
  import { n as normalizeProfileHydrationHandle, t as hydrateProfileHandles } from "./profile-hydration-client-GJ4kwJS8.js";
4
4
  import { s as validateTodaySearch } from "./route-search-BUlQ5lGM.js";
5
- import { t as Route$1 } from "./today-BmvIMJzI.js";
5
+ import { t as Route$1 } from "./today-CScZDxQx.js";
6
6
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { CheckCircle2, FileDown, Loader2, RefreshCw, Sparkles } from "lucide-react";
@@ -1,5 +1,5 @@
1
- import "./ui-rDHeS-cc.js";
2
- import "./client-stream-contracts-gtXEreFY.js";
1
+ import "./ui-CL21-Ku0.js";
2
+ import "./client-stream-contracts-DVzk8DzM.js";
3
3
  import "./profile-hydration-client-GJ4kwJS8.js";
4
4
  import { s as validateTodaySearch } from "./route-search-BUlQ5lGM.js";
5
5
  import "react";
@@ -8,7 +8,7 @@ import "react/jsx-runtime";
8
8
  import "lucide-react";
9
9
  import "@tanstack/react-query";
10
10
  //#region src/routes/today.tsx
11
- var $$splitComponentImporter = () => import("./today-DKWphGrC.js");
11
+ var $$splitComponentImporter = () => import("./today-CRa6Y-Tg.js");
12
12
  var Route$1 = createFileRoute("/today")({
13
13
  component: lazyRouteComponent($$splitComponentImporter, "component"),
14
14
  validateSearch: validateTodaySearch
@@ -18,7 +18,7 @@ var navLinkClass = "nav-link group flex items-center justify-center gap-4 rounde
18
18
  var navLinkCompactClass = "nav-link group flex items-center justify-center rounded-full px-3 py-2.5 text-[15px] text-[var(--ink)] transition-colors duration-150 hover:bg-[var(--bg-hover)]";
19
19
  var navLinkActiveClass = "nav-link-active font-bold";
20
20
  var navLinkIconClass = "shrink-0";
21
- var navLinkLabelClass = "sr-only min-[1100px]:not-sr-only";
21
+ var navLinkLabelClass = "max-[1100px]:sr-only";
22
22
  var navLinkLabelCompactClass = "sr-only";
23
23
  var mainColumnClass = "flex w-full min-w-0 max-w-[680px] flex-1 flex-col border-x border-[var(--line)] bg-[var(--bg)]";
24
24
  var mainColumnDmClass = "flex w-full min-w-0 flex-1 flex-col border-x border-[var(--line)] bg-[var(--bg)]";
@@ -1,12 +1,12 @@
1
- import { $ as feedRowBodyClass, B as embeddedCardClass, Dt as pageSubtitleClass, Et as pageHeaderRowClass, G as embeddedCardNameClass, H as embeddedCardHandleClass, Ht as searchFieldInputClass, J as feedActionButtonClass, Ot as pageTitleClass, Q as feedRowActionsClass, Tt as pageHeaderClass, U as embeddedCardHeaderClass, Ut as searchFieldShellClass, V as embeddedCardCopyClass, Vt as searchFieldIconClass, W as embeddedCardLabelClass, X as feedActionIconWrapClass, Y as feedActionIconClass, Z as feedClass, _n as tweetMediaGridClass, at as feedRowStatePillActiveClass, ct as feedRowTextClass, dt as linkPreviewCardClass, et as feedRowClass, ft as linkPreviewDescClass, it as feedRowNameClass, lt as feedRowTimestampClass, m as cx, mt as linkPreviewTitleClass, nt as feedRowHandleClass, ot as feedRowStatePillClass, pt as linkPreviewHostClass, rt as feedRowHeaderClass, st as feedRowStatePillOpenClass, tt as feedRowDotClass, vn as tweetMediaTileClass, z as embeddedCardBodyClass } from "./ui-rDHeS-cc.js";
1
+ import { $ as feedRowBodyClass, B as embeddedCardClass, Dt as pageSubtitleClass, Et as pageHeaderRowClass, G as embeddedCardNameClass, H as embeddedCardHandleClass, Ht as searchFieldInputClass, J as feedActionButtonClass, Ot as pageTitleClass, Q as feedRowActionsClass, Tt as pageHeaderClass, U as embeddedCardHeaderClass, Ut as searchFieldShellClass, V as embeddedCardCopyClass, Vt as searchFieldIconClass, W as embeddedCardLabelClass, X as feedActionIconWrapClass, Y as feedActionIconClass, Z as feedClass, _n as tweetMediaGridClass, at as feedRowStatePillActiveClass, ct as feedRowTextClass, dt as linkPreviewCardClass, et as feedRowClass, ft as linkPreviewDescClass, it as feedRowNameClass, lt as feedRowTimestampClass, m as cx, mt as linkPreviewTitleClass, nt as feedRowHandleClass, ot as feedRowStatePillClass, pt as linkPreviewHostClass, rt as feedRowHeaderClass, st as feedRowStatePillOpenClass, tt as feedRowDotClass, vn as tweetMediaTileClass, z as embeddedCardBodyClass } from "./ui-CL21-Ku0.js";
2
2
  import { D as tweetConversationResponseSchema, a as fetchQueryEnvelope, d as runEffectPromise, i as fetchJsonEffect, n as queryKeys, o as fetchQueryResponse, r as fetchJson, s as postAction, x as linkPreviewResponseSchema } from "./query-client-BdauHBgd.js";
3
- import { r as formatCompactNumber, t as AvatarChip } from "./AvatarChip-DWag3IzT.js";
3
+ import { r as formatCompactNumber, t as AvatarChip } from "./AvatarChip-B5ASnpQ4.js";
4
4
  import { r as useSelectedAccountId } from "./account-selection-CTdFGWRk.js";
5
- import { a as TweetSkeletonRows, n as FeedError, o as BirdclawEmpty, r as FeedLoading, s as BirdclawLoading, t as FeedEmpty } from "./FeedState-CwzcvP-p.js";
6
- import { d as isTweetArticleUrlEntity, f as normalizeTweetUrlEntityRangeForText, s as safeHttpUrl, t as ProfilePreview } from "./ProfilePreview-Bq-DSUM2.js";
7
- import { t as SmartTimestamp } from "./SmartTimestamp-C06w_f9J.js";
5
+ import { a as TweetSkeletonRows, n as FeedError, o as BirdclawEmpty, r as FeedLoading, s as BirdclawLoading, t as FeedEmpty } from "./FeedState-YrMZ10Gf.js";
6
+ import { d as isTweetArticleUrlEntity, f as normalizeTweetUrlEntityRangeForText, s as safeHttpUrl, t as ProfilePreview } from "./ProfilePreview-Dk2CdOOS.js";
7
+ import { t as SmartTimestamp } from "./SmartTimestamp-sxGoy8Uj.js";
8
8
  import { t as useDebouncedValue } from "./useDebouncedValue-DOnA6Xcy.js";
9
- import { t as TweetRichText } from "./TweetRichText-wzUAtbPS.js";
9
+ import { t as TweetRichText } from "./TweetRichText-BEo_OCEM.js";
10
10
  import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
11
11
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
12
  import { BookOpen, BookmarkCheck, CheckCircle2, Circle, ExternalLink, Heart, Image, MessageCircle, Repeat2, Search, UserSearch, X } from "lucide-react";
@@ -623,7 +623,7 @@ function getResponse() {
623
623
  * the dev styles URL for route-scoped CSS collection.
624
624
  */
625
625
  async function getStartManifest(matchedRoutes) {
626
- const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-mm-2VYBo.js");
626
+ const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-AFEKQ2i-.js");
627
627
  const startManifest = tsrStartManifest();
628
628
  let routes = startManifest.routes;
629
629
  routes[rootRouteId];
@@ -1767,7 +1767,7 @@ var getBaseManifest = getProdBaseManifest;
1767
1767
  var createEarlyHintsForRequest = createEarlyHintsCollector;
1768
1768
  async function loadEntries() {
1769
1769
  const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
1770
- import("./assets/router-B874XqWN.js"),
1770
+ import("./assets/router-DeGdUXyx.js"),
1771
1771
  import("./assets/start-5Z2QO8AU.js"),
1772
1772
  import("./assets/empty-plugin-adapters-D9UWiqvJ.js")
1773
1773
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "birdclaw",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "description": "Local Twitter memory in SQLite for archives, DMs, likes, bookmarks, and moderation",
5
5
  "homepage": "https://github.com/steipete/birdclaw#readme",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- import{Rn as e}from"./schemas-CntsNLmN.js";import{t}from"./SavedTimelineView-BSnwnujP.js";var n=e();function r(){return(0,n.jsx)(t,{eyebrow:`liked posts`,filter:`liked`,loadingLabel:`Loading liked posts...`,searchPlaceholder:`Search likes`,title:`Things worth keeping in the orbit.`})}export{r as component};