@dxos/plugin-magazine 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +105 -0
- package/PLUGIN.mdl +653 -0
- package/dist/lib/neutral/FeedArticle-PEWCFFSP.mjs +90 -0
- package/dist/lib/neutral/FeedArticle-PEWCFFSP.mjs.map +7 -0
- package/dist/lib/neutral/FeedProperties-EIO7IZOA.mjs +97 -0
- package/dist/lib/neutral/FeedProperties-EIO7IZOA.mjs.map +7 -0
- package/dist/lib/neutral/MagazineArticle-DEUTR23F.mjs +325 -0
- package/dist/lib/neutral/MagazineArticle-DEUTR23F.mjs.map +7 -0
- package/dist/lib/neutral/MagazinePlugin.mjs +62 -0
- package/dist/lib/neutral/MagazinePlugin.mjs.map +7 -0
- package/dist/lib/neutral/MagazinePlugin.workerd.mjs +12 -0
- package/dist/lib/neutral/MagazinePlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/PostArticle-RERHXPXC.mjs +230 -0
- package/dist/lib/neutral/PostArticle-RERHXPXC.mjs.map +7 -0
- package/dist/lib/neutral/PostCard-VDGN7BBA.mjs +60 -0
- package/dist/lib/neutral/PostCard-VDGN7BBA.mjs.map +7 -0
- package/dist/lib/neutral/app-graph-builder-JDPRBVHL.mjs +121 -0
- package/dist/lib/neutral/app-graph-builder-JDPRBVHL.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +21 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-3K4AQKBZ.mjs +12 -0
- package/dist/lib/neutral/chunk-3K4AQKBZ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-AFPBWBTK.mjs +591 -0
- package/dist/lib/neutral/chunk-AFPBWBTK.mjs.map +7 -0
- package/dist/lib/neutral/chunk-APQRTYT3.mjs +57 -0
- package/dist/lib/neutral/chunk-APQRTYT3.mjs.map +7 -0
- package/dist/lib/neutral/chunk-GU725ZF4.mjs +11 -0
- package/dist/lib/neutral/chunk-GU725ZF4.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/chunk-JFPR6OV4.mjs +60 -0
- package/dist/lib/neutral/chunk-JFPR6OV4.mjs.map +7 -0
- package/dist/lib/neutral/chunk-KTYLUOUG.mjs +36 -0
- package/dist/lib/neutral/chunk-KTYLUOUG.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MBPX7RPI.mjs +14 -0
- package/dist/lib/neutral/chunk-MBPX7RPI.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MJ2AY2CK.mjs +8 -0
- package/dist/lib/neutral/chunk-MJ2AY2CK.mjs.map +7 -0
- package/dist/lib/neutral/chunk-OYCDRSWB.mjs +624 -0
- package/dist/lib/neutral/chunk-OYCDRSWB.mjs.map +7 -0
- package/dist/lib/neutral/chunk-SAWKLGJU.mjs +28 -0
- package/dist/lib/neutral/chunk-SAWKLGJU.mjs.map +7 -0
- package/dist/lib/neutral/chunk-XCNCK47N.mjs +15 -0
- package/dist/lib/neutral/chunk-XCNCK47N.mjs.map +7 -0
- package/dist/lib/neutral/clear-magazine-KNY4OWY4.mjs +59 -0
- package/dist/lib/neutral/clear-magazine-KNY4OWY4.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +338 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +17 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/create-object-SYZMRR4H.mjs +98 -0
- package/dist/lib/neutral/create-object-SYZMRR4H.mjs.map +7 -0
- package/dist/lib/neutral/curate-magazine-MA6OLK2X.mjs +184 -0
- package/dist/lib/neutral/curate-magazine-MA6OLK2X.mjs.map +7 -0
- package/dist/lib/neutral/fetch-article-content-CZO6D3QD.mjs +31 -0
- package/dist/lib/neutral/fetch-article-content-CZO6D3QD.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +18 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/load-post-content-XGL6VFF6.mjs +65 -0
- package/dist/lib/neutral/load-post-content-XGL6VFF6.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +8 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/navigation-resolver-IN4OMCDR.mjs +18 -0
- package/dist/lib/neutral/navigation-resolver-IN4OMCDR.mjs.map +7 -0
- package/dist/lib/neutral/operation-handler-JE3743BU.mjs +8 -0
- package/dist/lib/neutral/operation-handler-JE3743BU.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +8 -0
- package/dist/lib/neutral/operations/index.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +16 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/plugin.workerd.mjs +16 -0
- package/dist/lib/neutral/plugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/react-surface-TZESAMG2.mjs +60 -0
- package/dist/lib/neutral/react-surface-TZESAMG2.mjs.map +7 -0
- package/dist/lib/neutral/routine-templates-A2XTJOZO.mjs +52 -0
- package/dist/lib/neutral/routine-templates-A2XTJOZO.mjs.map +7 -0
- package/dist/lib/neutral/skill-definition-3KLMUEC5.mjs +8 -0
- package/dist/lib/neutral/skill-definition-3KLMUEC5.mjs.map +7 -0
- package/dist/lib/neutral/skills/index.mjs +46 -0
- package/dist/lib/neutral/skills/index.mjs.map +7 -0
- package/dist/lib/neutral/sync-feed-UZX2XHSQ.mjs +99 -0
- package/dist/lib/neutral/sync-feed-UZX2XHSQ.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +81 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +14 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/MagazinePlugin.d.ts +4 -0
- package/dist/types/src/MagazinePlugin.d.ts.map +1 -0
- package/dist/types/src/MagazinePlugin.test.d.ts +2 -0
- package/dist/types/src/MagazinePlugin.test.d.ts.map +1 -0
- package/dist/types/src/MagazinePlugin.workerd.d.ts +4 -0
- package/dist/types/src/MagazinePlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/atoms/atoms.test.d.ts +2 -0
- package/dist/types/src/atoms/atoms.test.d.ts.map +1 -0
- package/dist/types/src/atoms/index.d.ts +7 -0
- package/dist/types/src/atoms/index.d.ts.map +1 -0
- package/dist/types/src/atoms/magazine-posts.d.ts +16 -0
- package/dist/types/src/atoms/magazine-posts.d.ts.map +1 -0
- package/dist/types/src/atoms/post-content.d.ts +7 -0
- package/dist/types/src/atoms/post-content.d.ts.map +1 -0
- package/dist/types/src/atoms/post-curation.d.ts +16 -0
- package/dist/types/src/atoms/post-curation.d.ts.map +1 -0
- package/dist/types/src/atoms/post-display.d.ts +22 -0
- package/dist/types/src/atoms/post-display.d.ts.map +1 -0
- package/dist/types/src/atoms/post-read.d.ts +14 -0
- package/dist/types/src/atoms/post-read.d.ts.map +1 -0
- package/dist/types/src/atoms/post-tags.d.ts +16 -0
- package/dist/types/src/atoms/post-tags.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +5 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/create-object.d.ts +5 -0
- package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +10 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/navigation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/navigation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/routine-templates.d.ts +5 -0
- package/dist/types/src/capabilities/routine-templates.d.ts.map +1 -0
- package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
- package/dist/types/src/components/PostContent/PostContent.d.ts +30 -0
- package/dist/types/src/components/PostContent/PostContent.d.ts.map +1 -0
- package/dist/types/src/components/PostContent/PostContent.test.d.ts +2 -0
- package/dist/types/src/components/PostContent/PostContent.test.d.ts.map +1 -0
- package/dist/types/src/components/PostContent/index.d.ts +2 -0
- package/dist/types/src/components/PostContent/index.d.ts.map +1 -0
- package/dist/types/src/components/PostStack/PostStack.d.ts +17 -0
- package/dist/types/src/components/PostStack/PostStack.d.ts.map +1 -0
- package/dist/types/src/components/PostStack/PostStack.stories.d.ts +10 -0
- package/dist/types/src/components/PostStack/PostStack.stories.d.ts.map +1 -0
- package/dist/types/src/components/PostStack/index.d.ts +2 -0
- package/dist/types/src/components/PostStack/index.d.ts.map +1 -0
- package/dist/types/src/components/SubscriptionStack/SubscriptionStack.d.ts +23 -0
- package/dist/types/src/components/SubscriptionStack/SubscriptionStack.d.ts.map +1 -0
- package/dist/types/src/components/SubscriptionStack/SubscriptionStack.stories.d.ts +8 -0
- package/dist/types/src/components/SubscriptionStack/SubscriptionStack.stories.d.ts.map +1 -0
- package/dist/types/src/components/SubscriptionStack/index.d.ts +2 -0
- package/dist/types/src/components/SubscriptionStack/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +4 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/containers/FeedArticle/FeedArticle.d.ts +6 -0
- package/dist/types/src/containers/FeedArticle/FeedArticle.d.ts.map +1 -0
- package/dist/types/src/containers/FeedArticle/FeedArticle.stories.d.ts +12 -0
- package/dist/types/src/containers/FeedArticle/FeedArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/FeedArticle/FeedToolbar.d.ts +10 -0
- package/dist/types/src/containers/FeedArticle/FeedToolbar.d.ts.map +1 -0
- package/dist/types/src/containers/FeedArticle/index.d.ts +2 -0
- package/dist/types/src/containers/FeedArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/FeedProperties/FeedProperties.d.ts +6 -0
- package/dist/types/src/containers/FeedProperties/FeedProperties.d.ts.map +1 -0
- package/dist/types/src/containers/FeedProperties/index.d.ts +2 -0
- package/dist/types/src/containers/FeedProperties/index.d.ts.map +1 -0
- package/dist/types/src/containers/MagazineArticle/MagazineArticle.d.ts +6 -0
- package/dist/types/src/containers/MagazineArticle/MagazineArticle.d.ts.map +1 -0
- package/dist/types/src/containers/MagazineArticle/MagazineArticle.stories.d.ts +9 -0
- package/dist/types/src/containers/MagazineArticle/MagazineArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/MagazineArticle/MagazineTile.d.ts +11 -0
- package/dist/types/src/containers/MagazineArticle/MagazineTile.d.ts.map +1 -0
- package/dist/types/src/containers/MagazineArticle/index.d.ts +2 -0
- package/dist/types/src/containers/MagazineArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/MagazineArticle/useToolbar.d.ts +18 -0
- package/dist/types/src/containers/MagazineArticle/useToolbar.d.ts.map +1 -0
- package/dist/types/src/containers/PostArticle/PostArticle.d.ts +6 -0
- package/dist/types/src/containers/PostArticle/PostArticle.d.ts.map +1 -0
- package/dist/types/src/containers/PostArticle/PostArticle.stories.d.ts +8 -0
- package/dist/types/src/containers/PostArticle/PostArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/PostArticle/PostToolbar.d.ts +19 -0
- package/dist/types/src/containers/PostArticle/PostToolbar.d.ts.map +1 -0
- package/dist/types/src/containers/PostArticle/index.d.ts +2 -0
- package/dist/types/src/containers/PostArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/PostCard/PostCard.d.ts +11 -0
- package/dist/types/src/containers/PostCard/PostCard.d.ts.map +1 -0
- package/dist/types/src/containers/PostCard/index.d.ts +2 -0
- package/dist/types/src/containers/PostCard/index.d.ts.map +1 -0
- package/dist/types/src/containers/SubscriptionsArticle/SubscriptionsArticle.d.ts +5 -0
- package/dist/types/src/containers/SubscriptionsArticle/SubscriptionsArticle.d.ts.map +1 -0
- package/dist/types/src/containers/SubscriptionsArticle/SubscriptionsArticle.stories.d.ts +8 -0
- package/dist/types/src/containers/SubscriptionsArticle/SubscriptionsArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/SubscriptionsArticle/index.d.ts +2 -0
- package/dist/types/src/containers/SubscriptionsArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +7 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +33 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/operations/clear-magazine.d.ts +10 -0
- package/dist/types/src/operations/clear-magazine.d.ts.map +1 -0
- package/dist/types/src/operations/curate-magazine.d.ts +25 -0
- package/dist/types/src/operations/curate-magazine.d.ts.map +1 -0
- package/dist/types/src/operations/curate-magazine.skill.test.d.ts +2 -0
- package/dist/types/src/operations/curate-magazine.skill.test.d.ts.map +1 -0
- package/dist/types/src/operations/curate-magazine.test.d.ts +2 -0
- package/dist/types/src/operations/curate-magazine.test.d.ts.map +1 -0
- package/dist/types/src/operations/extraction/article.d.ts +37 -0
- package/dist/types/src/operations/extraction/article.d.ts.map +1 -0
- package/dist/types/src/operations/extraction/article.test.d.ts +2 -0
- package/dist/types/src/operations/extraction/article.test.d.ts.map +1 -0
- package/dist/types/src/operations/extraction/index.d.ts +2 -0
- package/dist/types/src/operations/extraction/index.d.ts.map +1 -0
- package/dist/types/src/operations/fetch-article-content.d.ts +5 -0
- package/dist/types/src/operations/fetch-article-content.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/load-post-content.d.ts +8 -0
- package/dist/types/src/operations/load-post-content.d.ts.map +1 -0
- package/dist/types/src/operations/sources/article.d.ts +24 -0
- package/dist/types/src/operations/sources/article.d.ts.map +1 -0
- package/dist/types/src/operations/sources/cors.d.ts +12 -0
- package/dist/types/src/operations/sources/cors.d.ts.map +1 -0
- package/dist/types/src/operations/sources/feed-fetcher.d.ts +22 -0
- package/dist/types/src/operations/sources/feed-fetcher.d.ts.map +1 -0
- package/dist/types/src/operations/sources/feed-fetcher.test.d.ts +2 -0
- package/dist/types/src/operations/sources/feed-fetcher.test.d.ts.map +1 -0
- package/dist/types/src/operations/sources/http.d.ts +9 -0
- package/dist/types/src/operations/sources/http.d.ts.map +1 -0
- package/dist/types/src/operations/sources/index.d.ts +6 -0
- package/dist/types/src/operations/sources/index.d.ts.map +1 -0
- package/dist/types/src/operations/sources/rss.d.ts +4 -0
- package/dist/types/src/operations/sources/rss.d.ts.map +1 -0
- package/dist/types/src/operations/sources/rss.test.d.ts +2 -0
- package/dist/types/src/operations/sources/rss.test.d.ts.map +1 -0
- package/dist/types/src/operations/sources/standard-site.d.ts +33 -0
- package/dist/types/src/operations/sources/standard-site.d.ts.map +1 -0
- package/dist/types/src/operations/sync-feed.d.ts +5 -0
- package/dist/types/src/operations/sync-feed.d.ts.map +1 -0
- package/dist/types/src/operations/sync-feed.test.d.ts +2 -0
- package/dist/types/src/operations/sync-feed.test.d.ts.map +1 -0
- package/dist/types/src/operations/util.d.ts +25 -0
- package/dist/types/src/operations/util.d.ts.map +1 -0
- package/dist/types/src/operations/util.test.d.ts +2 -0
- package/dist/types/src/operations/util.test.d.ts.map +1 -0
- package/dist/types/src/paths.d.ts +3 -0
- package/dist/types/src/paths.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/plugin.workerd.d.ts +3 -0
- package/dist/types/src/plugin.workerd.d.ts.map +1 -0
- package/dist/types/src/skills/index.d.ts +2 -0
- package/dist/types/src/skills/index.d.ts.map +1 -0
- package/dist/types/src/skills/magazine-skill.d.ts +4 -0
- package/dist/types/src/skills/magazine-skill.d.ts.map +1 -0
- package/dist/types/src/stories/ArticleExtractor.stories.d.ts +267 -0
- package/dist/types/src/stories/ArticleExtractor.stories.d.ts.map +1 -0
- package/dist/types/src/stories/MagazineCurate.stories.d.ts +32 -0
- package/dist/types/src/stories/MagazineCurate.stories.d.ts.map +1 -0
- package/dist/types/src/stories/theregister-fixture.test.d.ts +2 -0
- package/dist/types/src/stories/theregister-fixture.test.d.ts.map +1 -0
- package/dist/types/src/templates/magazine-curation.d.ts +7 -0
- package/dist/types/src/templates/magazine-curation.d.ts.map +1 -0
- package/dist/types/src/testing/builder.d.ts +28 -0
- package/dist/types/src/testing/builder.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +247 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types/CreateSubscription.d.ts +29 -0
- package/dist/types/src/types/CreateSubscription.d.ts.map +1 -0
- package/dist/types/src/types/FeedOperation.d.ts +52 -0
- package/dist/types/src/types/FeedOperation.d.ts.map +1 -0
- package/dist/types/src/types/Magazine.d.ts +87 -0
- package/dist/types/src/types/Magazine.d.ts.map +1 -0
- package/dist/types/src/types/Magazine.test.d.ts +2 -0
- package/dist/types/src/types/Magazine.test.d.ts.map +1 -0
- package/dist/types/src/types/Subscription.d.ts +144 -0
- package/dist/types/src/types/Subscription.d.ts.map +1 -0
- package/dist/types/src/types/Subscription.test.d.ts +2 -0
- package/dist/types/src/types/Subscription.test.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +5 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/util/date.d.ts +8 -0
- package/dist/types/src/util/date.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +4 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/post-content.d.ts +14 -0
- package/dist/types/src/util/post-content.d.ts.map +1 -0
- package/dist/types/src/util/text.d.ts +18 -0
- package/dist/types/src/util/text.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dx.config.ts +48 -0
- package/package.json +164 -0
- package/src/MagazinePlugin.test.ts +36 -0
- package/src/MagazinePlugin.tsx +61 -0
- package/src/MagazinePlugin.workerd.ts +31 -0
- package/src/atoms/atoms.test.ts +323 -0
- package/src/atoms/index.ts +10 -0
- package/src/atoms/magazine-posts.ts +70 -0
- package/src/atoms/post-content.ts +34 -0
- package/src/atoms/post-curation.ts +36 -0
- package/src/atoms/post-display.ts +59 -0
- package/src/atoms/post-read.ts +40 -0
- package/src/atoms/post-tags.ts +66 -0
- package/src/capabilities/app-graph-builder.ts +125 -0
- package/src/capabilities/create-object.ts +127 -0
- package/src/capabilities/index.ts +17 -0
- package/src/capabilities/navigation-resolver.ts +21 -0
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +53 -0
- package/src/capabilities/routine-templates.ts +16 -0
- package/src/capabilities/skill-definition.ts +14 -0
- package/src/components/PostContent/PostContent.test.ts +81 -0
- package/src/components/PostContent/PostContent.tsx +111 -0
- package/src/components/PostContent/index.ts +5 -0
- package/src/components/PostStack/PostStack.stories.tsx +39 -0
- package/src/components/PostStack/PostStack.tsx +151 -0
- package/src/components/PostStack/index.ts +5 -0
- package/src/components/SubscriptionStack/SubscriptionStack.stories.tsx +52 -0
- package/src/components/SubscriptionStack/SubscriptionStack.tsx +161 -0
- package/src/components/SubscriptionStack/index.ts +5 -0
- package/src/components/index.ts +7 -0
- package/src/containers/FeedArticle/FeedArticle.stories.tsx +102 -0
- package/src/containers/FeedArticle/FeedArticle.tsx +68 -0
- package/src/containers/FeedArticle/FeedToolbar.tsx +47 -0
- package/src/containers/FeedArticle/index.ts +5 -0
- package/src/containers/FeedProperties/FeedProperties.tsx +107 -0
- package/src/containers/FeedProperties/index.ts +5 -0
- package/src/containers/MagazineArticle/MagazineArticle.stories.tsx +244 -0
- package/src/containers/MagazineArticle/MagazineArticle.tsx +146 -0
- package/src/containers/MagazineArticle/MagazineTile.tsx +88 -0
- package/src/containers/MagazineArticle/index.ts +5 -0
- package/src/containers/MagazineArticle/useToolbar.tsx +145 -0
- package/src/containers/PostArticle/PostArticle.stories.tsx +117 -0
- package/src/containers/PostArticle/PostArticle.tsx +140 -0
- package/src/containers/PostArticle/PostToolbar.tsx +120 -0
- package/src/containers/PostArticle/index.ts +5 -0
- package/src/containers/PostCard/PostCard.tsx +70 -0
- package/src/containers/PostCard/index.ts +5 -0
- package/src/containers/SubscriptionsArticle/SubscriptionsArticle.stories.tsx +80 -0
- package/src/containers/SubscriptionsArticle/SubscriptionsArticle.tsx +99 -0
- package/src/containers/SubscriptionsArticle/index.ts +5 -0
- package/src/containers/index.ts +11 -0
- package/src/index.ts +6 -0
- package/src/meta.ts +9 -0
- package/src/operations/clear-magazine.ts +83 -0
- package/src/operations/curate-magazine.skill.conversations.json +1 -0
- package/src/operations/curate-magazine.skill.test.ts +167 -0
- package/src/operations/curate-magazine.test.ts +91 -0
- package/src/operations/curate-magazine.ts +178 -0
- package/src/operations/extraction/article.test.ts +154 -0
- package/src/operations/extraction/article.ts +270 -0
- package/src/operations/extraction/index.ts +5 -0
- package/src/operations/fetch-article-content.ts +27 -0
- package/src/operations/index.ts +13 -0
- package/src/operations/load-post-content.ts +76 -0
- package/src/operations/sources/article.ts +122 -0
- package/src/operations/sources/cors.ts +19 -0
- package/src/operations/sources/feed-fetcher.test.ts +200 -0
- package/src/operations/sources/feed-fetcher.ts +26 -0
- package/src/operations/sources/http.ts +42 -0
- package/src/operations/sources/index.ts +9 -0
- package/src/operations/sources/rss.test.ts +201 -0
- package/src/operations/sources/rss.ts +138 -0
- package/src/operations/sources/standard-site.ts +381 -0
- package/src/operations/sources/testing/feed.xml +477 -0
- package/src/operations/sync-feed.test.ts +146 -0
- package/src/operations/sync-feed.ts +140 -0
- package/src/operations/util.test.ts +67 -0
- package/src/operations/util.ts +65 -0
- package/src/paths.ts +14 -0
- package/src/plugin.ts +11 -0
- package/src/plugin.workerd.ts +6 -0
- package/src/skills/index.ts +5 -0
- package/src/skills/magazine-skill.ts +45 -0
- package/src/stories/ArticleExtractor.stories.tsx +204 -0
- package/src/stories/MagazineCurate.stories.tsx +217 -0
- package/src/stories/fixtures/theregister-ai.xml +45 -0
- package/src/stories/theregister-fixture.test.ts +35 -0
- package/src/templates/magazine-curation.ts +47 -0
- package/src/testing/builder.ts +77 -0
- package/src/testing/index.ts +5 -0
- package/src/translations.ts +81 -0
- package/src/types/CreateSubscription.ts +61 -0
- package/src/types/FeedOperation.ts +134 -0
- package/src/types/Magazine.test.ts +69 -0
- package/src/types/Magazine.ts +214 -0
- package/src/types/Subscription.test.ts +171 -0
- package/src/types/Subscription.ts +366 -0
- package/src/types/index.ts +8 -0
- package/src/util/date.ts +27 -0
- package/src/util/index.ts +7 -0
- package/src/util/post-content.ts +19 -0
- package/src/util/text.ts +98 -0
- package/src/vite-env.d.ts +10 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-J5LGTIGS.mjs";
|
|
4
|
+
|
|
5
|
+
// src/types/CreateSubscription.ts
|
|
6
|
+
var CreateSubscription_exports = {};
|
|
7
|
+
__export(CreateSubscription_exports, {
|
|
8
|
+
HandleSchema: () => HandleSchema,
|
|
9
|
+
RssCreateBase: () => RssCreateBase,
|
|
10
|
+
StandardSiteCreateBase: () => StandardSiteCreateBase,
|
|
11
|
+
isHandle: () => isHandle,
|
|
12
|
+
isUrl: () => isUrl,
|
|
13
|
+
makeSubscriptionFromCreate: () => makeSubscriptionFromCreate
|
|
14
|
+
});
|
|
15
|
+
import * as Schema2 from "effect/Schema";
|
|
16
|
+
import { Format } from "@dxos/echo";
|
|
17
|
+
|
|
18
|
+
// src/types/Subscription.ts
|
|
19
|
+
var Subscription_exports = {};
|
|
20
|
+
__export(Subscription_exports, {
|
|
21
|
+
DEFAULT_KEEP: () => DEFAULT_KEEP,
|
|
22
|
+
FeedType: () => FeedType,
|
|
23
|
+
Post: () => Post,
|
|
24
|
+
PostContent: () => PostContent,
|
|
25
|
+
PostState: () => PostState,
|
|
26
|
+
SYSTEM_TAGS: () => SYSTEM_TAGS,
|
|
27
|
+
Subscription: () => Subscription,
|
|
28
|
+
appendPostContent: () => appendPostContent,
|
|
29
|
+
findPostContent: () => findPostContent,
|
|
30
|
+
findSystemTagUri: () => findSystemTagUri,
|
|
31
|
+
getPostSubscription: () => getPostSubscription,
|
|
32
|
+
getReadAt: () => getReadAt,
|
|
33
|
+
hasTag: () => hasTag,
|
|
34
|
+
instanceOf: () => instanceOf,
|
|
35
|
+
makePost: () => makePost,
|
|
36
|
+
makeSubscription: () => makeSubscription,
|
|
37
|
+
pickLatestPostContent: () => pickLatestPostContent,
|
|
38
|
+
queryPostContentForPost: () => queryPostContentForPost,
|
|
39
|
+
setReadAt: () => setReadAt,
|
|
40
|
+
setTag: () => setTag
|
|
41
|
+
});
|
|
42
|
+
import * as Effect from "effect/Effect";
|
|
43
|
+
import * as Schema from "effect/Schema";
|
|
44
|
+
import { Annotation, Database, DXN, Feed, Filter, Obj, Query, Ref, Scope, Tag, Type } from "@dxos/echo";
|
|
45
|
+
import { FormInputAnnotation, LabelAnnotation } from "@dxos/echo/Annotation";
|
|
46
|
+
import { EffectEx } from "@dxos/effect";
|
|
47
|
+
import { FactoryAnnotation, FeedAnnotation, StateMap, TagIndex } from "@dxos/schema";
|
|
48
|
+
var FeedType = Schema.Literal("standard-site", "rss", "bluesky");
|
|
49
|
+
var SYSTEM_TAGS = {
|
|
50
|
+
starred: {
|
|
51
|
+
key: {
|
|
52
|
+
source: "org.dxos.plugin.magazine",
|
|
53
|
+
id: "starred"
|
|
54
|
+
},
|
|
55
|
+
label: "Starred",
|
|
56
|
+
hue: "amber"
|
|
57
|
+
},
|
|
58
|
+
archived: {
|
|
59
|
+
key: {
|
|
60
|
+
source: "org.dxos.plugin.magazine",
|
|
61
|
+
id: "archived"
|
|
62
|
+
},
|
|
63
|
+
label: "Archived",
|
|
64
|
+
hue: "neutral"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var PostState = Schema.Struct({
|
|
68
|
+
/** ISO 8601 timestamp when first opened. */
|
|
69
|
+
readAt: Schema.optional(Schema.String)
|
|
70
|
+
});
|
|
71
|
+
var DEFAULT_KEEP = 10;
|
|
72
|
+
var Subscription = class extends Type.makeObject(DXN.make("org.dxos.type.subscription.feed", "0.1.0"))(Schema.Struct({
|
|
73
|
+
/** User-facing title of the feed. */
|
|
74
|
+
name: Schema.String.pipe(Schema.optional),
|
|
75
|
+
/** The URL of the RSS/Atom feed or AT Protocol handle/DID. */
|
|
76
|
+
url: Schema.String.pipe(Schema.optional),
|
|
77
|
+
/** Protocol type — determines which fetcher is used for sync. */
|
|
78
|
+
type: FeedType.pipe(Schema.optional),
|
|
79
|
+
/** Description of the feed. */
|
|
80
|
+
description: Schema.String.pipe(Schema.optional),
|
|
81
|
+
/** URL of the feed's associated website. */
|
|
82
|
+
link: Schema.String.pipe(Schema.optional),
|
|
83
|
+
/** URL of the feed's icon/image. */
|
|
84
|
+
iconUrl: Schema.String.pipe(Schema.optional),
|
|
85
|
+
/**
|
|
86
|
+
* Maximum number of (non-starred) Posts retained in the feed's queue when syncing.
|
|
87
|
+
* Older posts beyond this bound are dropped; starred posts are preserved regardless.
|
|
88
|
+
* Defaults to {@link DEFAULT_KEEP} when unset.
|
|
89
|
+
*/
|
|
90
|
+
keep: Schema.Number.pipe(Schema.annotations({
|
|
91
|
+
title: "Keep",
|
|
92
|
+
description: "Number of synced items."
|
|
93
|
+
}), Schema.optional),
|
|
94
|
+
/** Opaque sync cursor — protocol-specific. */
|
|
95
|
+
cursor: Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional),
|
|
96
|
+
/** Backing ECHO feed (queue) for Posts: immutable feed entries appended by sync. */
|
|
97
|
+
feed: Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false)),
|
|
98
|
+
/**
|
|
99
|
+
* Backing ECHO feed (queue) for fetched article bodies — one
|
|
100
|
+
* {@link PostContent} entry per Post whose content has been loaded.
|
|
101
|
+
*
|
|
102
|
+
* Feeds (not the {@link postState} side map) are the right home for big
|
|
103
|
+
* immutable payloads: they're append-only, lazily replicated, and don't
|
|
104
|
+
* inflate the Subscription document. The side map keeps only the small
|
|
105
|
+
* per-Post user state (read/archived/star/imageUrl).
|
|
106
|
+
*
|
|
107
|
+
* Optional for backwards compatibility with older Subscription documents
|
|
108
|
+
* that pre-date this feed; new subscriptions always have one via
|
|
109
|
+
* {@link makeSubscription}.
|
|
110
|
+
*/
|
|
111
|
+
contentFeed: Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false), Schema.optional),
|
|
112
|
+
/**
|
|
113
|
+
* Per-Post mutable state keyed by Post id, shared across every Magazine that references the Post.
|
|
114
|
+
* Posts live immutably in the `feed` queue; their `readAt` marker lives here. (`snippet`/`imageUrl`
|
|
115
|
+
* are derived from the Post, or refined onto `contentFeed` entries — not stored here; star/archive
|
|
116
|
+
* are tags — see `tags`.)
|
|
117
|
+
*/
|
|
118
|
+
postState: Ref.Ref(StateMap.StateMap).pipe(FormInputAnnotation.set(false)),
|
|
119
|
+
/**
|
|
120
|
+
* Per-Post tags keyed by tag uri → Post ids. Boolean flags (starred, archived — see
|
|
121
|
+
* {@link SYSTEM_TAGS}) are modelled as {@link Tag} objects so they
|
|
122
|
+
* participate in the space-wide tag system. Stored as a child {@link TagIndex} object.
|
|
123
|
+
*/
|
|
124
|
+
tags: Ref.Ref(TagIndex.TagIndex).pipe(FormInputAnnotation.set(false))
|
|
125
|
+
}).pipe(LabelAnnotation.set([
|
|
126
|
+
"name",
|
|
127
|
+
"url"
|
|
128
|
+
]), Annotation.IconAnnotation.set({
|
|
129
|
+
icon: "ph--rss--regular",
|
|
130
|
+
hue: "indigo"
|
|
131
|
+
}), FeedAnnotation.set(true), FactoryAnnotation.set((values) => makeSubscription(values)))) {
|
|
132
|
+
};
|
|
133
|
+
var instanceOf = (value) => Obj.instanceOf(Subscription, value);
|
|
134
|
+
var makeSubscription = (props = {}) => {
|
|
135
|
+
const postFeed = Feed.make();
|
|
136
|
+
const contentFeed = Feed.make();
|
|
137
|
+
const postState = StateMap.make();
|
|
138
|
+
const tags = TagIndex.make();
|
|
139
|
+
const subscription = Obj.make(Subscription, {
|
|
140
|
+
feed: Ref.make(postFeed),
|
|
141
|
+
contentFeed: Ref.make(contentFeed),
|
|
142
|
+
postState: Ref.make(postState),
|
|
143
|
+
tags: Ref.make(tags),
|
|
144
|
+
...props
|
|
145
|
+
});
|
|
146
|
+
Obj.setParent(postFeed, subscription);
|
|
147
|
+
Obj.setParent(contentFeed, subscription);
|
|
148
|
+
Obj.setParent(postState, subscription);
|
|
149
|
+
Obj.setParent(tags, subscription);
|
|
150
|
+
return subscription;
|
|
151
|
+
};
|
|
152
|
+
var Post = class extends Type.makeObject(DXN.make("org.dxos.type.subscription.post", "0.1.0"))(Schema.Struct({
|
|
153
|
+
/** Source subscription feed; populated by `SyncSubscription` so curated posts can show provenance. */
|
|
154
|
+
source: Ref.Ref(Subscription).pipe(FormInputAnnotation.set(false), Schema.optional),
|
|
155
|
+
/** Post title. */
|
|
156
|
+
title: Schema.String.pipe(Schema.optional),
|
|
157
|
+
/** URL link to the original article. */
|
|
158
|
+
link: Schema.String.pipe(Schema.optional),
|
|
159
|
+
/** Plain-text or summary. */
|
|
160
|
+
description: Schema.String.pipe(Schema.optional),
|
|
161
|
+
/** Plain-text or HTML content. */
|
|
162
|
+
content: Schema.String.pipe(Schema.optional),
|
|
163
|
+
/** Author name. */
|
|
164
|
+
author: Schema.String.pipe(Schema.optional),
|
|
165
|
+
/** ISO 8601 publication date. */
|
|
166
|
+
published: Schema.String.pipe(Schema.optional),
|
|
167
|
+
/** Unique identifier (guid) from the feed. */
|
|
168
|
+
guid: Schema.String.pipe(Schema.optional)
|
|
169
|
+
}).pipe(LabelAnnotation.set([
|
|
170
|
+
"title"
|
|
171
|
+
]), Annotation.IconAnnotation.set({
|
|
172
|
+
icon: "ph--article--regular",
|
|
173
|
+
hue: "orange"
|
|
174
|
+
}))) {
|
|
175
|
+
};
|
|
176
|
+
var makePost = (props = {}) => Obj.make(Post, props);
|
|
177
|
+
var PostContent = class extends Type.makeObject(DXN.make("org.dxos.type.subscription.postContent", "0.1.0"))(Schema.Struct({
|
|
178
|
+
/** Source Post (in the Subscription's `feed` queue). */
|
|
179
|
+
post: Ref.Ref(Post).pipe(FormInputAnnotation.set(false)),
|
|
180
|
+
/** Extracted article body, in Markdown. */
|
|
181
|
+
text: Schema.String,
|
|
182
|
+
/** Refined snippet derived from the full article (preferred over the description-derived one). */
|
|
183
|
+
snippet: Schema.optional(Schema.String),
|
|
184
|
+
/** Refined hero image derived from the full article (preferred over the description-derived one). */
|
|
185
|
+
imageUrl: Schema.optional(Schema.String),
|
|
186
|
+
/** ISO 8601 timestamp when the content was fetched. */
|
|
187
|
+
fetchedAt: Schema.String
|
|
188
|
+
}).pipe(Annotation.HiddenAnnotation.set(true))) {
|
|
189
|
+
};
|
|
190
|
+
var getReadAt = (subscription, postId) => {
|
|
191
|
+
const stateMap = subscription?.postState.target;
|
|
192
|
+
return stateMap ? StateMap.bind(stateMap).get(postId).readAt : void 0;
|
|
193
|
+
};
|
|
194
|
+
var setReadAt = (subscription, postId, value) => {
|
|
195
|
+
const stateMap = subscription.postState.target;
|
|
196
|
+
if (stateMap) {
|
|
197
|
+
StateMap.bind(stateMap).patch(postId, {
|
|
198
|
+
readAt: value
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var findSystemTagUri = async (db, which) => {
|
|
203
|
+
const [currentTag] = await db.query(Filter.foreignKeys(Tag.Tag, [
|
|
204
|
+
SYSTEM_TAGS[which].key
|
|
205
|
+
])).run();
|
|
206
|
+
if (currentTag) {
|
|
207
|
+
return Obj.getURI(currentTag).toString();
|
|
208
|
+
}
|
|
209
|
+
const legacyKey = {
|
|
210
|
+
source: "org.dxos.plugin.feed",
|
|
211
|
+
id: SYSTEM_TAGS[which].key.id
|
|
212
|
+
};
|
|
213
|
+
const [legacyTag] = await db.query(Filter.foreignKeys(Tag.Tag, [
|
|
214
|
+
legacyKey
|
|
215
|
+
])).run();
|
|
216
|
+
return legacyTag ? Obj.getURI(legacyTag).toString() : void 0;
|
|
217
|
+
};
|
|
218
|
+
var hasTag = (subscription, postId, tagUri) => {
|
|
219
|
+
const tagIndex = subscription?.tags.target;
|
|
220
|
+
return !!(tagIndex && tagUri) && TagIndex.bind(tagIndex).objects(tagUri).includes(postId);
|
|
221
|
+
};
|
|
222
|
+
var setTag = async (subscription, postId, db, which, value) => {
|
|
223
|
+
const tag = await Tag.findOrCreate(db, SYSTEM_TAGS[which]);
|
|
224
|
+
const uri = Obj.getURI(tag).toString();
|
|
225
|
+
const tagIndex = subscription.tags.target;
|
|
226
|
+
if (!tagIndex) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const tags = TagIndex.bind(tagIndex);
|
|
230
|
+
if (value) {
|
|
231
|
+
tags.setTag(uri, postId);
|
|
232
|
+
} else {
|
|
233
|
+
tags.unsetTag(uri, postId);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
var getPostSubscription = (post) => post.source?.target;
|
|
237
|
+
var queryPostContentForPost = (subscription, post) => {
|
|
238
|
+
const postFeed = subscription.feed?.target;
|
|
239
|
+
const contentFeed = subscription.contentFeed?.target;
|
|
240
|
+
if (!postFeed || !contentFeed) {
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
const postFeedUri = Obj.getURI(postFeed);
|
|
244
|
+
const contentFeedUri = Obj.getURI(contentFeed);
|
|
245
|
+
return Query.select(Filter.id(post.id)).referencedBy(PostContent, "post").from(Scope.feed(postFeedUri), Scope.feed(contentFeedUri));
|
|
246
|
+
};
|
|
247
|
+
var pickLatestPostContent = (entries) => {
|
|
248
|
+
if (entries.length === 0) {
|
|
249
|
+
return void 0;
|
|
250
|
+
}
|
|
251
|
+
return [
|
|
252
|
+
...entries
|
|
253
|
+
].sort((entryA, entryB) => entryB.fetchedAt.localeCompare(entryA.fetchedAt))[0];
|
|
254
|
+
};
|
|
255
|
+
var findPostContent = async (subscription, post) => {
|
|
256
|
+
const db = Obj.getDatabase(subscription);
|
|
257
|
+
const query = queryPostContentForPost(subscription, post);
|
|
258
|
+
if (!db || !query) {
|
|
259
|
+
return void 0;
|
|
260
|
+
}
|
|
261
|
+
return pickLatestPostContent(await db.query(query).run());
|
|
262
|
+
};
|
|
263
|
+
var ensureContentFeed = (subscription) => {
|
|
264
|
+
const existing = subscription.contentFeed?.target;
|
|
265
|
+
if (existing) {
|
|
266
|
+
return existing;
|
|
267
|
+
}
|
|
268
|
+
const created = Feed.make();
|
|
269
|
+
Obj.update(subscription, (subscription2) => {
|
|
270
|
+
const mutable = subscription2;
|
|
271
|
+
mutable.contentFeed = Ref.make(created);
|
|
272
|
+
});
|
|
273
|
+
Obj.setParent(created, subscription);
|
|
274
|
+
return created;
|
|
275
|
+
};
|
|
276
|
+
var appendPostContent = async (space, subscription, entry) => {
|
|
277
|
+
const echoFeed = ensureContentFeed(subscription);
|
|
278
|
+
const content = Obj.make(PostContent, {
|
|
279
|
+
post: Ref.fromURI(Obj.getURI(entry.post)),
|
|
280
|
+
text: entry.text,
|
|
281
|
+
...entry.snippet ? {
|
|
282
|
+
snippet: entry.snippet
|
|
283
|
+
} : {},
|
|
284
|
+
...entry.imageUrl ? {
|
|
285
|
+
imageUrl: entry.imageUrl
|
|
286
|
+
} : {},
|
|
287
|
+
fetchedAt: entry.fetchedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
288
|
+
});
|
|
289
|
+
await Feed.append(echoFeed, [
|
|
290
|
+
content
|
|
291
|
+
]).pipe(Effect.provide(Database.layer(space.db)), EffectEx.runAndForwardErrors);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// src/types/CreateSubscription.ts
|
|
295
|
+
var HandleSchema = Schema2.String.pipe(Schema2.pattern(/^@?([\da-z-]+\.)+[a-z]{2,}$|^did:[a-z]+:[a-zA-Z0-9._%:-]+$/i));
|
|
296
|
+
var isHandle = Schema2.is(HandleSchema);
|
|
297
|
+
var isUrl = Schema2.is(Format.URL);
|
|
298
|
+
var StandardSiteCreateBase = Schema2.Struct({
|
|
299
|
+
type: Schema2.Literal("standard-site"),
|
|
300
|
+
handle: HandleSchema.annotations({
|
|
301
|
+
title: "Handle",
|
|
302
|
+
description: "atproto handle, e.g. dxos.org."
|
|
303
|
+
}),
|
|
304
|
+
// No `name`: the feed name is taken from the selected publication (resolved by `fetchStandardSite`).
|
|
305
|
+
publication: Schema2.String.annotations({
|
|
306
|
+
title: "Publication",
|
|
307
|
+
description: "Choose a publication."
|
|
308
|
+
})
|
|
309
|
+
});
|
|
310
|
+
var RssCreateBase = Schema2.Struct({
|
|
311
|
+
type: Schema2.Literal("rss"),
|
|
312
|
+
url: Format.URL.annotations({
|
|
313
|
+
title: "URL",
|
|
314
|
+
description: "RSS feed URL."
|
|
315
|
+
}),
|
|
316
|
+
name: Schema2.optional(Schema2.String.annotations({
|
|
317
|
+
title: "Name"
|
|
318
|
+
}))
|
|
319
|
+
});
|
|
320
|
+
var makeSubscriptionFromCreate = (input) => {
|
|
321
|
+
switch (input.type) {
|
|
322
|
+
case "standard-site":
|
|
323
|
+
return makeSubscription({
|
|
324
|
+
type: "standard-site",
|
|
325
|
+
url: input.publication
|
|
326
|
+
});
|
|
327
|
+
case "rss":
|
|
328
|
+
return makeSubscription({
|
|
329
|
+
type: "rss",
|
|
330
|
+
url: input.url,
|
|
331
|
+
name: input.name
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/types/FeedOperation.ts
|
|
337
|
+
var FeedOperation_exports = {};
|
|
338
|
+
__export(FeedOperation_exports, {
|
|
339
|
+
ClearMagazine: () => ClearMagazine,
|
|
340
|
+
CurateMagazine: () => CurateMagazine,
|
|
341
|
+
FetchArticleContent: () => FetchArticleContent,
|
|
342
|
+
LoadPostContent: () => LoadPostContent,
|
|
343
|
+
SyncFeed: () => SyncFeed
|
|
344
|
+
});
|
|
345
|
+
import * as Schema4 from "effect/Schema";
|
|
346
|
+
import { Operation } from "@dxos/compute";
|
|
347
|
+
import { Database as Database2, DXN as DXN3, Ref as Ref3, Registry } from "@dxos/echo";
|
|
348
|
+
import { meta } from "#meta";
|
|
349
|
+
|
|
350
|
+
// src/types/Magazine.ts
|
|
351
|
+
var Magazine_exports = {};
|
|
352
|
+
__export(Magazine_exports, {
|
|
353
|
+
CreateMagazineSchema: () => CreateMagazineSchema,
|
|
354
|
+
CurationOutput: () => CurationOutput,
|
|
355
|
+
DEFAULT_INSTRUCTIONS: () => DEFAULT_INSTRUCTIONS,
|
|
356
|
+
Magazine: () => Magazine,
|
|
357
|
+
PostState: () => PostState2,
|
|
358
|
+
SKILL_KEY: () => SKILL_KEY,
|
|
359
|
+
composeInstructions: () => composeInstructions,
|
|
360
|
+
getPostState: () => getPostState,
|
|
361
|
+
getRank: () => getRank,
|
|
362
|
+
instanceOf: () => instanceOf2,
|
|
363
|
+
make: () => make,
|
|
364
|
+
patchPostState: () => patchPostState,
|
|
365
|
+
setRank: () => setRank
|
|
366
|
+
});
|
|
367
|
+
import * as Schema3 from "effect/Schema";
|
|
368
|
+
import { AppAnnotation } from "@dxos/app-toolkit";
|
|
369
|
+
import { Instructions, Skill } from "@dxos/compute";
|
|
370
|
+
import { Annotation as Annotation2, DXN as DXN2, Obj as Obj2, Ref as Ref2, Type as Type2 } from "@dxos/echo";
|
|
371
|
+
import { FormInlineAnnotation, FormInputAnnotation as FormInputAnnotation2, LabelAnnotation as LabelAnnotation2 } from "@dxos/echo/Annotation";
|
|
372
|
+
import { StateMap as StateMap2 } from "@dxos/schema";
|
|
373
|
+
import { trim } from "@dxos/util";
|
|
374
|
+
var SKILL_KEY = "org.dxos.skill.magazine";
|
|
375
|
+
var DEFAULT_INSTRUCTIONS = trim`
|
|
376
|
+
You curate articles for a Magazine around the Topic described below.
|
|
377
|
+
|
|
378
|
+
Select only candidates that clearly match the Topic — quality over quantity.
|
|
379
|
+
|
|
380
|
+
Never select duplicate articles. Two candidates are duplicates if they share a link or guid, or if
|
|
381
|
+
their titles and content describe the same story (e.g. the same article syndicated by different
|
|
382
|
+
feeds). Keep only one of each — prefer the most complete or authoritative source — and skip the rest.
|
|
383
|
+
|
|
384
|
+
For each candidate you select, also produce:
|
|
385
|
+
- A concise 1-2 sentence snippet (plain text, no markdown) capturing why the article is relevant to
|
|
386
|
+
the Topic. If you read the full article, use it to write a richer snippet.
|
|
387
|
+
- The best hero image URL for the article, when one is available.
|
|
388
|
+
`;
|
|
389
|
+
var PostState2 = Schema3.Struct({
|
|
390
|
+
/** Agent-assigned relevance within this magazine (lower = more relevant). */
|
|
391
|
+
rank: Schema3.optional(Schema3.Number),
|
|
392
|
+
/** Agent-written concise snippet summarising the article in the context of this magazine's topic. */
|
|
393
|
+
snippet: Schema3.optional(Schema3.String),
|
|
394
|
+
/** Agent-selected hero image URL for this post in this magazine. */
|
|
395
|
+
imageUrl: Schema3.optional(Schema3.String)
|
|
396
|
+
});
|
|
397
|
+
var CurationOutput = Schema3.Struct({
|
|
398
|
+
posts: Schema3.Array(Schema3.Struct({
|
|
399
|
+
id: Obj2.ID,
|
|
400
|
+
/** Concise 1-2 sentence snippet summarising why this article is relevant to the magazine topic. */
|
|
401
|
+
snippet: Schema3.optional(Schema3.String),
|
|
402
|
+
/** Best image URL found for this article (from the post or fetched content). */
|
|
403
|
+
imageUrl: Schema3.optional(Schema3.String)
|
|
404
|
+
}))
|
|
405
|
+
});
|
|
406
|
+
var Magazine = class extends Type2.makeObject(DXN2.make("org.dxos.type.magazine", "0.2.0"))(Schema3.Struct({
|
|
407
|
+
/** User-facing title of the magazine. */
|
|
408
|
+
name: Schema3.String.pipe(Schema3.optional),
|
|
409
|
+
/** Feeds to pull content from. */
|
|
410
|
+
feeds: Schema3.Array(Ref2.Ref(Subscription)),
|
|
411
|
+
/** Curated Post refs (insertion order; UI displays newest-last reversed). */
|
|
412
|
+
posts: Schema3.Array(Ref2.Ref(Post)).pipe(FormInputAnnotation2.set(false)),
|
|
413
|
+
/**
|
|
414
|
+
* Curation Instructions, created with the magazine ({@link make}). Holds the editorial brief and
|
|
415
|
+
* references the Magazine skill. Rendered inline by the properties form (the Instructions'
|
|
416
|
+
* own fields), so the brief is edited there without a custom surface.
|
|
417
|
+
* Optional for backward compatibility; {@link CurateMagazine} and the toolbar require it.
|
|
418
|
+
*/
|
|
419
|
+
instructions: Ref2.Ref(Instructions.Instructions).pipe(FormInlineAnnotation.set(true), Schema3.optional),
|
|
420
|
+
/**
|
|
421
|
+
* Per-Post magazine-scoped curation state, keyed by Post id. Shared per-Post state (readAt,
|
|
422
|
+
* star/archive tags) lives on `Subscription`; snippet/imageUrl here are agent-written at
|
|
423
|
+
* curation time and take precedence over the RSS-derived defaults in display.
|
|
424
|
+
*/
|
|
425
|
+
postState: Ref2.Ref(StateMap2.StateMap).pipe(FormInputAnnotation2.set(false)),
|
|
426
|
+
/**
|
|
427
|
+
* Maximum number of (non-starred) curated Posts retained on the magazine after curation.
|
|
428
|
+
* Older posts beyond this bound are dropped; starred posts are preserved regardless.
|
|
429
|
+
* Defaults to {@link Subscription.DEFAULT_KEEP} when unset.
|
|
430
|
+
*/
|
|
431
|
+
keep: Schema3.Number.pipe(Schema3.annotations({
|
|
432
|
+
title: "Keep",
|
|
433
|
+
description: "Number of items to keep."
|
|
434
|
+
}), Schema3.optional)
|
|
435
|
+
}).pipe(LabelAnnotation2.set([
|
|
436
|
+
"name"
|
|
437
|
+
]), Annotation2.IconAnnotation.set({
|
|
438
|
+
icon: "ph--book-open-text--regular",
|
|
439
|
+
hue: "indigo"
|
|
440
|
+
}), AppAnnotation.SkillsAnnotation.set([
|
|
441
|
+
SKILL_KEY
|
|
442
|
+
]))) {
|
|
443
|
+
};
|
|
444
|
+
var instanceOf2 = (value) => Obj2.instanceOf(Magazine, value);
|
|
445
|
+
var make = (props = {}) => {
|
|
446
|
+
const postState = StateMap2.make();
|
|
447
|
+
const magazine = Obj2.make(Magazine, {
|
|
448
|
+
name: props.name,
|
|
449
|
+
feeds: props.feeds ?? [],
|
|
450
|
+
posts: props.posts ?? [],
|
|
451
|
+
keep: props.keep,
|
|
452
|
+
postState: Ref2.make(postState)
|
|
453
|
+
});
|
|
454
|
+
const instructions = Instructions.make({
|
|
455
|
+
name: props.name ? `${props.name} curation` : "Magazine curation",
|
|
456
|
+
text: composeInstructions(props.instructions),
|
|
457
|
+
skills: [
|
|
458
|
+
Ref2.fromURI(Skill.registryURI(SKILL_KEY))
|
|
459
|
+
],
|
|
460
|
+
// Bind the magazine as session context so the agent sees it, not only the candidate JSON input.
|
|
461
|
+
objects: [
|
|
462
|
+
Ref2.make(magazine)
|
|
463
|
+
],
|
|
464
|
+
// Declare the selection contract so the agent's completeJob carries the chosen Posts.
|
|
465
|
+
output: CurationOutput
|
|
466
|
+
});
|
|
467
|
+
Obj2.update(magazine, (magazine2) => {
|
|
468
|
+
magazine2.instructions = Ref2.make(instructions);
|
|
469
|
+
});
|
|
470
|
+
Obj2.setParent(instructions, magazine);
|
|
471
|
+
if (instructions.text.target) {
|
|
472
|
+
Obj2.setParent(instructions.text.target, instructions);
|
|
473
|
+
}
|
|
474
|
+
Obj2.setParent(postState, magazine);
|
|
475
|
+
return magazine;
|
|
476
|
+
};
|
|
477
|
+
var composeInstructions = (topic) => {
|
|
478
|
+
const trimmed = topic?.trim();
|
|
479
|
+
return trimmed ? `${DEFAULT_INSTRUCTIONS}
|
|
480
|
+
|
|
481
|
+
## Topic
|
|
482
|
+
|
|
483
|
+
${trimmed}` : DEFAULT_INSTRUCTIONS;
|
|
484
|
+
};
|
|
485
|
+
var CreateMagazineSchema = Schema3.Struct({
|
|
486
|
+
name: Schema3.optional(Schema3.String.annotations({
|
|
487
|
+
title: "Name"
|
|
488
|
+
})),
|
|
489
|
+
feeds: Schema3.Array(Ref2.Ref(Subscription)).annotations({
|
|
490
|
+
title: "Feeds"
|
|
491
|
+
}),
|
|
492
|
+
instructions: Schema3.optional(Schema3.String.annotations({
|
|
493
|
+
title: "Topic",
|
|
494
|
+
description: "Describe what content to curate."
|
|
495
|
+
}))
|
|
496
|
+
});
|
|
497
|
+
var getRank = (magazine, postId) => {
|
|
498
|
+
const stateMap = magazine?.postState.target;
|
|
499
|
+
return stateMap ? StateMap2.bind(stateMap).get(postId).rank : void 0;
|
|
500
|
+
};
|
|
501
|
+
var getPostState = (magazine, postId) => {
|
|
502
|
+
const stateMap = magazine?.postState.target;
|
|
503
|
+
return stateMap ? StateMap2.bind(stateMap).get(postId) : {};
|
|
504
|
+
};
|
|
505
|
+
var patchPostState = (magazine, postId, state) => {
|
|
506
|
+
const stateMap = magazine.postState.target;
|
|
507
|
+
if (stateMap) {
|
|
508
|
+
StateMap2.bind(stateMap).patch(postId, state);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
var setRank = (magazine, postId, rank) => patchPostState(magazine, postId, {
|
|
512
|
+
rank
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// src/types/FeedOperation.ts
|
|
516
|
+
var makeKey = (name) => DXN3.make(`${meta.profile.key}.operation.${name}`);
|
|
517
|
+
var SyncFeed = Operation.make({
|
|
518
|
+
meta: {
|
|
519
|
+
key: makeKey("syncFeed"),
|
|
520
|
+
name: "Sync Feed",
|
|
521
|
+
description: "Fetches RSS/Atom feed and writes posts to the ECHO feed.",
|
|
522
|
+
icon: "ph--arrows-clockwise--regular"
|
|
523
|
+
},
|
|
524
|
+
services: [
|
|
525
|
+
Database2.Service
|
|
526
|
+
],
|
|
527
|
+
input: Schema4.Struct({
|
|
528
|
+
feed: Ref3.Ref(Subscription)
|
|
529
|
+
}),
|
|
530
|
+
output: Schema4.Void
|
|
531
|
+
}).pipe(Operation.visible);
|
|
532
|
+
var FetchArticleContent = Operation.make({
|
|
533
|
+
meta: {
|
|
534
|
+
key: makeKey("fetchArticleContent"),
|
|
535
|
+
name: "Fetch Article Content",
|
|
536
|
+
description: "Fetches and extracts text + image URLs from a Post's article page.",
|
|
537
|
+
icon: "ph--article--regular"
|
|
538
|
+
},
|
|
539
|
+
input: Schema4.Struct({
|
|
540
|
+
post: Ref3.Ref(Post).annotations({
|
|
541
|
+
description: "The Post to fetch content for. The Post must have a link."
|
|
542
|
+
})
|
|
543
|
+
}),
|
|
544
|
+
output: Schema4.Struct({
|
|
545
|
+
text: Schema4.String.annotations({
|
|
546
|
+
description: "Extracted plain text from the article page."
|
|
547
|
+
}),
|
|
548
|
+
imageUrls: Schema4.Array(Schema4.String).annotations({
|
|
549
|
+
description: "Image URLs found on the page (og:image first, then <img> src values)."
|
|
550
|
+
})
|
|
551
|
+
}),
|
|
552
|
+
services: [
|
|
553
|
+
Database2.Service
|
|
554
|
+
]
|
|
555
|
+
});
|
|
556
|
+
var LoadPostContent = Operation.make({
|
|
557
|
+
meta: {
|
|
558
|
+
key: makeKey("loadPostContent"),
|
|
559
|
+
name: "Load Post Content",
|
|
560
|
+
description: "Fetches and stores the full article content on a Post.",
|
|
561
|
+
icon: "ph--download--regular"
|
|
562
|
+
},
|
|
563
|
+
input: Schema4.Struct({
|
|
564
|
+
post: Ref3.Ref(Post).annotations({
|
|
565
|
+
description: "The Post to load content for."
|
|
566
|
+
}),
|
|
567
|
+
force: Schema4.optional(Schema4.Boolean.annotations({
|
|
568
|
+
description: "Re-fetch and append fresh content even if an entry already exists (refresh)."
|
|
569
|
+
}))
|
|
570
|
+
}),
|
|
571
|
+
output: Schema4.Void
|
|
572
|
+
});
|
|
573
|
+
var CurateMagazine = Operation.make({
|
|
574
|
+
meta: {
|
|
575
|
+
key: makeKey("curateMagazine"),
|
|
576
|
+
name: "Curate Magazine",
|
|
577
|
+
description: "Syncs feeds, selects matching posts via the magazine skill, and applies per-feed keep limits.",
|
|
578
|
+
icon: "ph--sparkle--regular"
|
|
579
|
+
},
|
|
580
|
+
input: Schema4.Struct({
|
|
581
|
+
magazine: Ref3.Ref(Magazine).annotations({
|
|
582
|
+
description: "The Magazine to curate."
|
|
583
|
+
})
|
|
584
|
+
}),
|
|
585
|
+
output: Schema4.Struct({
|
|
586
|
+
synced: Schema4.Number.annotations({
|
|
587
|
+
description: "Number of feeds successfully synced."
|
|
588
|
+
}),
|
|
589
|
+
curated: Schema4.Number.annotations({
|
|
590
|
+
description: "Number of posts added to the magazine."
|
|
591
|
+
})
|
|
592
|
+
}),
|
|
593
|
+
// Database.Service for candidate collection, Registry.Service to resolve the methodology skill;
|
|
594
|
+
// sub-operations (SyncFeed, RunInstructions) resolve through the ambient Operation.Service invoker.
|
|
595
|
+
services: [
|
|
596
|
+
Database2.Service,
|
|
597
|
+
Registry.Service
|
|
598
|
+
]
|
|
599
|
+
}).pipe(Operation.visible);
|
|
600
|
+
var ClearMagazine = Operation.make({
|
|
601
|
+
meta: {
|
|
602
|
+
key: makeKey("clearMagazine"),
|
|
603
|
+
name: "Clear Magazine",
|
|
604
|
+
description: "Removes a Magazine's posts, keeping any that are starred.",
|
|
605
|
+
icon: "ph--trash--regular"
|
|
606
|
+
},
|
|
607
|
+
input: Schema4.Struct({
|
|
608
|
+
magazine: Ref3.Ref(Magazine).annotations({
|
|
609
|
+
description: "The Magazine to clear."
|
|
610
|
+
})
|
|
611
|
+
}),
|
|
612
|
+
output: Schema4.Void,
|
|
613
|
+
services: [
|
|
614
|
+
Database2.Service
|
|
615
|
+
]
|
|
616
|
+
}).pipe(Operation.visible);
|
|
617
|
+
|
|
618
|
+
export {
|
|
619
|
+
Subscription_exports,
|
|
620
|
+
CreateSubscription_exports,
|
|
621
|
+
Magazine_exports,
|
|
622
|
+
FeedOperation_exports
|
|
623
|
+
};
|
|
624
|
+
//# sourceMappingURL=chunk-OYCDRSWB.mjs.map
|