@ontrove/sdk 0.1.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +34 -33
- package/dist/define.d.ts +21 -21
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +25 -25
- package/dist/index.d.ts +12 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -10
- package/dist/manifest.d.ts +6 -6
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +7 -7
- package/dist/runtime.d.ts +21 -21
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +15 -15
- package/dist/types.d.ts +57 -55
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -7
- package/package.json +18 -5
- package/src/define.ts +28 -35
- package/src/index.ts +17 -16
- package/src/manifest.ts +10 -10
- package/src/runtime.ts +34 -34
- package/src/types.ts +57 -55
package/dist/runtime.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The local-run harness — what makes `trove
|
|
3
|
-
* work (
|
|
2
|
+
* The local-run harness — what makes `trove source dev` / `trove source test`
|
|
3
|
+
* work (sources/sdk-reference; the cursors guide).
|
|
4
4
|
*
|
|
5
|
-
* {@link
|
|
5
|
+
* {@link runSource} builds a {@link SourceContext} from a `{ config, cursor }`
|
|
6
6
|
* spec, invokes `sync(ctx)`, then normalizes and validates the result: it accepts
|
|
7
|
-
* either a `
|
|
8
|
-
* `id` (first occurrence wins, matching server-side `(
|
|
7
|
+
* either a `SourceSyncResult` or a bare `SourceDocument[]`, deduplicates by
|
|
8
|
+
* `id` (first occurrence wins, matching server-side `(feed, id)` dedup), and
|
|
9
9
|
* validates every document's required fields, surfacing problems clearly instead
|
|
10
10
|
* of pushing a malformed payload to the cloud.
|
|
11
11
|
*
|
|
12
12
|
* It is the symmetric sibling of `@ontrove/mcp`'s `dispatch`/`toFetchHandler`: that
|
|
13
|
-
* runs a tool call end-to-end without the hosted runtime; this runs a
|
|
13
|
+
* runs a tool call end-to-end without the hosted runtime; this runs a source
|
|
14
14
|
* sync end-to-end without the Mac app sync engine.
|
|
15
15
|
*
|
|
16
16
|
* @module
|
|
@@ -45,7 +45,7 @@ function validateDocument(doc, index) {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
* Normalize a `sync` return value to a {@link
|
|
48
|
+
* Normalize a `sync` return value to a {@link SourceSyncResult}, accepting a
|
|
49
49
|
* bare document array for convenience.
|
|
50
50
|
*
|
|
51
51
|
* @param value - The raw `sync` return value.
|
|
@@ -65,7 +65,7 @@ function normalizeResult(value) {
|
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
67
|
* Deduplicate documents by `id`, keeping the first occurrence (matching the
|
|
68
|
-
* server's `(
|
|
68
|
+
* server's `(feed, id)` dedup, which skips re-returned ids).
|
|
69
69
|
*
|
|
70
70
|
* @param documents - The validated documents.
|
|
71
71
|
* @returns The deduped documents and the count dropped.
|
|
@@ -85,22 +85,22 @@ function dedup(documents) {
|
|
|
85
85
|
return { unique, duplicatesSkipped };
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* Run a
|
|
88
|
+
* Run a source's `sync` against a built `ctx` and collect/validate the result.
|
|
89
89
|
*
|
|
90
|
-
* This is the harness the CLI drives for `trove
|
|
91
|
-
* test`: it builds the {@link
|
|
90
|
+
* This is the harness the CLI drives for `trove source dev` / `trove source
|
|
91
|
+
* test`: it builds the {@link SourceContext} from `{ config, cursor }`, runs
|
|
92
92
|
* `sync(ctx)`, normalizes a bare-array return, validates every document's
|
|
93
93
|
* required fields (clear, indexed errors), and dedups by `id`. Errors thrown by
|
|
94
94
|
* `sync` itself propagate unchanged so the CLI can report a failed run exactly as
|
|
95
95
|
* the Mac app would.
|
|
96
96
|
*
|
|
97
|
-
* @typeParam C - The shape of the
|
|
98
|
-
* @param
|
|
97
|
+
* @typeParam C - The shape of the source's typed `ctx.config` preferences.
|
|
98
|
+
* @param source - The source whose `sync` to run.
|
|
99
99
|
* @param options - The `{ config, cursor }` spec plus test injection points.
|
|
100
100
|
* @returns The validated, deduped {@link RunResult}.
|
|
101
101
|
* @throws {Error} If `sync` throws, returns a malformed value, or a document fails validation.
|
|
102
102
|
*/
|
|
103
|
-
export async function
|
|
103
|
+
export async function runSource(source, options = {}) {
|
|
104
104
|
const logs = [];
|
|
105
105
|
const cursor = options.cursor ?? { type: 'none' };
|
|
106
106
|
const fetchImpl = options.fetchImpl ?? ((url, init) => globalThis.fetch(url, init));
|
|
@@ -119,7 +119,7 @@ export async function runConnector(connector, options = {}) {
|
|
|
119
119
|
},
|
|
120
120
|
now,
|
|
121
121
|
};
|
|
122
|
-
const raw = await
|
|
122
|
+
const raw = await source.sync(ctx);
|
|
123
123
|
const result = normalizeResult(raw);
|
|
124
124
|
result.documents.forEach(validateDocument);
|
|
125
125
|
const { unique, duplicatesSkipped } = dedup(result.documents);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public type surface for the `@ontrove/sdk`
|
|
2
|
+
* Public type surface for the `@ontrove/sdk` source authoring library.
|
|
3
3
|
*
|
|
4
|
-
* These types describe the
|
|
5
|
-
* and the cursors
|
|
6
|
-
* an object with a `sync(ctx)` method that fetches
|
|
7
|
-
* documents to index. The SDK owns the document shape (which maps 1:1 onto the
|
|
4
|
+
* These types describe the source contract (see the sources SDK reference
|
|
5
|
+
* and the cursors guide on the docs site): a source is
|
|
6
|
+
* an object with a `sync(ctx)` method that fetches new content from the
|
|
7
|
+
* upstream system and returns documents to index. The SDK owns the document shape (which maps 1:1 onto the
|
|
8
8
|
* `IngestDocumentInput` wire type), the typed `ctx` capability object, the
|
|
9
9
|
* watermark/cursor model, and the local-run harness the CLI drives.
|
|
10
10
|
*
|
|
11
|
-
* It is the symmetric sibling of `@ontrove/mcp
|
|
12
|
-
*
|
|
11
|
+
* It is the symmetric sibling of `@ontrove/mcp` (the toolkit-authoring library —
|
|
12
|
+
* every toolkit runs as a full MCP server on Trove's cloud): a source returns
|
|
13
|
+
* documents to be _stored_ (batch `sync`); a toolkit's tools return results to
|
|
14
|
+
* be _read live_.
|
|
13
15
|
*
|
|
14
16
|
* @module
|
|
15
17
|
*/
|
|
@@ -17,9 +19,9 @@
|
|
|
17
19
|
* The default content type Trove assigns a document when it omits `contentType`.
|
|
18
20
|
* Mirrors the GraphQL `ContentType` enum surfaced on `IngestDocumentInput`.
|
|
19
21
|
*/
|
|
20
|
-
export type
|
|
22
|
+
export type SourceContentType = 'text' | 'transcript' | 'highlight' | 'bookmark';
|
|
21
23
|
/**
|
|
22
|
-
* A single document a
|
|
24
|
+
* A single document a source returns from `sync`. The fields map **1:1** onto
|
|
23
25
|
* the GraphQL `IngestDocumentInput` the Mac app pushes via `ingestDocuments`:
|
|
24
26
|
*
|
|
25
27
|
* | SDK field | `IngestDocumentInput` field |
|
|
@@ -35,15 +37,15 @@ export type ConnectorContentType = 'text' | 'transcript' | 'highlight' | 'bookma
|
|
|
35
37
|
* | `metadata` | `metadata` (JSON) |
|
|
36
38
|
* | `contentType` | `contentType` (ContentType) |
|
|
37
39
|
*
|
|
38
|
-
* Dedup is keyed on `(
|
|
40
|
+
* Dedup is keyed on `(feed, id)`: returning the same `id` twice is safe and is
|
|
39
41
|
* skipped on the server, so `sync` can be idempotent and retried freely. At least
|
|
40
42
|
* one of `text` or `audioUrl` must be present — an audio-only document triggers
|
|
41
43
|
* transcription (Whisper), and the transcript becomes the document text.
|
|
42
44
|
*/
|
|
43
|
-
export interface
|
|
45
|
+
export interface SourceDocument {
|
|
44
46
|
/**
|
|
45
|
-
* The stable external identifier from the
|
|
46
|
-
* the
|
|
47
|
+
* The stable external identifier from the upstream system — the dedup key
|
|
48
|
+
* within the feed. Maps to `IngestDocumentInput.externalId`. Use the native id (HN
|
|
47
49
|
* `objectID`, RSS `guid`, Notion page id), never a value that changes between
|
|
48
50
|
* runs.
|
|
49
51
|
*/
|
|
@@ -78,7 +80,7 @@ export interface ConnectorDocument {
|
|
|
78
80
|
/** Array of string tags. Maps to `IngestDocumentInput.tags`. */
|
|
79
81
|
tags?: string[];
|
|
80
82
|
/**
|
|
81
|
-
* Arbitrary
|
|
83
|
+
* Arbitrary source-specific JSON. Maps to `IngestDocumentInput.metadata`.
|
|
82
84
|
* **Never** put credentials or auth headers here.
|
|
83
85
|
*/
|
|
84
86
|
metadata?: Record<string, unknown>;
|
|
@@ -87,19 +89,19 @@ export interface ConnectorDocument {
|
|
|
87
89
|
* `IngestDocumentInput.contentType`. Defaults to `text` (transcribed audio
|
|
88
90
|
* becomes `transcript` automatically).
|
|
89
91
|
*/
|
|
90
|
-
contentType?:
|
|
92
|
+
contentType?: SourceContentType;
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
|
-
* A typed watermark describing how a
|
|
94
|
-
* `
|
|
95
|
-
*
|
|
95
|
+
* A typed watermark describing how a feed resumes between syncs. The opaque
|
|
96
|
+
* `Feed.cursor` string is parsed into one of these (see the cursors guide,
|
|
97
|
+
* watermark types).
|
|
96
98
|
*
|
|
97
|
-
* - `date` — the
|
|
99
|
+
* - `date` — the feed is time-ordered and supports "since <date>"
|
|
98
100
|
* filtering (RSS, most APIs); the newest `value` you push becomes the next
|
|
99
101
|
* cursor.
|
|
100
|
-
* - `idSet` — the
|
|
102
|
+
* - `idSet` — the feed has monotonic ids but no reliable date filter; advance
|
|
101
103
|
* to the highest id seen (`max`), optionally tracking a recent id set.
|
|
102
|
-
* - `none` — re-fetch everything each run and rely purely on `(
|
|
104
|
+
* - `none` — re-fetch everything each run and rely purely on `(feed, id)`
|
|
103
105
|
* dedup. Always correct, just less efficient.
|
|
104
106
|
*/
|
|
105
107
|
export type Watermark = {
|
|
@@ -113,35 +115,35 @@ export type Watermark = {
|
|
|
113
115
|
readonly type: 'none';
|
|
114
116
|
};
|
|
115
117
|
/**
|
|
116
|
-
* The result of a
|
|
117
|
-
* the watermark the
|
|
118
|
-
* `
|
|
118
|
+
* The result of a source `sync`: the documents fetched this run and, optionally,
|
|
119
|
+
* the watermark the feed should advance to. A source may also return a bare
|
|
120
|
+
* `SourceDocument[]` for convenience — {@link runSource} normalizes that to
|
|
119
121
|
* `{ documents }` with no cursor change.
|
|
120
122
|
*/
|
|
121
|
-
export interface
|
|
123
|
+
export interface SourceSyncResult {
|
|
122
124
|
/** The documents fetched this run, mapping 1:1 onto `IngestDocumentInput`. */
|
|
123
|
-
documents:
|
|
125
|
+
documents: SourceDocument[];
|
|
124
126
|
/**
|
|
125
|
-
* The watermark to advance the
|
|
127
|
+
* The watermark to advance the feed's cursor to. Omit (or return `{ type: 'none' }`)
|
|
126
128
|
* to leave the cursor unchanged. The cloud only advances if the new value is
|
|
127
129
|
* monotonically ahead (compare-and-swap).
|
|
128
130
|
*/
|
|
129
131
|
cursor?: Watermark;
|
|
130
132
|
}
|
|
131
133
|
/**
|
|
132
|
-
* The standard `fetch` signature the SDK exposes on {@link
|
|
134
|
+
* The standard `fetch` signature the SDK exposes on {@link SourceContext.fetch}.
|
|
133
135
|
* Matches the platform `fetch` so existing code ports unchanged.
|
|
134
136
|
*/
|
|
135
137
|
export type FetchLike = (url: string | URL, init?: RequestInit) => Promise<Response>;
|
|
136
138
|
/**
|
|
137
|
-
* The single argument to `sync` — a capability object: everything a
|
|
139
|
+
* The single argument to `sync` — a capability object: everything a source
|
|
138
140
|
* reaches the outside world through is on `ctx`. There is no ambient authority.
|
|
139
141
|
*
|
|
140
142
|
* `ctx.credentials` (Keychain-resolved auth material) and `ctx.browser` (a
|
|
141
|
-
* Playwright browser for `needs_browser`
|
|
143
|
+
* Playwright browser for `needs_browser` sources) are **PROPOSED**, not part
|
|
142
144
|
* of the shipped contract, and so are intentionally absent here.
|
|
143
145
|
*/
|
|
144
|
-
export interface
|
|
146
|
+
export interface SourceContext<C = Record<string, unknown>> {
|
|
145
147
|
/**
|
|
146
148
|
* The user's preference values, keyed by the field names declared in
|
|
147
149
|
* `manifest.json` `config`. **Preferences only — never credentials.** Feed
|
|
@@ -150,19 +152,19 @@ export interface ConnectorContext<C = Record<string, unknown>> {
|
|
|
150
152
|
*/
|
|
151
153
|
readonly config: C;
|
|
152
154
|
/**
|
|
153
|
-
* The
|
|
155
|
+
* The feed's current watermark (the position from the previous run), or
|
|
154
156
|
* `{ type: 'none' }` on the first sync. Read-only — advance the cursor by
|
|
155
157
|
* returning a new {@link Watermark} from `sync`, not by mutating this.
|
|
156
158
|
*/
|
|
157
159
|
readonly cursor: Watermark;
|
|
158
160
|
/**
|
|
159
161
|
* Behaves like the standard `fetch`. Prefer `ctx.fetch` over global `fetch` —
|
|
160
|
-
* in the Mac app it routes through per-
|
|
161
|
-
* rate-limit handling, surfacing failures in the
|
|
162
|
+
* in the Mac app it routes through per-source timeouts, retry, and
|
|
163
|
+
* rate-limit handling, surfacing failures in the source's error log.
|
|
162
164
|
*/
|
|
163
165
|
fetch: FetchLike;
|
|
164
166
|
/**
|
|
165
|
-
* Structured log entry, surfaced in the Mac app's
|
|
167
|
+
* Structured log entry, surfaced in the Mac app's source logs and the
|
|
166
168
|
* `createSyncRun` audit record. Useful for reporting counts and progress.
|
|
167
169
|
*/
|
|
168
170
|
log(...args: unknown[]): void;
|
|
@@ -173,16 +175,16 @@ export interface ConnectorContext<C = Record<string, unknown>> {
|
|
|
173
175
|
now(): Date;
|
|
174
176
|
}
|
|
175
177
|
/**
|
|
176
|
-
* The type a
|
|
177
|
-
* a `sync` method that fetches
|
|
178
|
+
* The type a source's default export satisfies. A source is an object with
|
|
179
|
+
* a `sync` method that fetches new content and returns documents to index.
|
|
178
180
|
*
|
|
179
|
-
* @typeParam C - The shape of the
|
|
181
|
+
* @typeParam C - The shape of the source's typed `ctx.config` preferences.
|
|
180
182
|
*
|
|
181
183
|
* @example
|
|
182
184
|
* ```ts
|
|
183
|
-
* import {
|
|
185
|
+
* import { defineSource } from '@ontrove/sdk';
|
|
184
186
|
*
|
|
185
|
-
* export default
|
|
187
|
+
* export default defineSource({
|
|
186
188
|
* async sync(ctx) {
|
|
187
189
|
* const res = await ctx.fetch(ctx.config.feedUrl as string);
|
|
188
190
|
* return parse(await res.text());
|
|
@@ -190,18 +192,18 @@ export interface ConnectorContext<C = Record<string, unknown>> {
|
|
|
190
192
|
* });
|
|
191
193
|
* ```
|
|
192
194
|
*/
|
|
193
|
-
export interface
|
|
195
|
+
export interface TroveSource<C = Record<string, unknown>> {
|
|
194
196
|
/**
|
|
195
|
-
* The batch entry point. Fetches
|
|
196
|
-
* index, optionally with a new cursor. May return a bare `
|
|
197
|
+
* The batch entry point. Fetches new content and returns documents to
|
|
198
|
+
* index, optionally with a new cursor. May return a bare `SourceDocument[]`
|
|
197
199
|
* for convenience. Throw a plain `Error` to fail the run (the Mac app records
|
|
198
200
|
* the error and retries next tick).
|
|
199
201
|
*/
|
|
200
|
-
sync(ctx:
|
|
202
|
+
sync(ctx: SourceContext<C>): Promise<SourceSyncResult | SourceDocument[]>;
|
|
201
203
|
}
|
|
202
204
|
/**
|
|
203
205
|
* A single field descriptor inside a manifest `config` object — describes one
|
|
204
|
-
* preference input shown in the
|
|
206
|
+
* preference input shown in the source's setup wizard.
|
|
205
207
|
*/
|
|
206
208
|
export interface ManifestConfigField {
|
|
207
209
|
/** Display label in the setup UI. */
|
|
@@ -212,12 +214,12 @@ export interface ManifestConfigField {
|
|
|
212
214
|
placeholder?: string;
|
|
213
215
|
}
|
|
214
216
|
/**
|
|
215
|
-
* A
|
|
217
|
+
* A source `manifest.json` — declares what the source is, how often it runs,
|
|
216
218
|
* and which preference fields the user fills in during setup
|
|
217
|
-
* (
|
|
219
|
+
* (sources/manifest reference).
|
|
218
220
|
*/
|
|
219
|
-
export interface
|
|
220
|
-
/** Stable
|
|
221
|
+
export interface SourceManifest {
|
|
222
|
+
/** Stable source-type id; pattern `^[a-z0-9-]+$`. Required. */
|
|
221
223
|
id: string;
|
|
222
224
|
/** Human-readable display name. Required. */
|
|
223
225
|
name: string;
|
|
@@ -227,24 +229,24 @@ export interface ConnectorManifest {
|
|
|
227
229
|
icon?: string;
|
|
228
230
|
/** Semver version string. Required. */
|
|
229
231
|
version: string;
|
|
230
|
-
/** Who wrote the
|
|
232
|
+
/** Who wrote the source. */
|
|
231
233
|
author?: string;
|
|
232
234
|
/** Directory grouping — `reading`, `social`, `finance`, `dev`, `media`, etc. */
|
|
233
235
|
category?: string;
|
|
234
236
|
/**
|
|
235
237
|
* Human-readable sync cadence — `"every 6 hours"`, `"daily"`, `"on demand"`, or
|
|
236
|
-
* `null` for a live-only
|
|
238
|
+
* `null` for a live-only source. Optional (default: on demand).
|
|
237
239
|
*/
|
|
238
240
|
schedule?: string | null;
|
|
239
241
|
/** The preference fields shown in the setup wizard. Preferences only — no credentials. */
|
|
240
242
|
config?: Record<string, ManifestConfigField>;
|
|
241
|
-
/** Whether the
|
|
243
|
+
/** Whether the source requires a Playwright browser. Default `false`. */
|
|
242
244
|
needs_browser?: boolean;
|
|
243
245
|
/** What kind of source this is — `feed`, `account`, `files`, `api`. */
|
|
244
246
|
kind?: string;
|
|
245
|
-
/** How the
|
|
247
|
+
/** How the source reaches the upstream system — `http`, `browser`, `fs`. */
|
|
246
248
|
transport?: string;
|
|
247
|
-
/** Default content type for documents this
|
|
248
|
-
document_semantics?:
|
|
249
|
+
/** Default content type for documents this source produces. */
|
|
250
|
+
document_semantics?: SourceContentType;
|
|
249
251
|
}
|
|
250
252
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,UAAU,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErF;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B;;;;OAIG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,GAAG,IAAI,IAAI,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtD;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,GAAG,cAAc,EAAE,CAAC,CAAC;CAC3E;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC7C,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,iBAAiB,CAAC;CACxC"}
|
package/dist/types.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Public type surface for the `@ontrove/sdk`
|
|
2
|
+
* Public type surface for the `@ontrove/sdk` source authoring library.
|
|
3
3
|
*
|
|
4
|
-
* These types describe the
|
|
5
|
-
* and the cursors
|
|
6
|
-
* an object with a `sync(ctx)` method that fetches
|
|
7
|
-
* documents to index. The SDK owns the document shape (which maps 1:1 onto the
|
|
4
|
+
* These types describe the source contract (see the sources SDK reference
|
|
5
|
+
* and the cursors guide on the docs site): a source is
|
|
6
|
+
* an object with a `sync(ctx)` method that fetches new content from the
|
|
7
|
+
* upstream system and returns documents to index. The SDK owns the document shape (which maps 1:1 onto the
|
|
8
8
|
* `IngestDocumentInput` wire type), the typed `ctx` capability object, the
|
|
9
9
|
* watermark/cursor model, and the local-run harness the CLI drives.
|
|
10
10
|
*
|
|
11
|
-
* It is the symmetric sibling of `@ontrove/mcp
|
|
12
|
-
*
|
|
11
|
+
* It is the symmetric sibling of `@ontrove/mcp` (the toolkit-authoring library —
|
|
12
|
+
* every toolkit runs as a full MCP server on Trove's cloud): a source returns
|
|
13
|
+
* documents to be _stored_ (batch `sync`); a toolkit's tools return results to
|
|
14
|
+
* be _read live_.
|
|
13
15
|
*
|
|
14
16
|
* @module
|
|
15
17
|
*/
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ontrove/sdk",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "Thin standard library for authoring Trove
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Thin standard library for authoring Trove sources — defineSource, the sync(ctx) capability object, the document shape, the local-run harness, and manifest validation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Hollyburn Analytics Inc. <matt@hollyburnanalytics.com>",
|
|
8
8
|
"homepage": "https://ontrove.sh",
|
|
9
9
|
"bugs": {
|
|
10
|
-
"email": "matt@hollyburnanalytics.com"
|
|
10
|
+
"email": "matt@hollyburnanalytics.com",
|
|
11
|
+
"url": "https://github.com/hollyburnanalytics/trove-packages/issues"
|
|
11
12
|
},
|
|
12
13
|
"engines": {
|
|
13
14
|
"node": ">=20"
|
|
14
15
|
},
|
|
15
16
|
"keywords": [
|
|
16
17
|
"trove",
|
|
17
|
-
"
|
|
18
|
+
"source",
|
|
19
|
+
"sync",
|
|
18
20
|
"sdk",
|
|
19
21
|
"knowledge-base",
|
|
20
22
|
"ingestion",
|
|
@@ -31,7 +33,13 @@
|
|
|
31
33
|
},
|
|
32
34
|
"main": "./dist/index.js",
|
|
33
35
|
"types": "./dist/index.d.ts",
|
|
34
|
-
"files": [
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"src",
|
|
39
|
+
"CHANGELOG.md",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
35
43
|
"sideEffects": false,
|
|
36
44
|
"scripts": {
|
|
37
45
|
"prepack": "tsc -p tsconfig.build.json",
|
|
@@ -48,5 +56,10 @@
|
|
|
48
56
|
"@vitest/coverage-v8": "^4.1.1",
|
|
49
57
|
"typescript": "^6.0.2",
|
|
50
58
|
"vitest": "^4.1.1"
|
|
59
|
+
},
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "git+https://github.com/hollyburnanalytics/trove-packages.git",
|
|
63
|
+
"directory": "packages/trove-sdk"
|
|
51
64
|
}
|
|
52
65
|
}
|
package/src/define.ts
CHANGED
|
@@ -1,40 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `
|
|
3
|
-
* (
|
|
2
|
+
* `defineSource` — the single entry point for authoring a Trove source
|
|
3
|
+
* (sources/sdk-reference). It is the symmetric sibling of `defineMcpServer`
|
|
4
4
|
* in `@ontrove/mcp`.
|
|
5
5
|
*
|
|
6
6
|
* It is an identity function with light, eager validation: it confirms the value
|
|
7
|
-
* is a
|
|
7
|
+
* is a source object with a `sync` method, so a typo (`snyc`, a missing
|
|
8
8
|
* `sync`, a non-function) fails at authoring/deploy time with a clear message
|
|
9
9
|
* rather than at the first scheduled run. It does **not** execute `sync` — that is
|
|
10
|
-
* {@link
|
|
10
|
+
* {@link runSource}'s job.
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import type {
|
|
16
|
-
ConnectorContext,
|
|
17
|
-
ConnectorDocument,
|
|
18
|
-
ConnectorSyncResult,
|
|
19
|
-
TroveConnector,
|
|
20
|
-
} from './types.js';
|
|
15
|
+
import type { SourceContext, SourceDocument, SourceSyncResult, TroveSource } from './types.js';
|
|
21
16
|
|
|
22
17
|
/**
|
|
23
|
-
* Validate and return a
|
|
18
|
+
* Validate and return a source definition unchanged.
|
|
24
19
|
*
|
|
25
|
-
* Using `
|
|
26
|
-
* gives an eager runtime check: the CLI calls this when loading a
|
|
20
|
+
* Using `defineSource(...)` (rather than a bare `satisfies TroveSource`)
|
|
21
|
+
* gives an eager runtime check: the CLI calls this when loading a source
|
|
27
22
|
* module so a malformed export is rejected before any sync runs. The returned
|
|
28
23
|
* value is the same object, with full inferred types preserved.
|
|
29
24
|
*
|
|
30
|
-
* @typeParam C - The shape of the
|
|
31
|
-
* @param
|
|
32
|
-
* @returns The same
|
|
33
|
-
* @throws {Error} If `
|
|
25
|
+
* @typeParam C - The shape of the source's typed `ctx.config` preferences.
|
|
26
|
+
* @param source - The source object to validate.
|
|
27
|
+
* @returns The same source object.
|
|
28
|
+
* @throws {Error} If `source` is not an object with a `sync` function.
|
|
34
29
|
*
|
|
35
30
|
* @example
|
|
36
31
|
* ```ts
|
|
37
|
-
* export default
|
|
32
|
+
* export default defineSource({
|
|
38
33
|
* async sync(ctx) {
|
|
39
34
|
* const res = await ctx.fetch(ctx.config.feedUrl as string);
|
|
40
35
|
* return parseRss(await res.text());
|
|
@@ -42,29 +37,27 @@ import type {
|
|
|
42
37
|
* });
|
|
43
38
|
* ```
|
|
44
39
|
*/
|
|
45
|
-
export function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (connector === null || typeof connector !== 'object') {
|
|
49
|
-
throw new Error('defineConnector: expected a connector object with a `sync` method');
|
|
40
|
+
export function defineSource<C = Record<string, unknown>>(source: TroveSource<C>): TroveSource<C> {
|
|
41
|
+
if (source === null || typeof source !== 'object') {
|
|
42
|
+
throw new Error('defineSource: expected a source object with a `sync` method');
|
|
50
43
|
}
|
|
51
|
-
if (typeof (
|
|
52
|
-
throw new Error('
|
|
44
|
+
if (typeof (source as { sync?: unknown }).sync !== 'function') {
|
|
45
|
+
throw new Error('defineSource: source must have a `sync(ctx)` function');
|
|
53
46
|
}
|
|
54
|
-
return
|
|
47
|
+
return source;
|
|
55
48
|
}
|
|
56
49
|
|
|
57
50
|
/**
|
|
58
|
-
* A
|
|
59
|
-
* where the
|
|
60
|
-
* `
|
|
51
|
+
* A source authored inline as a single `sync` function, for the common case
|
|
52
|
+
* where the source has no other members. Equivalent to
|
|
53
|
+
* `defineSource({ sync })`.
|
|
61
54
|
*
|
|
62
|
-
* @typeParam C - The shape of the
|
|
63
|
-
* @param sync - The
|
|
64
|
-
* @returns A validated {@link
|
|
55
|
+
* @typeParam C - The shape of the source's typed `ctx.config` preferences.
|
|
56
|
+
* @param sync - The source's `sync(ctx)` implementation.
|
|
57
|
+
* @returns A validated {@link TroveSource} wrapping `sync`.
|
|
65
58
|
*/
|
|
66
59
|
export function defineSync<C = Record<string, unknown>>(
|
|
67
|
-
sync: (ctx:
|
|
68
|
-
):
|
|
69
|
-
return
|
|
60
|
+
sync: (ctx: SourceContext<C>) => Promise<SourceSyncResult | SourceDocument[]>,
|
|
61
|
+
): TroveSource<C> {
|
|
62
|
+
return defineSource<C>({ sync });
|
|
70
63
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@ontrove/sdk` — the thin standard library for authoring **Trove
|
|
3
|
-
* You write a `sync(ctx)` that fetches
|
|
2
|
+
* `@ontrove/sdk` — the thin standard library for authoring **Trove sources**.
|
|
3
|
+
* You write a `sync(ctx)` that fetches new content and returns documents; the
|
|
4
4
|
* SDK owns the document shape (which maps 1:1 onto `IngestDocumentInput`), the
|
|
5
5
|
* typed `ctx` capability object, the watermark/cursor model, the local-run
|
|
6
6
|
* harness the CLI drives, and manifest validation.
|
|
7
7
|
*
|
|
8
|
-
* It is the symmetric sibling of `@ontrove/mcp
|
|
9
|
-
*
|
|
10
|
-
* be
|
|
8
|
+
* It is the symmetric sibling of `@ontrove/mcp`, the toolkit-authoring library
|
|
9
|
+
* (every toolkit runs as a full MCP server on Trove's cloud): a source returns
|
|
10
|
+
* documents to be _stored_ (`defineSource` + `sync`); a toolkit's tools return
|
|
11
|
+
* results to be _read live_ (`defineMcpServer`).
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* ```ts
|
|
14
|
-
* import {
|
|
15
|
+
* import { defineSource } from '@ontrove/sdk';
|
|
15
16
|
*
|
|
16
|
-
* export default
|
|
17
|
+
* export default defineSource({
|
|
17
18
|
* async sync(ctx) {
|
|
18
19
|
* const res = await ctx.fetch('https://hn.algolia.com/api/v1/search?tags=front_page');
|
|
19
20
|
* const { hits } = await res.json();
|
|
@@ -33,25 +34,25 @@
|
|
|
33
34
|
* @module
|
|
34
35
|
*/
|
|
35
36
|
|
|
36
|
-
export {
|
|
37
|
+
export { defineSource, defineSync } from './define.js';
|
|
37
38
|
export {
|
|
38
39
|
isCredentialConfigKey,
|
|
39
40
|
type ManifestValidationResult,
|
|
40
|
-
|
|
41
|
+
validateSourceManifest,
|
|
41
42
|
} from './manifest.js';
|
|
42
43
|
export {
|
|
43
44
|
type RunOptions,
|
|
44
45
|
type RunResult,
|
|
45
|
-
|
|
46
|
+
runSource,
|
|
46
47
|
} from './runtime.js';
|
|
47
48
|
export type {
|
|
48
|
-
ConnectorContentType,
|
|
49
|
-
ConnectorContext,
|
|
50
|
-
ConnectorDocument,
|
|
51
|
-
ConnectorManifest,
|
|
52
|
-
ConnectorSyncResult,
|
|
53
49
|
FetchLike,
|
|
54
50
|
ManifestConfigField,
|
|
55
|
-
|
|
51
|
+
SourceContentType,
|
|
52
|
+
SourceContext,
|
|
53
|
+
SourceDocument,
|
|
54
|
+
SourceManifest,
|
|
55
|
+
SourceSyncResult,
|
|
56
|
+
TroveSource,
|
|
56
57
|
Watermark,
|
|
57
58
|
} from './types.js';
|