@littlebigbrain/client 0.1.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 +127 -0
- package/dist/client.d.ts +764 -0
- package/dist/client.js +878 -0
- package/dist/client.test.d.ts +1 -0
- package/dist/client.test.js +591 -0
- package/dist/contract-routes.test.d.ts +1 -0
- package/dist/contract-routes.test.js +74 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/schema.d.ts +13864 -0
- package/dist/schema.js +5 -0
- package/package.json +28 -0
- package/src/client.test.ts +673 -0
- package/src/client.ts +1428 -0
- package/src/contract-routes.test.ts +91 -0
- package/src/index.ts +16 -0
- package/src/node-test-shim.d.ts +16 -0
- package/src/schema.ts +13865 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# @lbb/client
|
|
2
|
+
|
|
3
|
+
TypeScript client for the [Little Big Brain](../../README.md) graph + hybrid search HTTP
|
|
4
|
+
API. Request and response types are generated from the committed
|
|
5
|
+
[`contracts/openapi.json`](../../contracts/openapi.json) (the single source of
|
|
6
|
+
truth, derived from the Rust `lbb-api` types); the client itself is a thin,
|
|
7
|
+
dependency-free wrapper over the platform `fetch`.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @lbb/client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { LbbClient, LbbError } from "@lbb/client";
|
|
17
|
+
|
|
18
|
+
const lbb = new LbbClient({
|
|
19
|
+
baseUrl: "https://db.eu.littlebigbrain.com",
|
|
20
|
+
apiKey: process.env.LBB_API_KEY, // lbb_sk_test_… or lbb_sk_live_…
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
await lbb.graph("main").facts.create({
|
|
24
|
+
triplets: [
|
|
25
|
+
{
|
|
26
|
+
source: { type: "SERVICE", name: "auth-service" },
|
|
27
|
+
relation: "WRITES_TO",
|
|
28
|
+
target: { type: "DATABASE", name: "user-db" },
|
|
29
|
+
confidence: 0.93,
|
|
30
|
+
evidence: "auth-service writes identity records to user-db",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
}, {
|
|
34
|
+
idempotencyKey: "import-2026-06-13",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await lbb.indexes.run({ wait: true });
|
|
38
|
+
|
|
39
|
+
const results = await lbb.search.hybrid("which systems store customer identity data", {
|
|
40
|
+
topK: 5,
|
|
41
|
+
source: "persisted",
|
|
42
|
+
consistency: "strong",
|
|
43
|
+
targets: ["entities", "assertions"],
|
|
44
|
+
});
|
|
45
|
+
for (const assertion of results.assertions ?? []) {
|
|
46
|
+
console.log(assertion.relation?.name, assertion.score);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Use `client.graph("name")` to scope graph writes and `client.rawRequest(...)`
|
|
51
|
+
when you need response metadata (`requestId`, `version`, headers). Every method
|
|
52
|
+
returns parsed JSON and throws `LbbError` with `status`, `type`, `code`,
|
|
53
|
+
`message`, `param`, `requestId`, and `docUrl` on a non-2xx response.
|
|
54
|
+
|
|
55
|
+
## Methods
|
|
56
|
+
|
|
57
|
+
| Area | Methods |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| Write | `graph("main").facts.create` |
|
|
60
|
+
| Search | `search.hybrid`, `search.multi`, `search.fullText`, `search.vector` |
|
|
61
|
+
| Search feedback (training data) | `searchFeedback` (grade results 3/1/0 → customer qrels), `searchFeedbackExport` |
|
|
62
|
+
| Traversal | `traverse`, `semanticTraverse` |
|
|
63
|
+
| Temporal / lineage / shapes | `currentState`, `history`, `why`, `shacl` |
|
|
64
|
+
| SPARQL | `sparqlRows`, `sparql` (SELECT/ASK/aggregate; GROUP BY entity, property, or date bucket), `sparqlText`, `analytics` |
|
|
65
|
+
| Ontology | `ontologyView` (add `{ counts: true }` for per-relation `edge_count`), `ontologySearch`, `ontologyResolve`, `ontologyDefine` |
|
|
66
|
+
| Index lifecycle | `indexes.run`, `indexes.build`, `indexes.delta`, `indexes.gc`, `compact` |
|
|
67
|
+
| Inspection | `entities.list`, `entities.filterByAttributes`, `status`, `metadata`, `summary` |
|
|
68
|
+
| Schema activation | `schema.view`, `schema.preview`, `schema.publish`, `schema.audit` |
|
|
69
|
+
| Database admin | `adminCreateStack`, `adminStack`, `adminRotateStackKey`, `adminDeleteStack` |
|
|
70
|
+
|
|
71
|
+
Request/response shapes are exported as `Schemas["TypeName"]` (e.g.
|
|
72
|
+
`Schemas["SemanticGraphSearchRequest"]`); the raw generated `components`,
|
|
73
|
+
`paths`, and `operations` are exported too.
|
|
74
|
+
|
|
75
|
+
## SPARQL
|
|
76
|
+
|
|
77
|
+
`client.sparqlRows(...)` runs a SPARQL 1.1 text query (SELECT or ASK) and
|
|
78
|
+
returns parsed results, so you never have to `JSON.parse` the results string or
|
|
79
|
+
zip `head.vars` with binding values yourself:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const { vars, rows } = await client.sparqlRows({
|
|
83
|
+
query: `SELECT ?service ?db WHERE {
|
|
84
|
+
?service <https://littlebigbrain.com/r/writes_to> ?db
|
|
85
|
+
} LIMIT 10`,
|
|
86
|
+
reason: true, // optional: fold in rule-derived edges
|
|
87
|
+
});
|
|
88
|
+
for (const row of rows) console.log(row.service, "->", row.db);
|
|
89
|
+
|
|
90
|
+
const exists = (await client.sparqlRows({ query: "ASK { ?s ?p ?o }" })).boolean;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
For app code that already has relation patterns but just needs typed attribute
|
|
94
|
+
predicates, `client.entities.filterByAttributes(...)` builds the structured
|
|
95
|
+
SPARQL filter body without exposing RDF property IRIs:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
await client.entities.filterByAttributes({
|
|
99
|
+
patterns: [{ subject: { var: "service" }, predicate: "WRITES_TO", object: { var: "db" } }],
|
|
100
|
+
where: [{ field: "slo", op: "ge", value: 0.99 }, { var: "db", field: "tier", value: "prod" }],
|
|
101
|
+
select: ["service"],
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`sparqlRows` returns `{ vars, boolean, bindings, rows }`: `rows` is the bindings
|
|
106
|
+
flattened to `{ variable: lexicalValue }`, `bindings` keeps the raw typed term
|
|
107
|
+
objects, and `boolean` is the ASK answer (or `null` for a SELECT). `client.sparqlText(...)`
|
|
108
|
+
returns the unparsed envelope, and the standalone `parseSparqlResults(response)`
|
|
109
|
+
helper (also exported) parses it. For the structured BGP form use
|
|
110
|
+
`client.sparql(body)` (`SparqlSelectRequest`).
|
|
111
|
+
|
|
112
|
+
A standalone stack also serves the **native SPARQL 1.1 Protocol** at `/sparql`
|
|
113
|
+
(`GET ?query=`, `POST` form or `application/sparql-query` body,
|
|
114
|
+
`Accept`-negotiated JSON/XML/CSV/TSV) for off-the-shelf SPARQL clients (YASGUI,
|
|
115
|
+
Protégé); `sparqlRows` returns parsed JSON rows for in-process use.
|
|
116
|
+
|
|
117
|
+
## Develop
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
npm install
|
|
121
|
+
npm run generate # regenerate src/schema.ts from ../../contracts/openapi.json
|
|
122
|
+
npm run build # tsc -> dist/
|
|
123
|
+
npm test # build + node:test (mocked fetch)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`runtime`: any environment with a global `fetch` (Node 18+, browsers, edge
|
|
127
|
+
workers), or pass your own via the `fetch` option.
|