@zhin.js/plugin-rss 1.1.16 → 1.1.17

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/lib/runtime.d.ts CHANGED
@@ -20,5 +20,6 @@ export interface RssRuntime {
20
20
  readonly config: Readonly<RssConfig>;
21
21
  readonly outbound: RssOutboundPush | null;
22
22
  }
23
- export declare const rssRuntimeToken: import("zhin.js").Token<RssRuntime>;
23
+ export declare const rssRuntimeStore: import("zhin.js").PluginStore<RssRuntime, unknown>;
24
+ export declare const rssRuntimeToken: import("zhin.js").PluginStore<RssRuntime, unknown>;
24
25
  //# sourceMappingURL=runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IACpC,qGAAqG;IACrG,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,eAAe,qCAG3B,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IACpC,qGAAqG;IACrG,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,eAAe,oDAG3B,CAAC;AACF,eAAO,MAAM,eAAe,oDAAkB,CAAC"}
package/lib/runtime.js CHANGED
@@ -1,3 +1,4 @@
1
- import { createToken } from 'zhin.js';
2
- export const rssRuntimeToken = createToken('zhin.rss.runtime', 'Owner-scoped RSS runtime');
1
+ import { definePluginStore } from 'zhin.js';
2
+ export const rssRuntimeStore = definePluginStore('zhin.rss.runtime', 'Owner-scoped RSS runtime');
3
+ export const rssRuntimeToken = rssRuntimeStore;
3
4
  //# sourceMappingURL=runtime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwBtC,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CACxC,kBAAkB,EAClB,0BAA0B,CAC3B,CAAC"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAwB5C,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAC9C,kBAAkB,EAClB,0BAA0B,CAC3B,CAAC;AACF,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-rss",
3
- "version": "1.1.16",
3
+ "version": "1.1.17",
4
4
  "description": "RSS/Atom feed subscription plugin for Zhin.js (Plugin Runtime)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -42,26 +42,25 @@
42
42
  "license": "MIT",
43
43
  "dependencies": {
44
44
  "rss-parser": "^3.13.0",
45
- "@zhin.js/console-contract": "1.1.3",
46
- "@zhin.js/page": "1.1.15",
47
- "@zhin.js/client": "1.1.25",
48
- "@zhin.js/tool": "1.1.16",
49
- "@zhin.js/im-contract": "1.1.12",
50
- "@zhin.js/skill": "1.1.14"
45
+ "@zhin.js/im-contract": "1.1.13",
46
+ "@zhin.js/console-contract": "1.1.4",
47
+ "@zhin.js/page": "1.1.16",
48
+ "@zhin.js/skill": "1.1.15",
49
+ "@zhin.js/tool": "1.1.17"
51
50
  },
52
51
  "devDependencies": {
53
52
  "typescript": "^6.0.3",
54
53
  "vitest": "^4.1.10",
55
54
  "zod": "^4.4.3",
56
- "zhin.js": "1.1.22"
55
+ "zhin.js": "1.1.23"
57
56
  },
58
57
  "peerDependencies": {
59
58
  "zod": "^4.0.0",
60
- "@zhin.js/command": "^1.1.15",
61
- "@zhin.js/skill": "^1.1.14",
62
- "zhin.js": "^1.1.22",
63
- "@zhin.js/tool": "^1.1.16",
64
- "@zhin.js/page": "^1.1.15"
59
+ "@zhin.js/page": "^1.1.16",
60
+ "@zhin.js/skill": "^1.1.15",
61
+ "@zhin.js/tool": "^1.1.17",
62
+ "zhin.js": "^1.1.23",
63
+ "@zhin.js/command": "^1.1.16"
65
64
  },
