astro-relatinator 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -160,11 +160,50 @@ const related = await getEmDashRelated("posts", post, { limit: 3 });
160
160
  </ul>
161
161
  ```
162
162
 
163
- The result has the same type as the entry that you give. When you give an id, the type of `entry.data` is `Record<string, unknown>`. To set a different type, use `getEmDashRelated<typeof post>("posts", "my-slug")`.
163
+ The result contains the published entries from the collection, not copies of the entry that you give. The types are:
164
+
165
+ ```ts
166
+ interface EmDashEntry<D extends object = Record<string, unknown>> {
167
+ readonly id: string;
168
+ readonly data: D;
169
+ }
170
+
171
+ function getEmDashRelated<D extends object = Record<string, unknown>>(
172
+ collection: string,
173
+ entry: string | EmDashEntry<D> | EmDashEntry<Partial<D>>,
174
+ options?: GetEmDashRelatedOptions<D>
175
+ ): Promise<EmDashEntry<D>[]>;
176
+ ```
177
+
178
+ `D` is the type of `entry.data` in the published entries. When you give an entry object, TypeScript gets `D` from the type of its `data`. When you give an id, `D` is `Record<string, unknown>`.
179
+
180
+ To set `D`, give it as a type argument. Then the entry object can have only some of the keys of `D`. The result has all of the keys of `D`, so you can map it without a cast:
181
+
182
+ ```ts
183
+ interface PostData {
184
+ title: string;
185
+ excerpt: string;
186
+ author: string;
187
+ content: unknown[];
188
+ }
189
+
190
+ // Only some of the keys of PostData.
191
+ const { title, excerpt, content } = post.data;
192
+ const entry = { id: post.id, data: { title, excerpt, content } };
193
+ const related = await getEmDashRelated<PostData>("posts", entry, { limit: 3 });
194
+
195
+ const cards = related.map(({ id, data }) => ({
196
+ href: `/posts/${id}`,
197
+ title: data.title,
198
+ author: data.author,
199
+ }));
200
+ ```
164
201
 
165
202
  ### EmDash options
166
203
 
167
- The options are the same as for `getRelated()`: `limit` (default `5`), `method` (default `"bm25"`), `fields`, and `text`.
204
+ The options are the same as for `getRelated()`: `limit` (default `5`), `method` (default `"bm25"`), `fields`, and `text`. The `GetEmDashRelatedOptions<D>` type describes them.
205
+
206
+ The `text` function gets each published entry. It also gets the entry object that you give when its id is not in the published entries. Thus the type of its argument is `EmDashEntry<Partial<D>>`, and each key of `entry.data` can be `undefined`.
168
207
 
169
208
  The default text of an entry has two parts:
170
209
 
package/dist/emdash.d.ts CHANGED
@@ -1,17 +1,23 @@
1
- import type { ContentEntry } from "./entry-text.js";
2
1
  import { portableTextToPlainText } from "./portable-text.js";
3
2
  import { type RelatedOptions } from "./related-index.js";
4
3
  export { portableTextToPlainText };
5
- /** The entry type when `getEmDashRelated` gets an id. */
6
- export interface EmDashEntry {
4
+ /**
5
+ * An EmDash entry. `D` is the type of `data` in the published entries
6
+ * of the collection.
7
+ */
8
+ export interface EmDashEntry<D extends object = Record<string, unknown>> {
7
9
  readonly id: string;
8
- readonly data: Record<string, unknown>;
10
+ readonly data: D;
9
11
  }
10
- export type GetEmDashRelatedOptions<E> = RelatedOptions<E>;
12
+ /**
13
+ * `text` gets the published entries and, for an entry object that is not
14
+ * published, that object. Thus its data is a part of `D`.
15
+ */
16
+ export type GetEmDashRelatedOptions<D extends object = Record<string, unknown>> = RelatedOptions<EmDashEntry<Partial<D>>>;
11
17
  /**
12
18
  * Finds the published entries of an EmDash `collection` that are most
13
19
  * related to `entry`, in rank order. The model is built once and reused
14
- * until an entry changes.
20
+ * until an entry changes. `D` is the type of `data` in the published
21
+ * entries. An entry object can have only a part of `D`.
15
22
  */
16
- export declare function getEmDashRelated<E extends ContentEntry>(collection: string, entry: E, options?: GetEmDashRelatedOptions<E>): Promise<E[]>;
17
- export declare function getEmDashRelated<E extends ContentEntry = EmDashEntry>(collection: string, entry: string, options?: GetEmDashRelatedOptions<E>): Promise<E[]>;
23
+ export declare function getEmDashRelated<D extends object = Record<string, unknown>>(collection: string, entry: string | EmDashEntry<D> | EmDashEntry<Partial<D>>, options?: GetEmDashRelatedOptions<D>): Promise<EmDashEntry<D>[]>;
package/dist/emdash.js CHANGED
@@ -22,7 +22,15 @@ async function getPublishedEntries(collection) {
22
22
  } while (cursor);
23
23
  return entries;
24
24
  }
25
- export async function getEmDashRelated(collection, entry, options = {}) {
25
+ /**
26
+ * Finds the published entries of an EmDash `collection` that are most
27
+ * related to `entry`, in rank order. The model is built once and reused
28
+ * until an entry changes. `D` is the type of `data` in the published
29
+ * entries. An entry object can have only a part of `D`.
30
+ */
31
+ export async function getEmDashRelated(collection,
32
+ // `EmDashEntry<D>` makes inference keep the optional keys of `D`.
33
+ entry, options = {}) {
26
34
  const { text, fields } = options;
27
35
  const textOf = text ?? ((e) => emdashEntryText(e, fields));
28
36
  const index = relatedIndex({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-relatinator",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Find related entries in your Astro content collections",
5
5
  "author": "Darko Bozhinovski <dbozhinovski@gmail.com>",
6
6
  "license": "MIT",