Skip to content

Commit 54ca517

Browse files
committed
Add JSDoc documentation
1 parent ed96998 commit 54ca517

13 files changed

+211
-28
lines changed

src/hyperjump/hyperjump.js

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { mimeMatch } from "./utilities.js";
1313
* @import { JsonCompatible, JsonType } from "../json/jsonast.js"
1414
* @import { UriSchemePlugin } from "./uri-schemes/uri-scheme-plugin.js"
1515
* @import { DocumentNode, MediaTypePlugin } from "./media-types/media-type-plugin.js"
16+
* @import { JsonPointerError } from "../json/jsonast-util.js"
1617
*/
1718

1819

@@ -28,6 +29,7 @@ import { mimeMatch } from "./utilities.js";
2829
*/
2930

3031
export class Hyperjump {
32+
// TODO: Add config to enable schemes and media types
3133
#config;
3234

3335
/** @type Record<string, DocumentNode> */
@@ -64,7 +66,22 @@ export class Hyperjump {
6466
this.addMediaTypePlugin(new JsonMediaTypePlugin());
6567
}
6668

67-
/** @type (uri: string, options?: GetOptions) => Promise<JsonCompatible<JrefNode>> */
69+
/**
70+
* Retrieve a document located at the given URI. URIs can be relative if a
71+
* base URI can be determined. On the server-side, the base URI is the CWD. In
72+
* browser, the base URI is the URI of the page.
73+
*
74+
* @see Use {@link Hyperjump.addUriSchemePlugin} to add support for additional
75+
* URI schemes.
76+
* @see Support for {@link JrefMediaTypePlugin | JRef} and
77+
* {@link JsonMediaTypePlugin | JSON} is built in. Use
78+
* {@link Hyperjump.addMediaTypePlugin} to add support for additional media
79+
* types.
80+
*
81+
* @type (uri: string, options?: GetOptions) => Promise<JsonCompatible<JrefNode>>
82+
* @throws &nbsp;{@link RetrievalError}
83+
* @throws &nbsp;{@link JsonPointerError}
84+
*/
6885
async get(uri, options = this.#defaultGetOptions) {
6986
uri = resolveIri(uri, options.referencedFrom ?? contextUri());
7087
const id = toAbsoluteIri(uri);
@@ -107,19 +124,39 @@ export class Hyperjump {
107124
}
108125
}
109126

110-
/** @type (plugin: UriSchemePlugin) => void */
127+
/**
128+
* Add support for a
129+
* {@link https://www.rfc-editor.org/rfc/rfc3986#section-3.1 | URI scheme}.
130+
* Support for the {@link HttpUriSchemePlugin | `http(s):`} and
131+
* {@link FileUriSchemePlugin | `file:`} URI schemes are enabled by default.
132+
*
133+
* @type (plugin: UriSchemePlugin) => void
134+
*/
111135
addUriSchemePlugin(plugin) {
112136
for (const scheme of plugin.schemes) {
113137
this.#uriSchemePlugins[scheme] = plugin;
114138
}
115139
}
116140

117-
/** @type (scheme: string) => void */
141+
/**
142+
* This is mostly useful for disabling a scheme that's enabled by default.
143+
*
144+
* @type (scheme: string) => void
145+
*/
118146
removeUriSchemePlugin(scheme) {
119147
delete this.#uriSchemePlugins[scheme];
120148
}
121149

122-
/** @type (uri: string, options: GetOptions) => Promise<Response> */
150+
/**
151+
* Unless you're using it in a {@link UriSchemePlugin.retrieve} method, this
152+
* is not the method you're looking for. It's used internally to fetch a
153+
* resource before processing it based on its media type. You might use it for
154+
* implementing {@link UriSchemePlugin}s for URI schemes that don't have
155+
* locating semantics (such as `urn:`) and instead map to another URI where
156+
* the resource can be retrieved from. See the example in the README.
157+
*
158+
* @type (uri: string, options: GetOptions) => Promise<Response>
159+
*/
123160
async retrieve(uri, options) {
124161
const { scheme } = parseIri(uri);
125162

@@ -130,6 +167,11 @@ export class Hyperjump {
130167
return this.#uriSchemePlugins[scheme].retrieve(uri, options);
131168
}
132169

170+
/**
171+
* Constructs an `Accept` header based on the registered media types.
172+
*
173+
* @type () => string
174+
*/
133175
acceptableMediaTypes() {
134176
let accept = "";
135177

@@ -153,7 +195,12 @@ export class Hyperjump {
153195
return accept;
154196
}
155197

156-
/** @type (uri: string) => string */
198+
/**
199+
* Returns the media type of the resource based on its URI. This is usually
200+
* based on the extension and configured by {@link MediaTypePlugin}s.
201+
*
202+
* @type (uri: string) => string
203+
*/
157204
getMediaType(uri) {
158205
for (const contentType in this.#mediaTypePlugins) {
159206
for (const extension of this.#mediaTypePlugins[contentType].extensions) {
@@ -168,17 +215,34 @@ export class Hyperjump {
168215
throw new UnknownMediaTypeError(`The media type of the file at '${uri}' could not be determined. Use the 'addMediaTypePlugin' function to add support for this media type.`);
169216
}
170217

171-
/** @type <T extends DocumentNode>(plugin: MediaTypePlugin<T>) => void */
218+
/**
219+
* Add support for a media tpe. Support for the
220+
* {@link JrefMediaTypePlugin | `JRef`} and
221+
* {@link JsonMediaTypePlugin | `JSON`} media types are enabled by default.
222+
*
223+
* @type <T extends DocumentNode>(plugin: MediaTypePlugin<T>) => void
224+
*/
172225
addMediaTypePlugin(plugin) {
173226
this.#mediaTypePlugins[plugin.mediaType] = plugin;
174227
}
175228

176-
/** @type (contentType: string) => void */
229+
/**
230+
* This is mostly useful for disabling a scheme that's enabled by default.
231+
*
232+
* @type (contentType: string) => void
233+
*/
177234
removeMediaTypePlugin(contentType) {
178235
delete this.#mediaTypePlugins[contentType];
179236
}
180237

181-
/** @type (contentType: string, quality: number) => void */
238+
/**
239+
* Set the
240+
* {@link https://developer.mozilla.org/en-US/docs/Glossary/Quality_values | quality}
241+
* that will be used in the Accept header of requests to indicate to servers
242+
* which media types are preferred over others.
243+
*
244+
* @type (contentType: string, quality: number) => void
245+
*/
182246
setMediaTypeQuality(contentType, quality) {
183247
this.#mediaTypePlugins[contentType].quality = quality;
184248
}
@@ -242,12 +306,22 @@ export class Hyperjump {
242306
}
243307
}
244308

245-
/** @type (key: string, node: JsonCompatible<JrefNode>) => Promise<JsonCompatible<JrefNode>> */
309+
/**
310+
* This is like indexing into an object or array. It will follow any
311+
* references it encounters so it always returns a JSON compatible value.
312+
*
313+
* @type (key: string, node: JsonCompatible<JrefNode>) => Promise<JsonCompatible<JrefNode>>
314+
*/
246315
async step(key, node) {
247316
return await this.#followReferences(pointerStep(key, node));
248317
}
249318

250-
/** @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<JsonCompatible<JrefNode>, void, unknown> */
319+
/**
320+
* Iterate over an array node. It will follow any references it encounters so
321+
* it always yields JSON compatible values.
322+
*
323+
* @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<JsonCompatible<JrefNode>, void, unknown>
324+
*/
251325
async * iter(node) {
252326
if (node.jsonType === "array") {
253327
for (const itemNode of node.children) {
@@ -265,7 +339,12 @@ export class Hyperjump {
265339
}
266340
}
267341

268-
/** @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<JsonCompatible<JrefNode>, void, unknown> */
342+
/**
343+
* Iterate over the values of an object. It will follow any references it
344+
* encounters so it always yields JSON compatible values.
345+
*
346+
* @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<JsonCompatible<JrefNode>, void, unknown>
347+
*/
269348
async * values(node) {
270349
if (node.jsonType === "object") {
271350
for (const propertyNode of node.children) {
@@ -274,7 +353,12 @@ export class Hyperjump {
274353
}
275354
}
276355

277-
/** @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<[string, JsonCompatible<JrefNode>], void, unknown> */
356+
/**
357+
* Iterate over key/value pairs of an object. It will follow any references it
358+
* encounters so it always yields JSON compatible values.
359+
*
360+
* @type (node: JsonCompatible<JrefNode>) => AsyncGenerator<[string, JsonCompatible<JrefNode>], void, unknown>
361+
*/
278362
async * entries(node) {
279363
if (node.jsonType === "object") {
280364
for (const propertyNode of node.children) {

src/hyperjump/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* @module hyperjump
3+
*/
4+
15
export * from "./hyperjump.js";
26
// eslint-disable-next-line import/extensions
37
export * from "./uri-schemes/uri-scheme-plugin.js";

src/hyperjump/media-types/jref-media-type-plugin.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import { fromJref } from "../../jref/jref-util.js";
66
*/
77

88

9-
/** @implements MediaTypePlugin<JrefDocumentNode> */
9+
/**
10+
* Supports JRef
11+
* - Media type: application/reference+json
12+
* - Extensions: .jref
13+
*
14+
* @implements MediaTypePlugin<JrefDocumentNode>
15+
*/
1016
export class JrefMediaTypePlugin {
1117
constructor() {
1218
this.mediaType = "application/reference+json";

src/hyperjump/media-types/json-media-type-plugin.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import { fromJson } from "../../json/jsonast-util.js";
66
*/
77

88

9-
/** @implements MediaTypePlugin<JsonDocumentNode> */
9+
/**
10+
* Supports JSON
11+
* - Media type: application/json
12+
* - Extensions: .json
13+
*
14+
* @implements MediaTypePlugin<JsonDocumentNode>
15+
*/
1016
export class JsonMediaTypePlugin {
1117
constructor() {
1218
this.mediaType = "application/json";

src/hyperjump/media-types/media-type-plugin.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export type DocumentNode = {
1313
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
1414
export interface MediaTypePlugin<T extends DocumentNode> {
1515
mediaType: string;
16+
/**
17+
* Extensions start with `.` (Example: `.jref`).
18+
* Filenames start with `/` (Example: `/.bowerrc`)
19+
*/
1620
extensions: string[];
1721
quality?: number;
1822
parse: (response: Response) => Promise<T>;

src/hyperjump/uri-schemes/file-scheme-plugin.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import { Readable } from "node:stream";
1010
*/
1111

1212

13-
/** @implements UriSchemePlugin */
13+
/**
14+
* Supports the `file:` URI scheme. Media type is determined by file extensions.
15+
*
16+
* @implements UriSchemePlugin
17+
*/
1418
export class FileUriSchemePlugin {
1519
#hyperjump;
1620

src/hyperjump/uri-schemes/http-scheme-plugin.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
*/
55

66

7-
/** @implements UriSchemePlugin */
7+
/**
8+
* Support the `http:` and `https:` URI schemes. Sends an Accept header
9+
* representng all registered media types.
10+
*
11+
* @implements UriSchemePlugin
12+
*/
813
export class HttpUriSchemePlugin {
914
#hyperjump;
1015
#successStatus;
@@ -19,7 +24,10 @@ export class HttpUriSchemePlugin {
1924
this.#successStatus = new Set([200, 203]);
2025
}
2126

22-
/** @type UriSchemePlugin["retrieve"] */
27+
/**
28+
* @type UriSchemePlugin["retrieve"]
29+
* @throws &nbsp;{@link HttpError}
30+
*/
2331
async retrieve(uri) {
2432
const response = await fetch(uri, {
2533
headers: { Accept: this.#hyperjump.acceptableMediaTypes() }

src/jref/jref-parse.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ import { fromJref } from "./jref-util.js";
1717
* }} JrefParseOptions
1818
*/
1919

20-
/** @type Plugin<[JrefParseOptions?], string, JrefDocumentNode> */
20+
/**
21+
* Parses JRef to a JRef AST. Includes {@link Reviver} option similar to the
22+
* standard
23+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}
24+
* function.
25+
*
26+
* @type Plugin<[JrefParseOptions?], string, JrefDocumentNode>
27+
*/
2128
export function jrefParse(options) {
2229
/** @type (document: string, file: VFile) => JrefDocumentNode */
2330
this.parser = function (document, file) {

src/jref/jref-stringify.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ import { toJref } from "./jref-util.js";
1515
* }} JrefStringifyOptions
1616
*/
1717

18-
/** @type Plugin<[JrefStringifyOptions?], JrefDocumentNode, string> */
18+
/**
19+
* Stringifies a JRef AST to JRef. Includes {@link Replacer} and `space` options
20+
* similar to the standard
21+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify | JSON.stringify}
22+
* function.
23+
*
24+
* @type Plugin<[JrefStringifyOptions?], JrefDocumentNode, string>
25+
*/
1926
export function jrefStringify(options) {
2027
/** @type (tree: Node) => string */
2128
this.compiler = (tree) => {

src/jref/jref-util.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ import {
2020
/** @type Reviver<any> */
2121
const defaultReviver = (value) => value;
2222

23-
/** @type <A extends JrefNode | undefined = JrefNode>(jref: string, uri: string, reviver?: Reviver<A>) => A */
23+
/**
24+
* Parse a JRef string into a JRef AST. Includes a reviver option similar to
25+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}.
26+
*
27+
* @type <A extends JrefNode | undefined = JrefNode>(jref: string, uri: string, reviver?: Reviver<A>) => A
28+
*/
2429
export const fromJref = (jref, uri, reviver = defaultReviver) => {
2530
return fromJson(jref, (node, key) => {
2631
if (node.jsonType === "object") {
@@ -58,7 +63,13 @@ const isReference = (objectNode) => {
5863
/** @type Replacer */
5964
const defaultReplacer = (node) => node;
6065

61-
/** @type (node: JrefNode, uri: string, replacer?: Replacer, space?: string) => string */
66+
/**
67+
* Stringify a JrefNode to a JRef string. Includes options for a
68+
* {@link Replacer} and `space` like
69+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify | JSON.stringify}.
70+
*
71+
* @type (node: JrefNode, uri: string, replacer?: Replacer, space?: string) => string
72+
*/
6273
export const toJref = (node, uri, replacer = defaultReplacer, space = "") => {
6374
return toJson(node, (node, key) => {
6475
const replacedNode = replacer(node, key);
@@ -94,5 +105,12 @@ export const toJref = (node, uri, replacer = defaultReplacer, space = "") => {
94105
}, space);
95106
};
96107

97-
export const pointerGet = /** @type (pointer: string, tree: JrefNode, documentUri?: string) => JrefNode */ (jsonPointerGet);
108+
/**
109+
* Index into an object or array JsonNode. Reference nodes are not followed.
110+
*/
98111
export const pointerStep = /** @type (segment: string, tree: JrefNode, uri?: string) => JrefNode */ (jsonPointerStep);
112+
113+
/**
114+
* Get a JrefNode using a JSON Pointer. Reference nodes are not followed.
115+
*/
116+
export const pointerGet = /** @type (pointer: string, tree: JrefNode, documentUri?: string) => JrefNode */ (jsonPointerGet);

0 commit comments

Comments
 (0)