nusus 0.2.1 → 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.
Files changed (37) hide show
  1. package/README.md +26 -5
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/models.d.ts +38 -0
  5. package/dist/models.d.ts.map +1 -1
  6. package/dist/turath/catalog-authors.d.ts +2 -0
  7. package/dist/turath/catalog-authors.d.ts.map +1 -0
  8. package/dist/turath/catalog-authors.js +3043 -0
  9. package/dist/turath/catalog-authors.js.map +1 -0
  10. package/dist/turath/catalog-data.d.ts +1 -0
  11. package/dist/turath/catalog-data.d.ts.map +1 -1
  12. package/dist/turath/catalog-data.js +1 -0
  13. package/dist/turath/catalog-data.js.map +1 -1
  14. package/dist/turath/catalog.d.ts +7 -1
  15. package/dist/turath/catalog.d.ts.map +1 -1
  16. package/dist/turath/catalog.js +73 -9
  17. package/dist/turath/catalog.js.map +1 -1
  18. package/dist/turath/citations.d.ts +8 -1
  19. package/dist/turath/citations.d.ts.map +1 -1
  20. package/dist/turath/citations.js +16 -1
  21. package/dist/turath/citations.js.map +1 -1
  22. package/dist/turath/client.d.ts +7 -6
  23. package/dist/turath/client.d.ts.map +1 -1
  24. package/dist/turath/client.js +38 -15
  25. package/dist/turath/client.js.map +1 -1
  26. package/dist/turath/excerpt.d.ts +22 -0
  27. package/dist/turath/excerpt.d.ts.map +1 -0
  28. package/dist/turath/excerpt.js +147 -0
  29. package/dist/turath/excerpt.js.map +1 -0
  30. package/dist/turath/index.d.ts +3 -3
  31. package/dist/turath/index.d.ts.map +1 -1
  32. package/dist/turath/index.js +2 -2
  33. package/dist/turath/index.js.map +1 -1
  34. package/dist/turath/normalize.d.ts.map +1 -1
  35. package/dist/turath/normalize.js +2 -5
  36. package/dist/turath/normalize.js.map +1 -1
  37. package/package.json +4 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Nusus
2
2
 
