@nbtca/docs 0.2.3 → 0.3.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/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  # @nbtca/docs
2
2
 
3
- Data-only library for the [NBTCA documents repository](https://github.com/nbtca/documents).
4
- Fetches directory listings and raw markdown files from GitHub with built-in TTL caching,
5
- stale-on-error fallback, and rate-limit handling.
6
-
7
- Rendering is the consumer's job (e.g. `@nbtca/prompt`).
3
+ Typed GitHub client for the [NBTCA documents repository](https://github.com/nbtca/documents).
4
+ It lists Markdown documents, reads raw content, caches successful responses, and falls back to
5
+ stale data after transient failures. Rendering remains the consumer's responsibility.
8
6
 
9
7
  ## Install
10
8
 
@@ -17,53 +15,63 @@ npm install @nbtca/docs
17
15
  ```ts
18
16
  import { createDocsClient } from '@nbtca/docs';
19
17
 
20
- const docs = createDocsClient(); // defaults to nbtca/documents@main
18
+ const docs = createDocsClient();
21
19
 
22
- const items = await docs.listDir('tutorial'); // DocItem[]
23
- const all = await docs.listAll(); // all markdown DocItem[]
24
- const md = await docs.getFile('repair/guide.md'); // string (raw markdown)
25
- ```
26
-
27
- Custom target:
28
-
29
- ```ts
30
- const docs = createDocsClient({
31
- owner: 'my-org',
32
- repo: 'my-docs',
33
- branch: 'main',
34
- token: process.env.GITHUB_TOKEN,
35
- });
20
+ const sections = await docs.listDir();
21
+ const documents = await docs.listAll();
22
+ const markdown = await docs.getFile('repair/guide.md');
23
+ const page = await docs.getDocument('repair/index.md');
24
+ const matches = await docs.search('repair', { pathPrefix: 'repair' });
36
25
  ```
37
26
 
38
27
  ## API
39
28
 
40
29
  ### `createDocsClient(options?)`
41
30
 
42
- | Option | Default | Description |
43
- |---|---|---|
44
- | `owner` | `'nbtca'` | GitHub org/user |
45
- | `repo` | `'documents'` | Repository name |
46
- | `branch` | `'main'` | Branch or ref |
47
- | `token` | `GITHUB_TOKEN` env | Auth token (raises rate limit) |
48
- | `cacheTtlMs.dir` | `300000` (5 min) | Directory listing cache TTL |
49
- | `cacheTtlMs.file` | `600000` (10 min) | File content cache TTL |
31
+ | Option | Default | Description |
32
+ | ----------------- | ---------------------------- | ---------------------------- |
33
+ | `owner` | `'nbtca'` | GitHub owner |
34
+ | `repo` | `'documents'` | Repository name |
35
+ | `branch` | `'main'` | Branch name or ref |
36
+ | `token` | `GITHUB_TOKEN` or `GH_TOKEN` | GitHub token |
37
+ | `cacheTtlMs.dir` | `300000` | Directory and tree cache TTL |
38
+ | `cacheTtlMs.file` | `600000` | File cache TTL |
50
39
 
51
40
  ### `docs.listDir(path?)`
52
41
 
53
- Returns `DocItem[]` for the given path (root if omitted).
54
- Filters out hidden files, non-markdown files, and repository metadata.
42
+ Lists directories and Markdown files at a repository-relative path. The root path is used when
43
+ `path` is omitted.
55
44
 
56
45
  ### `docs.getFile(path)`
57
46
 
58
- Returns raw markdown as a string. Falls back to stale cache on network error.
47
+ Returns raw file content.
59
48
 
60
49
  ### `docs.listAll()`
61
50
 
62
- Returns every markdown file in the repository through GitHub's recursive tree API.
51
+ Lists every Markdown file through GitHub's recursive tree API.
52
+
53
+ ### `docs.listSections()`
54
+
55
+ Returns top-level content sections with document counts and optional index paths.
56
+
57
+ ### `docs.getDocument(path)`
58
+
59
+ Returns content with its route, section, title, summary, and semantic component attributes. Component
60
+ metadata covers `PageHero`, `FactStrip`, `LinkCard`, `Split`, `TimelineEntry`, and `Figure` without
61
+ imposing a renderer.
62
+
63
+ ### `docs.search(query, options?)`
64
+
65
+ Searches paths, titles, summaries, Markdown text, and semantic component attributes. Results are
66
+ ranked and include excerpts. Use `pathPrefix` to scope a search and `limit` to cap results.
67
+
68
+ ### `docs.clear()`
69
+
70
+ Clears all cached values and in-flight request bookkeeping.
63
71
 
64
72
  ### `DocsFetchError`
65
73
 
66
- Thrown when a fetch fails with no stale cache available. Has `.path` and `.status` fields.
74
+ Thrown when a request fails without usable stale data. Exposes `path` and HTTP `status`.
67
75
 
68
76
  ## License
69
77
 
package/dist/cache.d.ts CHANGED
@@ -9,4 +9,3 @@ export declare class TtlCache<T> {
9
9
  clear(): void;
10
10
  private evictOldest;
11
11
  }
12
- //# sourceMappingURL=cache.d.ts.map
package/dist/cache.js CHANGED
@@ -31,4 +31,3 @@ export class TtlCache {
31
31
  this.map.delete(key);
32
32
  }
33
33
  }
34
- //# sourceMappingURL=cache.js.map
package/dist/client.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import type { DocsClient, DocsClientOptions } from './types.js';
2
2
  export declare function createDocsClient(options?: DocsClientOptions): DocsClient;
3
- //# sourceMappingURL=client.d.ts.map
package/dist/client.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { TtlCache } from './cache.js';
2
+ import { parseDoc, searchDoc } from './content.js';
2
3
  import { DocsFetchError } from './types.js';
3
4
  const DEFAULTS = {
4
5
  owner: 'nbtca',
@@ -7,15 +8,40 @@ const DEFAULTS = {
7
8
  dirTtlMs: 5 * 60 * 1000,
8
9
  fileTtlMs: 10 * 60 * 1000,
9
10
  };
10
- const SKIP = new Set(['.github', '.husky', '.vitepress', '.vscode', 'node_modules',
11
- 'assets', 'public', 'scripts', 'utils', 'package.json', 'pnpm-lock.yaml',
12
- 'tsconfig.json', 'eslint.config.mjs', '.nvmrc', '.gitignore',
13
- '.markdownlint-cli2.jsonc', 'CONTRIBUTING.md', 'CONTEXT.md']);
11
+ const SKIP = new Set([
12
+ '.github',
13
+ '.husky',
14
+ '.vitepress',
15
+ '.vscode',
16
+ 'node_modules',
17
+ 'assets',
18
+ 'public',
19
+ 'scripts',
20
+ 'utils',
21
+ 'package.json',
22
+ 'pnpm-lock.yaml',
23
+ 'tsconfig.json',
24
+ 'eslint.config.mjs',
25
+ '.nvmrc',
26
+ '.gitignore',
27
+ '.markdownlint-cli2.jsonc',
28
+ 'CONTRIBUTING.md',
29
+ 'CONTEXT.md',
30
+ 'README.md',
31
+ 'docs',
32
+ ]);
33
+ const SEARCH_CONCURRENCY = 6;
34
+ const SEARCH_RESULT_LIMIT = 20;
14
35
  function filterAndSort(raw) {
15
36
  return raw
16
- .filter(i => !i.name.startsWith('.') && !SKIP.has(i.name) &&
17
- (i.type === 'dir' || (i.type === 'file' && i.name.endsWith('.md'))))
18
- .map(i => ({ name: i.name, path: i.path, type: (i.type === 'dir' ? 'dir' : 'file') }))
37
+ .filter((item) => !item.name.startsWith('.') &&
38
+ !SKIP.has(item.name) &&
39
+ (item.type === 'dir' || (item.type === 'file' && item.name.endsWith('.md'))))
40
+ .map((item) => ({
41
+ name: item.name,
42
+ path: item.path,
43
+ type: item.type === 'dir' ? 'dir' : 'file',
44
+ }))
19
45
  .sort((a, b) => {
20
46
  if (a.type !== b.type)
21
47
  return a.type === 'dir' ? -1 : 1;
@@ -24,54 +50,108 @@ function filterAndSort(raw) {
24
50
  }
25
51
  function filterTree(items) {
26
52
  return items
27
- .filter(i => {
28
- const parts = i.path.split('/');
29
- if (parts.some(p => p.startsWith('.') || SKIP.has(p)))
53
+ .filter((item) => {
54
+ const parts = item.path.split('/');
55
+ if (parts.some((part) => part.startsWith('.') || SKIP.has(part)))
30
56
  return false;
31
- // Only return .md files; directories are navigated via listDir
32
- return i.type === 'blob' && i.path.endsWith('.md');
57
+ return item.type === 'blob' && item.path.endsWith('.md');
33
58
  })
34
- .map(i => ({
35
- name: i.path.split('/').pop(),
36
- path: i.path,
59
+ .map((item) => ({
60
+ name: item.path.slice(item.path.lastIndexOf('/') + 1),
61
+ path: item.path,
37
62
  type: 'file',
38
63
  }))
39
64
  .sort((a, b) => a.path.localeCompare(b.path));
40
65
  }
41
66
  function copyItems(items) {
42
- return items.map(item => ({ ...item }));
67
+ return items.map((item) => ({ ...item }));
68
+ }
69
+ function sectionsFromItems(items) {
70
+ const sections = new Map();
71
+ for (const item of items) {
72
+ const separator = item.path.indexOf('/');
73
+ if (separator < 1)
74
+ continue;
75
+ const path = item.path.slice(0, separator);
76
+ const current = sections.get(path) ?? { count: 0, path };
77
+ current.count += 1;
78
+ if (item.path === `${path}/index.md`)
79
+ current.indexPath = item.path;
80
+ sections.set(path, current);
81
+ }
82
+ return [...sections.values()]
83
+ .map((section) => ({ ...section }))
84
+ .sort((left, right) => left.path.localeCompare(right.path));
85
+ }
86
+ function searchLimit(value) {
87
+ const limit = value ?? SEARCH_RESULT_LIMIT;
88
+ if (!Number.isSafeInteger(limit) || limit < 0) {
89
+ throw new RangeError('limit must be a non-negative safe integer');
90
+ }
91
+ return limit;
92
+ }
93
+ async function mapConcurrent(values, concurrency, map) {
94
+ const results = new Array(values.length);
95
+ let nextIndex = 0;
96
+ async function worker() {
97
+ for (;;) {
98
+ const index = nextIndex;
99
+ nextIndex += 1;
100
+ if (index >= values.length)
101
+ return;
102
+ const value = values[index];
103
+ if (value !== undefined)
104
+ results[index] = await map(value);
105
+ }
106
+ }
107
+ const workers = Math.min(concurrency, values.length);
108
+ await Promise.all(Array.from({ length: workers }, worker));
109
+ return results;
43
110
  }
44
111
  function encodePath(path) {
45
- return path.split('/').map(encodeURIComponent).join('/');
112
+ return path
113
+ .split('/')
114
+ .map((segment) => encodeURIComponent(segment))
115
+ .join('/');
46
116
  }
47
117
  function assertRepositoryPath(path, allowEmpty) {
48
118
  if (allowEmpty && path === '')
49
119
  return;
50
120
  const parts = path.split('/');
51
- if (path === ''
52
- || path.startsWith('/')
53
- || path.endsWith('/')
54
- || path.includes('\\')
55
- || parts.some(part => part === '' || part === '.' || part === '..')) {
121
+ if (path === '' ||
122
+ path.startsWith('/') ||
123
+ path.endsWith('/') ||
124
+ path.includes('\\') ||
125
+ parts.some((part) => part === '' || part === '.' || part === '..')) {
56
126
  throw new TypeError('path must be a normalized repository-relative path');
57
127
  }
58
128
  }
129
+ function hasControlCharacter(value) {
130
+ for (const character of value) {
131
+ const code = character.charCodeAt(0);
132
+ if (code <= 0x1f || code === 0x7f)
133
+ return true;
134
+ }
135
+ return false;
136
+ }
59
137
  function assertRepositoryCoordinate(value, name) {
60
- if (value === ''
61
- || value !== value.trim()
62
- || value === '.'
63
- || value === '..'
64
- || /[\/\\\u0000-\u001f\u007f]/.test(value)) {
138
+ if (value === '' ||
139
+ value !== value.trim() ||
140
+ value === '.' ||
141
+ value === '..' ||
142
+ value.includes('/') ||
143
+ value.includes('\\') ||
144
+ hasControlCharacter(value)) {
65
145
  throw new TypeError(`${name} must be a valid GitHub repository coordinate`);
66
146
  }
67
147
  }
68
148
  function assertBranchRef(value) {
69
149
  const parts = value.split('/');
70
- if (value === ''
71
- || value !== value.trim()
72
- || value.includes('\\')
73
- || /[\u0000-\u001f\u007f]/.test(value)
74
- || parts.some(part => part === '' || part === '.' || part === '..')) {
150
+ if (value === '' ||
151
+ value !== value.trim() ||
152
+ value.includes('\\') ||
153
+ hasControlCharacter(value) ||
154
+ parts.some((part) => part === '' || part === '.' || part === '..')) {
75
155
  throw new TypeError('branch must be a valid Git ref');
76
156
  }
77
157
  }
@@ -85,16 +165,20 @@ function cacheTtl(value, fallback, name) {
85
165
  function isTransientStatus(status) {
86
166
  return status === 408 || status === 429 || status >= 500;
87
167
  }
168
+ function reject(error) {
169
+ return Promise.reject(error instanceof Error ? error : new Error('Operation failed with a non-error value'));
170
+ }
88
171
  function isRecord(value) {
89
172
  return typeof value === 'object' && value !== null;
90
173
  }
91
174
  function isGitHubItem(value) {
92
- return isRecord(value) && typeof value.name === 'string' &&
93
- typeof value.path === 'string' && typeof value.type === 'string';
175
+ return (isRecord(value) &&
176
+ typeof value.name === 'string' &&
177
+ typeof value.path === 'string' &&
178
+ typeof value.type === 'string');
94
179
  }
95
180
  function isGitHubTreeItem(value) {
96
- return isRecord(value) && typeof value.path === 'string' &&
97
- typeof value.type === 'string';
181
+ return isRecord(value) && typeof value.path === 'string' && typeof value.type === 'string';
98
182
  }
99
183
  function parseContentsResponse(value) {
100
184
  if (!Array.isArray(value) || !value.every(isGitHubItem)) {
@@ -103,8 +187,10 @@ function parseContentsResponse(value) {
103
187
  return value;
104
188
  }
105
189
  function parseTreeResponse(value) {
106
- if (!isRecord(value) || typeof value.truncated !== 'boolean' ||
107
- !Array.isArray(value.tree) || !value.tree.every(isGitHubTreeItem)) {
190
+ if (!isRecord(value) ||
191
+ typeof value.truncated !== 'boolean' ||
192
+ !Array.isArray(value.tree) ||
193
+ !value.tree.every(isGitHubTreeItem)) {
108
194
  throw new TypeError('Invalid GitHub tree response');
109
195
  }
110
196
  return { tree: value.tree, truncated: value.truncated };
@@ -116,30 +202,35 @@ export function createDocsClient(options = {}) {
116
202
  assertRepositoryCoordinate(owner, 'owner');
117
203
  assertRepositoryCoordinate(repo, 'repo');
118
204
  assertBranchRef(branch);
119
- const token = options.token ?? (typeof process !== 'undefined'
120
- ? (process.env['GITHUB_TOKEN'] ?? process.env['GH_TOKEN'])
121
- : undefined);
205
+ const token = options.token ??
206
+ (typeof process !== 'undefined'
207
+ ? (process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN)
208
+ : undefined);
122
209
  const apiRepoUrl = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`;
123
210
  const rawRepoUrl = `https://raw.githubusercontent.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`;
124
211
  const encodedBranch = encodeURIComponent(branch);
125
212
  const dirTtlMs = cacheTtl(options.cacheTtlMs?.dir, DEFAULTS.dirTtlMs, 'cacheTtlMs.dir');
126
213
  const fileTtlMs = cacheTtl(options.cacheTtlMs?.file, DEFAULTS.fileTtlMs, 'cacheTtlMs.file');
127
214
  const dirCache = new TtlCache(dirTtlMs, 30);
128
- const fileCache = new TtlCache(fileTtlMs, 50);
215
+ const fileCache = new TtlCache(fileTtlMs, 200);
129
216
  const treeCache = new TtlCache(dirTtlMs, 1);
130
217
  const dirRequests = new Map();
131
218
  const fileRequests = new Map();
132
219
  const treeRequests = new Map();
133
220
  let cacheGeneration = 0;
134
221
  function headers() {
135
- const h = { 'Accept': 'application/vnd.github.v3+json' };
222
+ const requestHeaders = {
223
+ Accept: 'application/vnd.github.v3+json',
224
+ };
136
225
  if (token)
137
- h['Authorization'] = `Bearer ${token}`;
138
- return h;
226
+ requestHeaders.Authorization = `Bearer ${token}`;
227
+ return requestHeaders;
139
228
  }
140
229
  async function withResponse(url, timeoutMs, consume) {
141
230
  const ctrl = new AbortController();
142
- const timer = setTimeout(() => ctrl.abort(), timeoutMs);
231
+ const timer = setTimeout(() => {
232
+ ctrl.abort();
233
+ }, timeoutMs);
143
234
  try {
144
235
  const response = await fetch(url, { signal: ctrl.signal, headers: headers() });
145
236
  return await consume(response);
@@ -148,13 +239,11 @@ export function createDocsClient(options = {}) {
148
239
  clearTimeout(timer);
149
240
  }
150
241
  }
151
- function recoverFailure(cache, key, path, error, copy = value => value) {
242
+ function recoverFailure(cache, key, path, error, copy = (value) => value) {
152
243
  const stale = cache.getStale(key);
153
244
  if (stale !== undefined)
154
245
  return copy(stale);
155
- const message = error instanceof Error && error.name === 'AbortError'
156
- ? 'Request timed out'
157
- : String(error);
246
+ const message = error instanceof Error && error.name === 'AbortError' ? 'Request timed out' : String(error);
158
247
  throw new DocsFetchError(path, null, message);
159
248
  }
160
249
  function shareRequest(requests, key, load) {
@@ -170,27 +259,27 @@ export function createDocsClient(options = {}) {
170
259
  requests.set(key, request);
171
260
  return request;
172
261
  }
173
- async function loadDir(path, key, generation) {
262
+ async function loadDir(path, generation) {
174
263
  const url = `${apiRepoUrl}/contents/${encodePath(path)}?ref=${encodedBranch}`;
175
264
  try {
176
265
  return await withResponse(url, 10000, async (response) => {
177
266
  if (!response.ok) {
178
- const stale = dirCache.getStale(key);
267
+ const stale = dirCache.getStale(path);
179
268
  if (isTransientStatus(response.status) && stale !== undefined)
180
269
  return copyItems(stale);
181
- throw new DocsFetchError(path, response.status, `HTTP ${response.status}`);
270
+ throw new DocsFetchError(path, response.status, `HTTP ${String(response.status)}`);
182
271
  }
183
272
  const data = parseContentsResponse(await response.json());
184
273
  const items = filterAndSort(data);
185
274
  if (generation === cacheGeneration)
186
- dirCache.set(key, copyItems(items));
275
+ dirCache.set(path, copyItems(items));
187
276
  return items;
188
277
  });
189
278
  }
190
279
  catch (error) {
191
280
  if (error instanceof DocsFetchError)
192
281
  throw error;
193
- return recoverFailure(dirCache, key, path, error, copyItems);
282
+ return recoverFailure(dirCache, path, path, error, copyItems);
194
283
  }
195
284
  }
196
285
  function listDir(path = '') {
@@ -198,12 +287,12 @@ export function createDocsClient(options = {}) {
198
287
  assertRepositoryPath(path, true);
199
288
  }
200
289
  catch (error) {
201
- return Promise.reject(error);
290
+ return reject(error);
202
291
  }
203
292
  const hit = dirCache.get(path);
204
293
  if (hit)
205
294
  return Promise.resolve(copyItems(hit));
206
- return shareRequest(dirRequests, path, () => loadDir(path, path, cacheGeneration));
295
+ return shareRequest(dirRequests, path, () => loadDir(path, cacheGeneration)).then(copyItems);
207
296
  }
208
297
  async function loadAll(generation) {
209
298
  const key = '__tree__';
@@ -214,7 +303,7 @@ export function createDocsClient(options = {}) {
214
303
  const stale = treeCache.getStale(key);
215
304
  if (isTransientStatus(response.status) && stale !== undefined)
216
305
  return copyItems(stale);
217
- throw new DocsFetchError('', response.status, `HTTP ${response.status}`);
306
+ throw new DocsFetchError('', response.status, `HTTP ${String(response.status)}`);
218
307
  }
219
308
  const data = parseTreeResponse(await response.json());
220
309
  if (data.truncated) {
@@ -240,7 +329,10 @@ export function createDocsClient(options = {}) {
240
329
  const hit = treeCache.get(key);
241
330
  if (hit)
242
331
  return Promise.resolve(copyItems(hit));
243
- return shareRequest(treeRequests, key, () => loadAll(cacheGeneration));
332
+ return shareRequest(treeRequests, key, () => loadAll(cacheGeneration)).then(copyItems);
333
+ }
334
+ async function listSections() {
335
+ return sectionsFromItems(await listAll());
244
336
  }
245
337
  async function loadFile(path, generation) {
246
338
  const url = `${rawRepoUrl}/${encodedBranch}/${encodePath(path)}`;
@@ -250,7 +342,7 @@ export function createDocsClient(options = {}) {
250
342
  const stale = fileCache.getStale(path);
251
343
  if (isTransientStatus(response.status) && stale !== undefined)
252
344
  return stale;
253
- throw new DocsFetchError(path, response.status, `HTTP ${response.status}`);
345
+ throw new DocsFetchError(path, response.status, `HTTP ${String(response.status)}`);
254
346
  }
255
347
  const content = await response.text();
256
348
  if (generation === cacheGeneration)
@@ -269,13 +361,55 @@ export function createDocsClient(options = {}) {
269
361
  assertRepositoryPath(path, false);
270
362
  }
271
363
  catch (error) {
272
- return Promise.reject(error);
364
+ return reject(error);
273
365
  }
274
366
  const hit = fileCache.get(path);
275
367
  if (hit !== undefined)
276
368
  return Promise.resolve(hit);
277
369
  return shareRequest(fileRequests, path, () => loadFile(path, cacheGeneration));
278
370
  }
371
+ async function getDocument(path) {
372
+ if (!path.toLowerCase().endsWith('.md')) {
373
+ throw new TypeError('path must point to a Markdown document');
374
+ }
375
+ return parseDoc(path, await getFile(path));
376
+ }
377
+ async function search(query, options = {}) {
378
+ const normalizedQuery = query.trim();
379
+ if (!normalizedQuery)
380
+ throw new TypeError('query must not be empty');
381
+ const limit = searchLimit(options.limit);
382
+ const pathPrefix = options.pathPrefix ?? '';
383
+ assertRepositoryPath(pathPrefix, true);
384
+ if (limit === 0)
385
+ return [];
386
+ const all = await listAll();
387
+ const candidates = pathPrefix
388
+ ? all.filter((item) => item.path.startsWith(`${pathPrefix}/`))
389
+ : all;
390
+ let loaded = 0;
391
+ let firstFailure;
392
+ const matches = await mapConcurrent(candidates, SEARCH_CONCURRENCY, async (item) => {
393
+ try {
394
+ const document = await getDocument(item.path);
395
+ loaded += 1;
396
+ return searchDoc(document, normalizedQuery);
397
+ }
398
+ catch (error) {
399
+ if (error instanceof DocsFetchError) {
400
+ firstFailure ?? (firstFailure = error);
401
+ return null;
402
+ }
403
+ throw error;
404
+ }
405
+ });
406
+ if (loaded === 0 && firstFailure)
407
+ throw firstFailure;
408
+ return matches
409
+ .filter((result) => result !== null)
410
+ .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path))
411
+ .slice(0, limit);
412
+ }
279
413
  function clear() {
280
414
  cacheGeneration += 1;
281
415
  dirCache.clear();
@@ -285,6 +419,5 @@ export function createDocsClient(options = {}) {
285
419
  fileRequests.clear();
286
420
  treeRequests.clear();
287
421
  }
288
- return { listDir, listAll, getFile, clear };
422
+ return { listDir, listAll, listSections, getFile, getDocument, search, clear };
289
423
  }
290
- //# sourceMappingURL=client.js.map
@@ -0,0 +1,3 @@
1
+ import type { DocPage, DocsSearchResult } from './types.js';
2
+ export declare function parseDoc(path: string, content: string): DocPage;
3
+ export declare function searchDoc(page: DocPage, query: string): DocsSearchResult | null;
@@ -0,0 +1,330 @@
1
+ const SUMMARY_LENGTH = 160;
2
+ const EXCERPT_LENGTH = 180;
3
+ const COMPONENT_ATTRIBUTES = {
4
+ Band: ['alt', 'source'],
5
+ Figure: ['alt', 'caption', 'date', 'source'],
6
+ LinkCard: ['title', 'desc', 'alt'],
7
+ PageHero: ['title', 'lede', 'alt', 'source'],
8
+ Split: ['heading', 'alt'],
9
+ TimelineEntry: ['year', 'title'],
10
+ };
11
+ function splitFrontmatter(content) {
12
+ const match = /^(?:\uFEFF)?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(content);
13
+ if (!match)
14
+ return { body: content, frontmatter: '' };
15
+ return {
16
+ body: content.slice(match[0].length),
17
+ frontmatter: match[1] ?? '',
18
+ };
19
+ }
20
+ function decodeScalar(value) {
21
+ const trimmed = value.trim();
22
+ if (!trimmed || trimmed === '|' || trimmed === '>' || trimmed === '~' || trimmed === 'null') {
23
+ return undefined;
24
+ }
25
+ if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
26
+ try {
27
+ const parsed = JSON.parse(trimmed);
28
+ return typeof parsed === 'string' ? parsed : undefined;
29
+ }
30
+ catch {
31
+ return trimmed.slice(1, -1);
32
+ }
33
+ }
34
+ if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
35
+ return trimmed.slice(1, -1).replace(/''/g, "'");
36
+ }
37
+ return trimmed;
38
+ }
39
+ function frontmatterValue(frontmatter, key) {
40
+ for (const line of frontmatter.split(/\r?\n/)) {
41
+ if (/^[ \t]/.test(line))
42
+ continue;
43
+ const separator = line.indexOf(':');
44
+ if (separator < 0 || line.slice(0, separator).trim() !== key)
45
+ continue;
46
+ return decodeScalar(line.slice(separator + 1));
47
+ }
48
+ return undefined;
49
+ }
50
+ function cleanInline(value) {
51
+ return value
52
+ .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
53
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
54
+ .replace(/`([^`]+)`/g, '$1')
55
+ .replace(/<[^>]+>/g, '')
56
+ .replace(/[*_~]+/g, '')
57
+ .replace(/\s+/g, ' ')
58
+ .trim();
59
+ }
60
+ function extractTitle(body) {
61
+ let fence;
62
+ for (const line of body.split(/\r?\n/)) {
63
+ const marker = /^\s*(`{3,}|~{3,})/.exec(line)?.[1]?.slice(0, 1);
64
+ if (marker) {
65
+ if (!fence)
66
+ fence = marker;
67
+ else if (marker === fence)
68
+ fence = undefined;
69
+ continue;
70
+ }
71
+ if (fence)
72
+ continue;
73
+ const match = /^#\s+(.+?)\s*$/.exec(line);
74
+ if (match?.[1])
75
+ return cleanInline(match[1].replace(/\s+#+\s*$/, ''));
76
+ }
77
+ return undefined;
78
+ }
79
+ function truncate(value, length) {
80
+ const characters = [];
81
+ for (const character of value)
82
+ characters.push(character);
83
+ if (characters.length <= length)
84
+ return value;
85
+ return `${characters.slice(0, length).join('').trimEnd()}…`;
86
+ }
87
+ function extractSummary(body) {
88
+ const paragraphs = [];
89
+ let current = [];
90
+ let fence;
91
+ let inContainer = false;
92
+ let inTag = false;
93
+ let hiddenTag;
94
+ const finishParagraph = () => {
95
+ if (current.length > 0)
96
+ paragraphs.push(current.join(' '));
97
+ current = [];
98
+ };
99
+ for (const rawLine of body.split(/\r?\n/)) {
100
+ const line = rawLine.trim();
101
+ const marker = /^(`{3,}|~{3,})/.exec(line)?.[1]?.slice(0, 1);
102
+ if (marker) {
103
+ if (!fence)
104
+ fence = marker;
105
+ else if (marker === fence)
106
+ fence = undefined;
107
+ finishParagraph();
108
+ continue;
109
+ }
110
+ if (fence)
111
+ continue;
112
+ if (hiddenTag) {
113
+ if (line.toLowerCase().includes(`</${hiddenTag}>`))
114
+ hiddenTag = undefined;
115
+ continue;
116
+ }
117
+ const hiddenStart = /^<(script|style)(?:\s|>)/i.exec(line)?.[1]?.toLowerCase();
118
+ if (hiddenStart === 'script' || hiddenStart === 'style') {
119
+ hiddenTag = line.toLowerCase().includes(`</${hiddenStart}>`) ? undefined : hiddenStart;
120
+ finishParagraph();
121
+ continue;
122
+ }
123
+ if (line.startsWith(':::')) {
124
+ inContainer = !inContainer;
125
+ finishParagraph();
126
+ continue;
127
+ }
128
+ if (inContainer)
129
+ continue;
130
+ if (inTag) {
131
+ if (line.endsWith('>'))
132
+ inTag = false;
133
+ continue;
134
+ }
135
+ if (line.startsWith('<')) {
136
+ if (!line.endsWith('>'))
137
+ inTag = true;
138
+ finishParagraph();
139
+ continue;
140
+ }
141
+ if (line === '') {
142
+ finishParagraph();
143
+ if (paragraphs.length > 0)
144
+ break;
145
+ continue;
146
+ }
147
+ if (/^(?:#{1,6}\s|>|\||[-*+]\s|\d+[.)]\s|(?:-{3,}|\*{3,}|_{3,})$)/.test(line)) {
148
+ finishParagraph();
149
+ continue;
150
+ }
151
+ current.push(line);
152
+ }
153
+ finishParagraph();
154
+ return truncate(cleanInline(paragraphs[0] ?? ''), SUMMARY_LENGTH);
155
+ }
156
+ function markdownText(body) {
157
+ return cleanInline(body
158
+ .replace(/<!--[\s\S]*?-->/g, ' ')
159
+ .replace(/<(?:script|style)(?:\s[^>]*)?>[\s\S]*?<\/(?:script|style)>/gi, ' ')
160
+ .replace(/<[A-Z][A-Za-z\d]*(?:\s[^>]*)?\s*\/\s*>/g, ' ')
161
+ .replace(/<\/?[A-Z][A-Za-z\d]*(?:\s[^>]*)?>/g, ' ')
162
+ .replace(/^---\s*$/gm, ' ')
163
+ .replace(/^:::[^\n]*$/gm, ' ')
164
+ .replace(/^\s*(?:#{1,6}|>|[-*+]|\d+[.)])\s+/gm, ''));
165
+ }
166
+ function parseAttributes(source) {
167
+ const attributes = {};
168
+ const pattern = /([:@A-Za-z_][:@\w.-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
169
+ for (const match of source.matchAll(pattern)) {
170
+ const name = match[1];
171
+ if (!name)
172
+ continue;
173
+ attributes[name] = match[2] ?? match[3] ?? match[4] ?? true;
174
+ }
175
+ return attributes;
176
+ }
177
+ function componentSource(body) {
178
+ const lines = [];
179
+ let fence;
180
+ for (const line of body.split(/\r?\n/)) {
181
+ const marker = /^\s*(`{3,}|~{3,})/.exec(line)?.[1]?.slice(0, 1);
182
+ if (marker) {
183
+ if (!fence)
184
+ fence = marker;
185
+ else if (marker === fence)
186
+ fence = undefined;
187
+ continue;
188
+ }
189
+ if (!fence)
190
+ lines.push(line);
191
+ }
192
+ return lines.join('\n').replace(/<!--[\s\S]*?-->/g, ' ');
193
+ }
194
+ function extractComponents(body) {
195
+ const components = [];
196
+ const pattern = /<([A-Z][A-Za-z\d]*)\b((?:[^>"']|"[^"]*"|'[^']*')*)\/?\s*>/g;
197
+ for (const match of componentSource(body).matchAll(pattern)) {
198
+ const name = match[1];
199
+ if (!name)
200
+ continue;
201
+ components.push({ attributes: parseAttributes(match[2] ?? ''), name });
202
+ }
203
+ return components;
204
+ }
205
+ function componentText(components) {
206
+ const values = [];
207
+ for (const component of components) {
208
+ if (component.name === 'FactStrip') {
209
+ const facts = component.attributes[':facts'];
210
+ if (typeof facts === 'string') {
211
+ for (const match of facts.matchAll(/\b(?:label|value)\s*:\s*(['"])(.*?)\1/gs)) {
212
+ if (match[2])
213
+ values.push(match[2].replace(/\\(['"\\])/g, '$1'));
214
+ }
215
+ }
216
+ }
217
+ for (const name of COMPONENT_ATTRIBUTES[component.name] ?? []) {
218
+ const value = component.attributes[name];
219
+ if (typeof value === 'string')
220
+ values.push(value);
221
+ }
222
+ }
223
+ return values.join(' ');
224
+ }
225
+ function routeFromPath(path) {
226
+ const withoutExtension = path.replace(/\.md$/i, '');
227
+ if (withoutExtension === 'index')
228
+ return '/';
229
+ if (withoutExtension.endsWith('/index'))
230
+ return `/${withoutExtension.slice(0, -5)}`;
231
+ return `/${withoutExtension}`;
232
+ }
233
+ function fallbackTitle(path) {
234
+ const name = path.slice(path.lastIndexOf('/') + 1);
235
+ return name.replace(/\.md$/i, '');
236
+ }
237
+ export function parseDoc(path, content) {
238
+ const { body, frontmatter } = splitFrontmatter(content);
239
+ const components = extractComponents(body);
240
+ const hero = components.find((component) => component.name === 'PageHero');
241
+ const heroTitle = hero?.attributes.title;
242
+ const heroSummary = hero?.attributes.lede;
243
+ const name = path.slice(path.lastIndexOf('/') + 1);
244
+ const title = cleanInline(extractTitle(body) ??
245
+ frontmatterValue(frontmatter, 'title') ??
246
+ (typeof heroTitle === 'string' ? heroTitle : ''));
247
+ const summary = cleanInline(frontmatterValue(frontmatter, 'summary') ??
248
+ (typeof heroSummary === 'string' ? heroSummary : extractSummary(body)));
249
+ return {
250
+ components,
251
+ content,
252
+ name,
253
+ path,
254
+ route: routeFromPath(path),
255
+ section: path.includes('/') ? (path.split('/')[0] ?? null) : null,
256
+ summary: truncate(summary, SUMMARY_LENGTH),
257
+ title: title || fallbackTitle(path),
258
+ };
259
+ }
260
+ function normalize(value) {
261
+ return value.normalize('NFKC').toLowerCase();
262
+ }
263
+ function countMatches(value, term) {
264
+ let count = 0;
265
+ let offset = 0;
266
+ while (offset < value.length) {
267
+ const index = value.indexOf(term, offset);
268
+ if (index < 0)
269
+ break;
270
+ count += 1;
271
+ offset = index + Math.max(term.length, 1);
272
+ }
273
+ return count;
274
+ }
275
+ function excerpt(text, query, terms) {
276
+ if (!text)
277
+ return '';
278
+ const normalized = normalize(text);
279
+ const exactIndex = normalized.indexOf(query);
280
+ const matchIndex = exactIndex >= 0
281
+ ? exactIndex
282
+ : Math.min(...terms.map((term) => normalized.indexOf(term)).filter((index) => index >= 0));
283
+ if (!Number.isFinite(matchIndex))
284
+ return truncate(text, EXCERPT_LENGTH);
285
+ const start = Math.max(0, matchIndex - Math.floor(EXCERPT_LENGTH / 3));
286
+ const prefix = start > 0 ? '…' : '';
287
+ const value = text.slice(start, start + EXCERPT_LENGTH).trim();
288
+ const suffix = start + EXCERPT_LENGTH < text.length ? '…' : '';
289
+ return `${prefix}${value}${suffix}`;
290
+ }
291
+ export function searchDoc(page, query) {
292
+ const normalizedQuery = normalize(query.trim());
293
+ if (!normalizedQuery)
294
+ throw new TypeError('query must not be empty');
295
+ const terms = normalizedQuery.split(/\s+/).filter(Boolean);
296
+ const componentValue = componentText(page.components);
297
+ const bodyValue = markdownText(splitFrontmatter(page.content).body);
298
+ const textValue = `${componentValue} ${bodyValue}`.trim();
299
+ const title = normalize(page.title);
300
+ const summary = normalize(page.summary);
301
+ const path = normalize(page.path.replace(/[-_/]+/g, ' '));
302
+ const components = normalize(componentValue);
303
+ const text = normalize(bodyValue);
304
+ const combined = `${title}\n${summary}\n${path}\n${components}\n${text}`;
305
+ if (!terms.every((term) => combined.includes(term)))
306
+ return null;
307
+ let score = title === normalizedQuery ? 240 : 0;
308
+ score += countMatches(title, normalizedQuery) * 80;
309
+ score += countMatches(summary, normalizedQuery) * 40;
310
+ score += countMatches(components, normalizedQuery) * 60;
311
+ score += countMatches(path, normalizedQuery) * 24;
312
+ score += Math.min(countMatches(text, normalizedQuery), 5) * 10;
313
+ for (const term of terms) {
314
+ score += countMatches(title, term) * 24;
315
+ score += countMatches(summary, term) * 12;
316
+ score += countMatches(components, term) * 18;
317
+ score += countMatches(path, term) * 8;
318
+ score += Math.min(countMatches(text, term), 5) * 3;
319
+ }
320
+ return {
321
+ excerpt: excerpt(textValue, normalizedQuery, terms),
322
+ name: page.name,
323
+ path: page.path,
324
+ route: page.route,
325
+ score,
326
+ section: page.section,
327
+ summary: page.summary,
328
+ title: page.title,
329
+ };
330
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createDocsClient } from './client.js';
2
- export type { DocItem, DocsClient, DocsClientOptions } from './types.js';
2
+ export { parseDoc } from './content.js';
3
+ export type { DocComponent, DocItem, DocPage, DocSection, DocsClient, DocsClientOptions, DocsSearchOptions, DocsSearchResult, } from './types.js';
3
4
  export { DocsFetchError } from './types.js';
4
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { createDocsClient } from './client.js';
2
+ export { parseDoc } from './content.js';
2
3
  export { DocsFetchError } from './types.js';
3
- //# sourceMappingURL=index.js.map
package/dist/types.d.ts CHANGED
@@ -3,6 +3,39 @@ export interface DocItem {
3
3
  path: string;
4
4
  type: 'file' | 'dir';
5
5
  }
6
+ export interface DocComponent {
7
+ attributes: Readonly<Record<string, string | true>>;
8
+ name: string;
9
+ }
10
+ export interface DocPage {
11
+ components: DocComponent[];
12
+ content: string;
13
+ name: string;
14
+ path: string;
15
+ route: string;
16
+ section: string | null;
17
+ summary: string;
18
+ title: string;
19
+ }
20
+ export interface DocSection {
21
+ count: number;
22
+ indexPath?: string;
23
+ path: string;
24
+ }
25
+ export interface DocsSearchOptions {
26
+ limit?: number;
27
+ pathPrefix?: string;
28
+ }
29
+ export interface DocsSearchResult {
30
+ excerpt: string;
31
+ name: string;
32
+ path: string;
33
+ route: string;
34
+ score: number;
35
+ section: string | null;
36
+ summary: string;
37
+ title: string;
38
+ }
6
39
  export interface DocsClientOptions {
7
40
  owner?: string;
8
41
  repo?: string;
@@ -16,7 +49,10 @@ export interface DocsClientOptions {
16
49
  export interface DocsClient {
17
50
  listDir(path?: string): Promise<DocItem[]>;
18
51
  listAll(): Promise<DocItem[]>;
52
+ listSections(): Promise<DocSection[]>;
19
53
  getFile(path: string): Promise<string>;
54
+ getDocument(path: string): Promise<DocPage>;
55
+ search(query: string, options?: DocsSearchOptions): Promise<DocsSearchResult[]>;
20
56
  clear(): void;
21
57
  }
22
58
  export declare class DocsFetchError extends Error {
@@ -24,4 +60,3 @@ export declare class DocsFetchError extends Error {
24
60
  readonly status: number | null;
25
61
  constructor(path: string, status: number | null, message: string);
26
62
  }
27
- //# sourceMappingURL=types.d.ts.map
package/dist/types.js CHANGED
@@ -6,4 +6,3 @@ export class DocsFetchError extends Error {
6
6
  this.name = 'DocsFetchError';
7
7
  }
8
8
  }
9
- //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nbtca/docs",
3
- "version": "0.2.3",
4
- "description": "Data-only library for the NBTCA documents repository",
3
+ "version": "0.3.0",
4
+ "description": "GitHub-backed document client for NBTCA",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -18,11 +18,16 @@
18
18
  "scripts": {
19
19
  "clean": "node --input-type=module --eval \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
20
20
  "prebuild": "npm run clean",
21
- "build": "tsc",
21
+ "build": "tsc -p tsconfig.build.json",
22
+ "format": "prettier --write .",
23
+ "format:check": "prettier --check .",
24
+ "lint": "eslint . --max-warnings 0",
25
+ "typecheck": "tsc --noEmit",
22
26
  "test": "vitest run",
23
27
  "precheck:package": "npm run build",
24
28
  "check:package": "node scripts/check-package.mjs",
25
- "check": "npm test && npm run check:package && npm audit --audit-level=moderate",
29
+ "audit": "npm audit --audit-level=moderate",
30
+ "check": "npm run format:check && npm run lint && npm run typecheck && npm test && npm run check:package && npm run audit",
26
31
  "prepublishOnly": "npm run check"
27
32
  },
28
33
  "keywords": [
@@ -46,8 +51,15 @@
46
51
  "node": ">=20.12.0"
47
52
  },
48
53
  "devDependencies": {
49
- "@types/node": "^26.0.0",
50
- "typescript": "^5.4.0",
54
+ "@eslint/js": "^9.39.5",
55
+ "@types/node": "20.12.12",
56
+ "eslint": "^9.39.5",
57
+ "eslint-config-prettier": "^10.1.8",
58
+ "globals": "^17.9.0",
59
+ "prettier": "^3.9.6",
60
+ "typescript": "^5.9.3",
61
+ "typescript-eslint": "^8.67.0",
62
+ "vite": "6.4.3",
51
63
  "vitest": "^3.2.7"
52
64
  }
53
65
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAKA,qBAAa,QAAQ,CAAC,CAAC;IAInB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+B;gBAGhC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAW;IAGvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAO/B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAKhC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,WAAW;CAMpB"}
package/dist/cache.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,QAAQ;IAGnB,YACmB,KAAa,EACb,UAAkB,EAAE;QADpB,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAa;QAJtB,QAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IAKhD,CAAC;IAEJ,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,WAAW,EAAE,CAAC;IACvD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAEO,WAAW;QACjB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;aACnC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;aAC/C,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAW,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAsIzE,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAqL5E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM,GAAG,IAAI;gBADrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrC,OAAO,EAAE,MAAM;CAKlB"}
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YACkB,IAAY,EACZ,MAAqB,EACrC,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAe;QAIrC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}