66
65
  "peerDependenciesMeta": {
67
66
  "@zhin.js/command": {
@@ -1,6 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { definePage } from '@zhin.js/console-contract';
3
- import { createDeclarativePage } from '@zhin.js/client';
2
+ import { definePage, createDeclarativePage } from '@zhin.js/console-contract';
4
3
  export const meta = definePage({
5
4
  title: 'RSS 订阅',
6
5
  titleI18n: { en: 'RSS Subscriptions' },
@@ -1,5 +1,4 @@
1
- import { definePage } from '@zhin.js/console-contract';
2
- import { createDeclarativePage } from '@zhin.js/client';
1
+ import { definePage, createDeclarativePage } from '@zhin.js/console-contract';
3
2
 
4
3
  export interface RssSubscriptionItem {
5
4
  readonly id: string;
package/plugin.js CHANGED
@@ -1,15 +1,15 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { DataMigrationError, pluginDataMigrationProviderToken, TargetMigrationScopes, pluginTaskProviderToken } from 'zhin.js/plugin-runtime';
2
+ import { DataMigrationError, TargetMigrationScopes } from 'zhin.js/plugin-runtime';
3
3
  import { createSubscriptionTargetMigration, subscriptionMigrationScope } from "./lib/target-migration.js";
4
4
  import { projectLocaleToken, resolveLocale } from 'zhin.js/i18n';
5
- import { definePlugin, logger, databaseHostToken, outboundHostToken, pluginConsoleRpcToken, scheduleHostToken, } from 'zhin.js';
5
+ import { definePlugin, definePluginCapabilityGraph, logger, databaseHostToken, outboundHostToken, pluginConsoleRpcToken, pluginDataMigrationProviderToken, pluginTaskProviderToken, scheduleHostToken, } from 'zhin.js';
6
6
  import { createAdministratorRssState } from "./lib/storage.js";
7
7
  import { AdministratorRssTasks } from "./lib/admin-tasks.js";
8
8
  import { createRssConsoleRpc } from "./lib/console.js";
9
9
  import { resolveRssConfig } from "./lib/feed.js";
10
10
  import { createInMemoryRssDb, RSS_SEEN_TABLE, RSS_SUBS_TABLE, } from "./lib/db-store.js";
11
11
  import { cleanOldSeen, pollAllFeeds } from "./lib/poll.js";
12
- import { rssRuntimeToken } from "./lib/runtime.js";
12
+ import { rssRuntimeStore } from "./lib/runtime.js";
13
13
  function defineRssTables(db) {
14
14
  db.define(RSS_SUBS_TABLE, {
15
15
  url: { type: 'text', nullable: false },
@@ -43,6 +43,21 @@ export default definePlugin({
43
43
  metadata: {
44
44
  displayName: 'RSS',
45
45
  },
46
+ capabilityGraph: definePluginCapabilityGraph({
47
+ provides: [
48
+ rssRuntimeStore,
49
+ pluginConsoleRpcToken,
50
+ pluginDataMigrationProviderToken,
51
+ pluginTaskProviderToken,
52
+ ],
53
+ injects: [databaseHostToken, outboundHostToken, scheduleHostToken, projectLocaleToken],
54
+ features: {
55
+ commands: ['rss-add', 'rss-check', 'rss-list', 'rss-preview', 'rss-remove'],
56
+ skills: ['rss'],
57
+ tools: ['rss_list_subscriptions', 'rss_preview_feed'],
58
+ pages: ['index'],
59
+ },
60
+ }),
46
61
  setup(context) {
47
62
  const config = resolveRssConfig(context.config.get());
48
63
  const database = context.resources.has(databaseHostToken) ? context.resources.use(databaseHostToken) : undefined;
@@ -52,8 +67,9 @@ export default definePlugin({
52
67
  return host;
53
68
  })() : createInMemoryRssDb();
54
69
  const migrationScopes = database ? new TargetMigrationScopes({ pending: scope => scope.startsWith('historical:') }) : undefined;
55
- if (database && migrationScopes)
56
- context.resources.provide(pluginDataMigrationProviderToken, createSubscriptionTargetMigration({ database, scopes: migrationScopes }));
70
+ const dataMigration = database && migrationScopes
71
+ ? createSubscriptionTargetMigration({ database, scopes: migrationScopes })
72
+ : undefined;
57
73
  const outbound = context.resources.has(outboundHostToken) ? context.resources.use(outboundHostToken) : undefined;
58
74
  let outboundPush = null;
59
75
  if (outbound) {
@@ -69,15 +85,13 @@ export default definePlugin({
69
85
  await run();
70
86
  };
71
87
  }
72
- const runtime = Object.freeze({
88
+ const runtime = rssRuntimeStore.provide(context, Object.freeze({
73
89
  db,
74
90
  migrationScopes,
75
91
  locale: resolveLocale(context.resources.use(projectLocaleToken)),
76
92
  config: Object.freeze({ ...config }),
77
93
  outbound: outboundPush,
78
- });
79
- context.resources.provide(rssRuntimeToken, runtime);
80
- context.resources.provide(pluginConsoleRpcToken, createRssConsoleRpc(runtime));
94
+ }));
81
95
  // Keep optional in-memory/chat-only installations working. Administrator tasks
82
96
  // must have the real durable state port, exact outbound and an active scheduler.
83
97
  let administrator;
@@ -92,36 +106,40 @@ export default definePlugin({
92
106
  catch { /* No persistent state port: no administrator provider. */ }
93
107
  if (state) {
94
108
  administrator = new AdministratorRssTasks(createAdministratorRssState(database), outbound, config, undefined, runtime.locale);
95
- context.resources.provide(pluginTaskProviderToken, administrator);
96
109
  context.lifecycle.add(() => administrator?.stop());
97
110
  }
98
111
  }
99
- if (!context.resources.has(scheduleHostToken))
100
- return;
101
- const schedule = context.resources.use(scheduleHostToken);
102
- const dispose = schedule.register({
103
- id: 'rss/poll_feeds',
104
- cron: config.pollCron,
105
- description: 'Poll RSS subscriptions',
106
- async execute() {
107
- // Both pools share this existing registration. A slow chat feed does not
108
- // prevent administrator polling, and neither pool shares the other's cursor.
109
- const results = await Promise.allSettled([pollAllFeeds(runtime), administrator?.tick()]);
110
- // Keep the schedule lease until both pools drain, even if one fails.
111
- for (const result of results)
112
- if (result.status === 'rejected')
113
- throw result.reason;
114
- },
115
- });
116
- const disposeClean = schedule.register({
117
- id: 'rss/clean_old_seen',
118
- cron: '0 0 4 * * *',
119
- description: 'Clean seen records older than 7 days',
120
- async execute() {
121
- await cleanOldSeen(runtime);
122
- },
123
- });
124
- context.lifecycle.add(dispose);
125
- context.lifecycle.add(disposeClean);
112
+ if (context.resources.has(scheduleHostToken)) {
113
+ const schedule = context.resources.use(scheduleHostToken);
114
+ const dispose = schedule.register({
115
+ id: 'rss/poll_feeds',
116
+ cron: config.pollCron,
117
+ description: 'Poll RSS subscriptions',
118
+ async execute() {
119
+ // Both pools share this existing registration. A slow chat feed does not
120
+ // prevent administrator polling, and neither pool shares the other's cursor.
121
+ const results = await Promise.allSettled([pollAllFeeds(runtime), administrator?.tick()]);
122
+ // Keep the schedule lease until both pools drain, even if one fails.
123
+ for (const result of results)
124
+ if (result.status === 'rejected')
125
+ throw result.reason;
126
+ },
127
+ });
128
+ const disposeClean = schedule.register({
129
+ id: 'rss/clean_old_seen',
130
+ cron: '0 0 4 * * *',
131
+ description: 'Clean seen records older than 7 days',
132
+ async execute() {
133
+ await cleanOldSeen(runtime);
134
+ },
135
+ });
136
+ context.lifecycle.add(dispose);
137
+ context.lifecycle.add(disposeClean);
138
+ }
139
+ return {
140
+ consoleRpc: createRssConsoleRpc(runtime),
141
+ ...(dataMigration ? { dataMigration } : {}),
142
+ ...(administrator ? { tasks: administrator } : {}),
143
+ };
126
144
  },
127
145
  });
package/src/runtime.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { DeliveryTarget, TargetMigrationScopes } from 'zhin.js/plugin-runtime';
2
2
  import type { Locale } from 'zhin.js/i18n';
3
- import { createToken } from 'zhin.js';
3
+ import { definePluginStore } from 'zhin.js';
4
4
  import type { RssConfig } from './feed.js';
5
5
  import type { RssMemoryDb } from './memory-store.js';
6
6
  import type { ChannelInfo } from './channel.js';
@@ -24,7 +24,8 @@ export interface RssRuntime {
24
24
  readonly outbound: RssOutboundPush | null;
25
25
  }
26
26
 
27
- export const rssRuntimeToken = createToken<RssRuntime>(
27
+ export const rssRuntimeStore = definePluginStore<RssRuntime>(
28
28
  'zhin.rss.runtime',
29
29
  'Owner-scoped RSS runtime',
30
30
  );
31
+ export const rssRuntimeToken = rssRuntimeStore;