3
- TypeScript SDK for searching and citing classical Islamic and Arabic texts through [Turath](https://app.turath.io/), a Shamela-style digital library. Use Nusus to retrieve source text, metadata, citations, and direct links from Arabic heritage books for research tools and AI agents.
3
+ TypeScript SDK for searching and citing classical Islamic and Arabic texts through [Turath](https://app.turath.io/), a Shamela-style digital library. Use Nusus to retrieve source text, metadata, citations, locators, and direct links from Arabic heritage books for research tools and AI agents.
4
4
 
5
5
  ```bash
6
6
  npm install nusus
@@ -13,7 +13,9 @@ import { createTurathClient } from "nusus/turath";
13
13
 
14
14
  const turath = createTurathClient({ timeout: 10_000 });
15
15
  const books = turath.findBooks("الأربعون النووية");
16
+ const authors = turath.findAuthors("النووي");
16
17
  const categories = turath.listCategories();
18
+ const catalog = turath.getCatalogMetadata();
17
19
  const results = await turath.search("إنما الأعمال بالنيات", {
18
20
  bookIds: [147927],
19
21
  });
@@ -21,19 +23,28 @@ const context = await turath.getContext(results.items[0]);
21
23
 
22
24
  console.log(context.text);
23
25
  console.log(context.citation);
26
+ console.log(context.locator);
24
27
  console.log(context.url);
25
28
  ```
26
29
 
27
- Agent-ready retrieval is one call:
30
+ Agent-ready retrieval is one call. By default each hit is a single page with a match-centered excerpt; adjacent pages are opt-in:
28
31
 
29
32
  ```ts
30
33
  const context = await turath.retrieve("النية", {
31
34
  maxPassages: 5,
32
35
  maxCharsPerPassage: 2_000,
36
+ // pagesBefore: 1,
37
+ // pagesAfter: 1,
33
38
  });
39
+
40
+ for (const passage of context.passages) {
41
+ console.log(passage.citation); // includes تراث bookId + صفحة تراث
42
+ console.log(passage.locator); // { bookId, internalPage, url, ... }
43
+ console.log(passage.provenance); // rank, truncation, scope, ...
44
+ }
34
45
  ```
35
46
 
36
- All requests support `AbortSignal`; failures use the exported `NususError` codes. Source text is returned unchanged. Search filters currently accept one Turath ID each because that is all the upstream API has verified.
47
+ All requests support `AbortSignal`; failures use the exported `NususError` codes. Source text is returned unchanged. Search filters currently accept one Turath ID each because that is all the upstream API has verified. The core SDK is retrieval-only: no madhhab ranking, fatwa logic, or hadith grading.
37
48
 
38
49
  ## Agent CLI
39
50
 
@@ -50,7 +61,11 @@ The CLI emits JSON Lines with passage text, source metadata, citations, and dire
50
61
 
51
62
  ## Known limitations
52
63
 
53
- Book and category discovery uses a bundled snapshot of 8,124 Turath books scanned in March 2026 because Turath does not expose verified catalog endpoints. Newly added or changed upstream records may therefore be absent until the snapshot is refreshed. Author-name discovery is not yet available; catalog books retain their author IDs. Browser support is not claimed because the checked API responses do not advertise CORS support.
64
+ Book and category discovery uses a bundled snapshot of 8,124 Turath books scanned in March 2026 because Turath does not expose verified catalog endpoints. Newly added or changed upstream records may therefore be absent until the snapshot is refreshed.
65
+
66
+ Offline author discovery uses an ID→name map verified via official `GET /author` only (no fabricated names), plus live `getAuthor()` for full metadata. `getCatalogMetadata()` reports known book/author ID counts, resolved offline names, and unresolved author IDs. Re-hydrate or resume with `bun scripts/refresh-catalog.mjs authors` (resumable, rate-limit aware). Book listing refresh is fail-closed: `bun scripts/refresh-catalog.mjs books` refuses unofficial sources.
67
+
68
+ Browser support is not claimed because the checked API responses do not advertise CORS support.
54
69
 
55
70
  ## Development
56
71
 
@@ -59,5 +74,11 @@ bun install
59
74
  bun test
60
75
  bun run typecheck
61
76
  bun run build
62
- ```
63
77
 
78
+ # optional live contract (also scheduled via GitHub Actions)
79
+ bun run test:live
80
+
81
+ # official-API catalog tooling
82
+ bun scripts/refresh-catalog.mjs authors --limit 10
83
+ bun scripts/refresh-catalog.mjs books # fails closed on purpose
84
+ ```
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { NususError } from "./errors.js";
2
2
  export type { NususErrorCode } from "./errors.js";
3
- export type { Author, AuthorSummary, Book, BookSummary, Category, CategorySummary, Passage, RetrievedContext, SearchPage, SourceLocation, TurathId, } from "./models.js";
3
+ export type { Author, AuthorSummary, Book, BookSummary, CatalogMetadata, Category, CategorySummary, Passage, PassageProvenance, RetrievedContext, RetrieveScope, SearchPage, SourceLocation, SourceLocator, TurathId, } from "./models.js";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACV,MAAM,EACN,aAAa,EACb,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACV,MAAM,EACN,aAAa,EACb,IAAI,EACJ,WAAW,EACX,eAAe,EACf,QAAQ,EACR,eAAe,EACf,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,QAAQ,GACT,MAAM,aAAa,CAAC"}
package/dist/models.d.ts CHANGED
@@ -36,6 +36,31 @@ export type SourceLocation = {
36
36
  printedPage?: number;
37
37
  volume?: string;
38
38
  };
39
+ export type SourceLocator = {
40
+ bookId: string;
41
+ internalPage?: number;
42
+ printedPage?: number;
43
+ volume?: string;
44
+ url: string;
45
+ };
46
+ export type RetrieveScope = {
47
+ bookIds?: TurathId[];
48
+ authorIds?: TurathId[];
49
+ categoryIds?: TurathId[];
50
+ };
51
+ export type PassageProvenance = {
52
+ query: string;
53
+ scope?: RetrieveScope;
54
+ rank: number;
55
+ totalMatches: number;
56
+ truncated: boolean;
57
+ truncation?: "prefix" | "match-window";
58
+ contextPages: {
59
+ before: number;
60
+ after: number;
61
+ };
62
+ retrievedVia: "page" | "search-hit";
63
+ };
39
64
  export type Passage = {
40
65
  provider: "turath";
41
66
  book: BookSummary;
@@ -47,6 +72,8 @@ export type Passage = {
47
72
  headings: string[];
48
73
  url: string;
49
74
  citation: string;
75
+ locator?: SourceLocator;
76
+ provenance?: PassageProvenance;
50
77
  raw?: unknown;
51
78
  };
52
79
  export type SearchPage = {
@@ -59,4 +86,15 @@ export type RetrievedContext = {
59
86
  totalMatches: number;
60
87
  query: string;
61
88
  };
89
+ export type CatalogMetadata = {
90
+ scannedAt: string;
91
+ bookCount: number;
92
+ categoryCount: number;
93
+ /** Distinct author IDs referenced by the bundled book catalog. */
94
+ authorIdCount: number;
95
+ /** Bundled offline author names verified via official GET /author. */
96
+ authorNameCount: number;
97
+ /** Known catalog author IDs with no verified offline name (missing/empty upstream or not yet hydrated). */
98
+ unresolvedAuthorIdCount: number;
99
+ };
62
100
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvC,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,eAAe,GAAG;IACvC,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,aAAa,GAAG;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,WAAW,GAAG;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CATALOG_AUTHORS: readonly [number, string][];
2
+ //# sourceMappingURL=catalog-authors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-authors.d.ts","sourceRoot":"","sources":["../../src/turath/catalog-authors.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EA89FtD,CAAC"}