@qaecy/cue-sdk 0.0.5 → 0.0.8
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/PORTAL_MIGRATION.md +346 -0
- package/README.md +50 -3
- package/cue-BIvMahsX.js +3553 -0
- package/index.d.ts +13 -1
- package/index.js +15 -3
- package/lib/api.d.ts +1 -2
- package/lib/auth.d.ts +41 -2
- package/lib/cache.d.ts +26 -0
- package/lib/cue.d.ts +42 -2
- package/lib/documents.d.ts +84 -0
- package/lib/entities.d.ts +107 -0
- package/lib/models.d.ts +201 -9
- package/lib/privileges.d.ts +53 -0
- package/lib/profile.d.ts +22 -5
- package/lib/project-view.d.ts +107 -0
- package/lib/project.d.ts +17 -2
- package/lib/schema.d.ts +66 -0
- package/lib/signal.d.ts +54 -0
- package/lib/sync.d.ts +79 -0
- package/node.js +45 -302
- package/package.json +1 -1
- package/variables.d.ts +40 -0
- package/cue-y-t8nSnt.js +0 -353
package/lib/models.d.ts
CHANGED
|
@@ -16,12 +16,12 @@ export interface CueEndpoints {
|
|
|
16
16
|
firestoreEmulatorPort: number;
|
|
17
17
|
}
|
|
18
18
|
export interface CueSdkConfig {
|
|
19
|
-
/** Firebase API key for this project */
|
|
20
|
-
apiKey
|
|
21
|
-
/** Firebase App ID */
|
|
22
|
-
appId
|
|
23
|
-
/** Firebase Measurement ID */
|
|
24
|
-
measurementId
|
|
19
|
+
/** Firebase API key for this project. Defaults to the QAECY demo app if omitted. */
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
/** Firebase App ID. Defaults to the QAECY demo app if omitted. */
|
|
22
|
+
appId?: string;
|
|
23
|
+
/** Firebase Measurement ID. Defaults to the QAECY demo app if omitted. */
|
|
24
|
+
measurementId?: string;
|
|
25
25
|
/** Target environment. Defaults to 'production'. */
|
|
26
26
|
environment?: CueEnvironment;
|
|
27
27
|
/** Override individual endpoint URLs. Takes precedence over environment. */
|
|
@@ -40,6 +40,11 @@ export interface SearchRequest {
|
|
|
40
40
|
/** Optional category filters */
|
|
41
41
|
categories?: string[];
|
|
42
42
|
}
|
|
43
|
+
/** Options for `CueProjectView.search()`. */
|
|
44
|
+
export interface SearchOptions {
|
|
45
|
+
/** Optional content category IRI filters. */
|
|
46
|
+
categories?: string[];
|
|
47
|
+
}
|
|
43
48
|
export interface SearchSource {
|
|
44
49
|
item: string;
|
|
45
50
|
parent: string;
|
|
@@ -60,9 +65,11 @@ export interface ProjectSettings {
|
|
|
60
65
|
}>;
|
|
61
66
|
chatDisabled: boolean;
|
|
62
67
|
graph?: {
|
|
63
|
-
type:
|
|
64
|
-
uri
|
|
68
|
+
type: 'qlever' | 'fuseki';
|
|
69
|
+
uri?: string;
|
|
65
70
|
};
|
|
71
|
+
/** Processing tier determining credit costs. Defaults to "l" if not set. */
|
|
72
|
+
tier?: 's' | 'm' | 'l';
|
|
66
73
|
}
|
|
67
74
|
export interface ProjectData {
|
|
68
75
|
id: string;
|
|
@@ -84,6 +91,23 @@ export interface CreateProjectOptions {
|
|
|
84
91
|
name: string;
|
|
85
92
|
/** Explicit project ID. Defaults to a new UUID. */
|
|
86
93
|
id?: string;
|
|
94
|
+
/** UIDs to set as project admins. Non-superadmin callers are always included automatically. */
|
|
95
|
+
admins?: string[];
|
|
96
|
+
/** UIDs to set as project syncers. Non-superadmin callers are always included automatically. */
|
|
97
|
+
syncers?: string[];
|
|
98
|
+
/** UIDs to set as project members. Non-superadmin callers are always included automatically. */
|
|
99
|
+
members?: string[];
|
|
100
|
+
/** Graph backend type. The service maps this to the configured URI. */
|
|
101
|
+
graphType?: 'fuseki' | 'qlever';
|
|
102
|
+
/** Processing tier determining credit costs. */
|
|
103
|
+
tier?: 's' | 'm' | 'l';
|
|
104
|
+
}
|
|
105
|
+
export interface SyncProgress {
|
|
106
|
+
percent: number;
|
|
107
|
+
syncCount: number;
|
|
108
|
+
totalCount: number;
|
|
109
|
+
syncSize: number;
|
|
110
|
+
totalSize: number;
|
|
87
111
|
}
|
|
88
112
|
export interface SyncOptions {
|
|
89
113
|
/** The project/space ID to sync into */
|
|
@@ -94,7 +118,16 @@ export interface SyncOptions {
|
|
|
94
118
|
userId: string;
|
|
95
119
|
/** Enable verbose logging */
|
|
96
120
|
verbose?: boolean;
|
|
121
|
+
/** Called whenever upload progress changes */
|
|
122
|
+
onProgress?: (progress: SyncProgress) => void;
|
|
123
|
+
/** Write RDF as BLOBs to the processed bucket instead of patching the graph directly */
|
|
124
|
+
legacy?: boolean;
|
|
97
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Credit cost table fetched from the public bucket (`unit-credit.json`).
|
|
128
|
+
* Maps file extension → tier → credits per unit.
|
|
129
|
+
*/
|
|
130
|
+
export type UnitCreditMap = Partial<Record<'s' | 'm' | 'l', Record<string, number>>>;
|
|
98
131
|
/** Per-extension cost breakdown returned by {@link CueSyncApi.scanCost}. */
|
|
99
132
|
export interface ScanOutputRecord {
|
|
100
133
|
/** File extension (without leading dot), e.g. `"pdf"`, `"ifc"`. */
|
|
@@ -109,17 +142,29 @@ export interface ScanOutputRecord {
|
|
|
109
142
|
units: number;
|
|
110
143
|
/** Total size of files with this extension in megabytes. */
|
|
111
144
|
sizeMb: number;
|
|
145
|
+
/** Credits to consume for this extension (units × credit-per-unit for the project tier). */
|
|
146
|
+
credits?: number;
|
|
112
147
|
}
|
|
113
148
|
export interface UnitsConsumedDto {
|
|
149
|
+
creditsAvailable: number;
|
|
150
|
+
creditsConsumed: number;
|
|
151
|
+
filesProcessed: number;
|
|
114
152
|
unitsAvailable: number;
|
|
115
153
|
unitsConsumed: number;
|
|
116
|
-
filesProcessed: number;
|
|
117
154
|
}
|
|
118
155
|
export interface SyncPreview {
|
|
119
156
|
/** Per-extension cost breakdown for files not yet synced */
|
|
120
157
|
costRecords: ScanOutputRecord[];
|
|
158
|
+
/** Project tier used for cost calculation */
|
|
159
|
+
tier: 's' | 'm' | 'l';
|
|
160
|
+
/** Human-readable tier name from tier-names.json */
|
|
161
|
+
tierName: string;
|
|
121
162
|
/** Total units required for the new files */
|
|
122
163
|
unitsToConsume: number;
|
|
164
|
+
/** Total credits to consume (derived from unit-credit.json + project tier) */
|
|
165
|
+
creditsToConsume: number;
|
|
166
|
+
/** Credits currently available for this project */
|
|
167
|
+
creditsAvailable: number;
|
|
123
168
|
/** Units still available for this project */
|
|
124
169
|
unitsAvailable: number;
|
|
125
170
|
/** Number of new files that would be uploaded */
|
|
@@ -140,6 +185,23 @@ export interface SyncResult {
|
|
|
140
185
|
totalSize: number;
|
|
141
186
|
/** Whether any RDF metadata was written */
|
|
142
187
|
rdfWritten: boolean;
|
|
188
|
+
/** Updated credit balance after sync, fetched from the consumption endpoint */
|
|
189
|
+
creditsAvailable: number;
|
|
190
|
+
}
|
|
191
|
+
export interface OrgMember {
|
|
192
|
+
uid: string;
|
|
193
|
+
name: string;
|
|
194
|
+
email: string;
|
|
195
|
+
isAdmin: boolean;
|
|
196
|
+
}
|
|
197
|
+
export interface OrganizationData {
|
|
198
|
+
id: string;
|
|
199
|
+
name: string;
|
|
200
|
+
created: string;
|
|
201
|
+
admins: string[];
|
|
202
|
+
members: string[];
|
|
203
|
+
alternativeIDs: string[];
|
|
204
|
+
domain: string;
|
|
143
205
|
}
|
|
144
206
|
export interface ProfileSSOAccount {
|
|
145
207
|
id: string;
|
|
@@ -154,3 +216,133 @@ export interface APIKeyDoc {
|
|
|
154
216
|
uid: string;
|
|
155
217
|
expiration: string;
|
|
156
218
|
}
|
|
219
|
+
/** Alias for {@link ProjectData} — the Firestore document shape for a project. */
|
|
220
|
+
export type ProjectDoc = ProjectData;
|
|
221
|
+
/** Alias for {@link OrganizationData} — the Firestore document shape for an org. */
|
|
222
|
+
export type OrganizationDoc = OrganizationData;
|
|
223
|
+
export interface UserDoc {
|
|
224
|
+
id: string;
|
|
225
|
+
name: string;
|
|
226
|
+
email: string;
|
|
227
|
+
created: string;
|
|
228
|
+
lastVisit: string;
|
|
229
|
+
lastVisitProjects?: Record<string, string>;
|
|
230
|
+
organizations: string[];
|
|
231
|
+
locale?: string;
|
|
232
|
+
hasAcceptedTermsAndConditions: boolean;
|
|
233
|
+
}
|
|
234
|
+
export interface RDFWritingDoc {
|
|
235
|
+
id: string;
|
|
236
|
+
accumulatedSizeSinceLastIdleEvent: number;
|
|
237
|
+
accumulatedFilesSinceLastIdleEvent: number;
|
|
238
|
+
firstRDFWrite: string;
|
|
239
|
+
lastRDFWrite: string;
|
|
240
|
+
}
|
|
241
|
+
export interface ViewDefinition {
|
|
242
|
+
id: string;
|
|
243
|
+
pinned?: boolean;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Minimal cache interface for SPARQL query results.
|
|
247
|
+
*
|
|
248
|
+
* Implement this against any storage backend (Cloud Storage, localStorage,
|
|
249
|
+
* IndexedDB, in-memory Map) and pass it to the project-view classes to enable
|
|
250
|
+
* stale-while-revalidate query caching.
|
|
251
|
+
*
|
|
252
|
+
* The Angular adapter wires this to `CueCache` from `cue-repos`.
|
|
253
|
+
*/
|
|
254
|
+
export interface QueryCache {
|
|
255
|
+
get(key: string): Promise<unknown | undefined>;
|
|
256
|
+
set(key: string, data: unknown): Promise<void>;
|
|
257
|
+
}
|
|
258
|
+
/** A taxonomy node (content category or entity category) from the triplestore. */
|
|
259
|
+
export interface CategoryDef {
|
|
260
|
+
iri: string;
|
|
261
|
+
label: string;
|
|
262
|
+
/** IRI of the parent category (skos:broader), if any. */
|
|
263
|
+
parent?: string;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* A relationship type discovered in the triplestore via `qcy:relatedEntity` property scan.
|
|
267
|
+
* The IRI is the property IRI, label is its rdfs:label.
|
|
268
|
+
*/
|
|
269
|
+
export type RelationshipDef = CategoryDef;
|
|
270
|
+
/** Core label + classification data for a single entity. */
|
|
271
|
+
export interface EntityCoreData {
|
|
272
|
+
value: string;
|
|
273
|
+
categories: string[];
|
|
274
|
+
mentionCount?: number;
|
|
275
|
+
}
|
|
276
|
+
/** A single directed relationship edge between two entities. */
|
|
277
|
+
export interface EntityRelationship {
|
|
278
|
+
/** IRI of the property used (e.g. `qcy:hasContractor`). */
|
|
279
|
+
relIRI: string;
|
|
280
|
+
/** Full IRI of the related entity. */
|
|
281
|
+
nodeIRI: string;
|
|
282
|
+
/** Label of the related entity. */
|
|
283
|
+
nodeValue: string;
|
|
284
|
+
/** Category IRIs of the related entity. */
|
|
285
|
+
nodeCategories: string[];
|
|
286
|
+
}
|
|
287
|
+
/** Incoming and outgoing relationship edges for one entity. */
|
|
288
|
+
export interface EntityRelationships {
|
|
289
|
+
incoming: EntityRelationship[];
|
|
290
|
+
outgoing: EntityRelationship[];
|
|
291
|
+
}
|
|
292
|
+
/** An OSM geometry associated with an entity or related entity. */
|
|
293
|
+
export interface MapGeometry {
|
|
294
|
+
osmIRI: string;
|
|
295
|
+
wkt: string;
|
|
296
|
+
}
|
|
297
|
+
/** Fully resolved data for a single entity, merging all lazy-loaded slices. */
|
|
298
|
+
export interface EntityDetailedData extends EntityCoreData {
|
|
299
|
+
relationshipData?: EntityRelationships;
|
|
300
|
+
/** UUIDs of documents that reference this entity. */
|
|
301
|
+
documentRefs?: string[];
|
|
302
|
+
directMapGeometries?: MapGeometry[];
|
|
303
|
+
indirectMapGeometries?: Array<{
|
|
304
|
+
rel: string;
|
|
305
|
+
entityUUID: string;
|
|
306
|
+
geometries: MapGeometry[];
|
|
307
|
+
}>;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Project-level entity category graph — nodes are category IRIs, edges
|
|
311
|
+
* represent the `qcy:relatedEntity` connection at the category level.
|
|
312
|
+
*/
|
|
313
|
+
export interface ProjectEntitiesData {
|
|
314
|
+
entities: Array<{
|
|
315
|
+
iri: string;
|
|
316
|
+
size?: number;
|
|
317
|
+
}>;
|
|
318
|
+
relations: Array<{
|
|
319
|
+
sourceID: string;
|
|
320
|
+
targetID: string;
|
|
321
|
+
}>;
|
|
322
|
+
}
|
|
323
|
+
/** Core metadata for a single document (FileContent node). */
|
|
324
|
+
export interface DocumentInfo {
|
|
325
|
+
id: string;
|
|
326
|
+
contentIRI: string;
|
|
327
|
+
path: string;
|
|
328
|
+
suffix: string;
|
|
329
|
+
size: number;
|
|
330
|
+
tags: string[];
|
|
331
|
+
categories: string[];
|
|
332
|
+
subject?: string;
|
|
333
|
+
summary?: string;
|
|
334
|
+
providerId?: string;
|
|
335
|
+
}
|
|
336
|
+
/** Count + total size for a group of documents (e.g. grouped by suffix or category). */
|
|
337
|
+
export interface DocumentSummary {
|
|
338
|
+
size: number;
|
|
339
|
+
count: number;
|
|
340
|
+
}
|
|
341
|
+
/** Project-level document overview — fetched once on project init. */
|
|
342
|
+
export interface ProjectDocumentsData {
|
|
343
|
+
duplicateCount: number;
|
|
344
|
+
/** File extension → `{ size, count }` */
|
|
345
|
+
documentsBySuffix: Record<string, DocumentSummary>;
|
|
346
|
+
/** Content-category IRI → `{ size, count }` */
|
|
347
|
+
documentsByContentCategory: Record<string, DocumentSummary>;
|
|
348
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ReadonlySignal } from './signal';
|
|
2
|
+
/** Roles ordered from highest to lowest privilege. */
|
|
3
|
+
declare const ROLE_HIERARCHY: readonly ["superadmin", "admin", "syncer", "member"];
|
|
4
|
+
export type UserProjectRole = (typeof ROLE_HIERARCHY)[number];
|
|
5
|
+
export interface Privileges {
|
|
6
|
+
changeContentCategories: boolean;
|
|
7
|
+
createEntities: boolean;
|
|
8
|
+
createProvider: boolean;
|
|
9
|
+
deleteDocuments: boolean;
|
|
10
|
+
deleteUserFromProject: boolean;
|
|
11
|
+
downloadDocuments: boolean;
|
|
12
|
+
editContentCategories: boolean;
|
|
13
|
+
editPublicReposAvailableToAgent: boolean;
|
|
14
|
+
editTier: boolean;
|
|
15
|
+
inviteUserToProject: boolean;
|
|
16
|
+
renameDocuments: boolean;
|
|
17
|
+
uploadDocuments: boolean;
|
|
18
|
+
viewEntities: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Minimum role required for each privilege. */
|
|
21
|
+
export declare const REQUIRED_ROLES: Record<keyof Privileges, UserProjectRole>;
|
|
22
|
+
/**
|
|
23
|
+
* Manages role-based access control for the current user + selected project.
|
|
24
|
+
*
|
|
25
|
+
* - Call `setProjectRoles()` whenever the selected project changes.
|
|
26
|
+
* - Read `privileges` (a `ReadonlySignal<Privileges>`) for reactive access.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* cue.privileges.setProjectRoles(['admin']);
|
|
30
|
+
* const canUpload = cue.privileges.privileges.get().uploadDocuments; // true
|
|
31
|
+
*/
|
|
32
|
+
export declare class CuePrivileges {
|
|
33
|
+
private readonly _isSuperAdmin;
|
|
34
|
+
private readonly _projectRoles;
|
|
35
|
+
/**
|
|
36
|
+
* Reactive signal — current user's privileges for the selected project.
|
|
37
|
+
* Recomputes automatically when `setProjectRoles()` is called or when
|
|
38
|
+
* the `isSuperAdmin` signal changes.
|
|
39
|
+
*/
|
|
40
|
+
readonly privileges: ReadonlySignal<Privileges>;
|
|
41
|
+
constructor(_isSuperAdmin: ReadonlySignal<boolean>);
|
|
42
|
+
/**
|
|
43
|
+
* Set the user's roles for the currently selected project.
|
|
44
|
+
*
|
|
45
|
+
* Roles are expanded along the hierarchy: `admin` automatically includes
|
|
46
|
+
* `syncer` and `member`; `syncer` includes `member`. Pass an empty array
|
|
47
|
+
* to reset to the lowest privilege level.
|
|
48
|
+
*/
|
|
49
|
+
setProjectRoles(roles: UserProjectRole[]): void;
|
|
50
|
+
private _expand;
|
|
51
|
+
private _compute;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
package/lib/profile.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { UserInfo } from 'firebase/auth';
|
|
2
2
|
import { FirebaseApp } from 'firebase/app';
|
|
3
|
-
import { APIKeyDoc, APIKeyInfo, ProfileSSOAccount } from './models';
|
|
3
|
+
import { APIKeyDoc, APIKeyInfo, OrgMember, OrganizationData, ProfileSSOAccount } from './models';
|
|
4
4
|
import { CueAuth } from './auth';
|
|
5
5
|
export declare class CueProfile {
|
|
6
6
|
private readonly _auth;
|
|
7
|
-
private readonly
|
|
8
|
-
private
|
|
9
|
-
constructor(_auth: CueAuth, app: FirebaseApp, useEmulator: boolean,
|
|
7
|
+
private readonly _gatewayUrl;
|
|
8
|
+
private readonly _functions;
|
|
9
|
+
constructor(_auth: CueAuth, app: FirebaseApp, useEmulator: boolean, _gatewayUrl: string);
|
|
10
|
+
private _url;
|
|
11
|
+
private _fetch;
|
|
10
12
|
/** Whether the current user has an active API key. */
|
|
11
13
|
hasAPIKey(): Promise<boolean>;
|
|
12
14
|
/** Returns the sign-in methods registered for the current user's email. */
|
|
@@ -31,6 +33,21 @@ export declare class CueProfile {
|
|
|
31
33
|
revokeAPIKey(): Promise<void>;
|
|
32
34
|
/** Fetches the current user's existing API key. */
|
|
33
35
|
requestAPIKey(): Promise<APIKeyInfo>;
|
|
34
|
-
|
|
36
|
+
/** Returns organizations the current user is a member of. */
|
|
37
|
+
listOrganizations(): Promise<(Pick<OrganizationData, 'id' | 'name'> & {
|
|
38
|
+
isAdmin: boolean;
|
|
39
|
+
})[]>;
|
|
40
|
+
/** Returns all members of the given organisation. Caller must be an org admin or superadmin. */
|
|
41
|
+
getOrgMembers(orgId: string): Promise<OrgMember[]>;
|
|
35
42
|
private _requireUser;
|
|
43
|
+
/**
|
|
44
|
+
* Fetch display name and email for a list of user UIDs.
|
|
45
|
+
* Uses the `getUserInfo` Firebase callable function.
|
|
46
|
+
*/
|
|
47
|
+
getUserInfo(uids: string[]): Promise<Record<string, {
|
|
48
|
+
name: string;
|
|
49
|
+
email: string;
|
|
50
|
+
}>>;
|
|
51
|
+
/** Record that the current user has accepted the terms of service. */
|
|
52
|
+
acceptTerms(): Promise<void>;
|
|
36
53
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { CueApi } from './api';
|
|
2
|
+
import { CueProjectSchema } from './schema';
|
|
3
|
+
import { CueProjectEntities } from './entities';
|
|
4
|
+
import { CueProjectDocuments } from './documents';
|
|
5
|
+
import { ReadonlySignal } from './signal';
|
|
6
|
+
import { QueryCache, SearchOptions, SearchResponse, CategoryDef, RelationshipDef, EntityDetailedData, EntityRelationships, ProjectEntitiesData, DocumentInfo, ProjectDocumentsData } from './models';
|
|
7
|
+
export interface CueProjectViewOptions {
|
|
8
|
+
language: string;
|
|
9
|
+
queryCache?: QueryCache;
|
|
10
|
+
/** Override the RDF resource base URL. Defaults to `https://cue.qaecy.com/r/`. */
|
|
11
|
+
rdfBase?: string;
|
|
12
|
+
/** Graph engine type from projectSettings.graph.type (e.g. 'qlever' or 'fuseki'). */
|
|
13
|
+
graphType?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Framework-agnostic facade over `CueProjectSchema`, `CueProjectEntities`, and
|
|
17
|
+
* `CueProjectDocuments`. Exposes a flat, ergonomic API for all knowledge-graph
|
|
18
|
+
* view state needed by the portal.
|
|
19
|
+
*
|
|
20
|
+
* Create via `cue.createProjectView()` rather than constructing directly — the
|
|
21
|
+
* factory wires the active `QueryCache` automatically.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const view = cue.createProjectView('my-project', { language: 'en' });
|
|
26
|
+
* view.entityInfoMap.subscribe(map => render(map));
|
|
27
|
+
* view.requestEntityData(['uuid1', 'uuid2']);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class CueProjectView {
|
|
31
|
+
private readonly _api;
|
|
32
|
+
private readonly _projectId;
|
|
33
|
+
/** Direct access to the schema data class (available categories / relationships). */
|
|
34
|
+
readonly schema: CueProjectSchema;
|
|
35
|
+
/** Direct access to the entity data class. */
|
|
36
|
+
readonly entities: CueProjectEntities;
|
|
37
|
+
/** Direct access to the document data class. */
|
|
38
|
+
readonly documents: CueProjectDocuments;
|
|
39
|
+
/** Available content category definitions for this project. Auto-fetched on init. */
|
|
40
|
+
readonly availableContentCategories: ReadonlySignal<CategoryDef[]>;
|
|
41
|
+
/** Available entity category definitions for this project. Auto-fetched on init. */
|
|
42
|
+
readonly availableEntityCategories: ReadonlySignal<CategoryDef[]>;
|
|
43
|
+
/** Available entity relationship types. Auto-fetched on init. */
|
|
44
|
+
readonly availableEntityRelationships: ReadonlySignal<RelationshipDef[]>;
|
|
45
|
+
/** Merged per-entity detail map. Populated lazily via `requestEntityData()` etc. */
|
|
46
|
+
readonly entityInfoMap: ReadonlySignal<Record<string, EntityDetailedData>>;
|
|
47
|
+
/** Project-level entity co-occurrence graph. Fetched once on init. */
|
|
48
|
+
readonly entityGraph: ReadonlySignal<ProjectEntitiesData | undefined>;
|
|
49
|
+
/** Per-document info map. Populated lazily via `requestDocumentData()`. */
|
|
50
|
+
readonly documentInfoMap: ReadonlySignal<Record<string, DocumentInfo>>;
|
|
51
|
+
/** Project document overview (counts by suffix and category). Fetched on init. */
|
|
52
|
+
readonly projectDocumentsData: ReadonlySignal<ProjectDocumentsData | undefined>;
|
|
53
|
+
private readonly _searchResults;
|
|
54
|
+
/** The result of the most recent `search()` call. `undefined` before first search. */
|
|
55
|
+
readonly searchResults: ReadonlySignal<SearchResponse | undefined>;
|
|
56
|
+
private _destroyed;
|
|
57
|
+
constructor(_api: CueApi, _projectId: string, { language, queryCache, rdfBase, graphType }: CueProjectViewOptions);
|
|
58
|
+
/**
|
|
59
|
+
* Lazily batch-fetch core data (label + categories) for the given entity UUIDs.
|
|
60
|
+
* Already-fetched UUIDs are skipped. Populates `entityInfoMap`.
|
|
61
|
+
*/
|
|
62
|
+
requestEntityData(uuids: string[], includeMentionCount?: boolean): void;
|
|
63
|
+
/**
|
|
64
|
+
* Lazily fetch OSM location data for the given entity UUIDs.
|
|
65
|
+
* Already-fetched UUIDs are skipped. Populates `entityInfoMap` geometry fields.
|
|
66
|
+
*/
|
|
67
|
+
requestEntityLocations(uuids: string[]): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Fetch incoming and outgoing relationships for a single entity IRI.
|
|
70
|
+
* Result is stored in `entityInfoMap[uuid].relationshipData`.
|
|
71
|
+
*/
|
|
72
|
+
fetchEntityRelationships(iri: string): Promise<EntityRelationships>;
|
|
73
|
+
/**
|
|
74
|
+
* Fetch UUIDs of documents that reference the given entity IRI.
|
|
75
|
+
* Result is stored in `entityInfoMap[uuid].documentRefs`.
|
|
76
|
+
*/
|
|
77
|
+
fetchEntityDocuments(iri: string): Promise<string[]>;
|
|
78
|
+
/** Constructs the full RDF IRI for an entity UUID. */
|
|
79
|
+
entityIri(uuid: string): string;
|
|
80
|
+
/**
|
|
81
|
+
* Lazily batch-fetch document info for the given UUIDs.
|
|
82
|
+
* Already-fetched UUIDs are skipped. Populates `documentInfoMap`.
|
|
83
|
+
*/
|
|
84
|
+
requestDocumentData(uuids: string[]): void;
|
|
85
|
+
/**
|
|
86
|
+
* Run a natural-language search against the project.
|
|
87
|
+
* The result is stored in `searchResults` and replaces any previous result.
|
|
88
|
+
*/
|
|
89
|
+
search(term: string, options?: SearchOptions): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Switch the active language for schema labels and document text fields.
|
|
92
|
+
* Schema responses are cached per language (instant if previously loaded).
|
|
93
|
+
* The document info map is cleared and lazily re-populated on next access.
|
|
94
|
+
*/
|
|
95
|
+
setLanguage(lang: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Reset all entity and document state and re-fetch the project overview.
|
|
98
|
+
* Prefer creating a fresh `CueProjectView` when switching projects.
|
|
99
|
+
* Use `reset()` only when the same project's data needs to be invalidated.
|
|
100
|
+
*/
|
|
101
|
+
reset(): void;
|
|
102
|
+
/**
|
|
103
|
+
* Tear down this view instance. Clears all reactive state and blocks further
|
|
104
|
+
* updates. Call from the Angular adapter's `ngOnDestroy` or equivalent.
|
|
105
|
+
*/
|
|
106
|
+
destroy(): void;
|
|
107
|
+
}
|
package/lib/project.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { FirebaseApp } from 'firebase/app';
|
|
2
2
|
import { CueAuth } from './auth';
|
|
3
3
|
import { CreateProjectOptions, CueEndpoints, ProjectData } from './models';
|
|
4
|
+
type ProjectRole = 'admin' | 'syncer' | 'member';
|
|
4
5
|
export declare class CueProjects {
|
|
5
6
|
private readonly _auth;
|
|
6
7
|
private readonly _db;
|
|
8
|
+
private readonly _functions;
|
|
9
|
+
private readonly _gatewayUrl;
|
|
7
10
|
constructor(_auth: CueAuth, app: FirebaseApp, useEmulator?: boolean, endpoints?: CueEndpoints);
|
|
8
11
|
private _requireUser;
|
|
9
12
|
/**
|
|
@@ -12,8 +15,8 @@ export declare class CueProjects {
|
|
|
12
15
|
*/
|
|
13
16
|
createProject(options: CreateProjectOptions): Promise<ProjectData>;
|
|
14
17
|
/**
|
|
15
|
-
* List all projects where the authenticated user appears in the members
|
|
16
|
-
*
|
|
18
|
+
* List all projects where the authenticated user appears in the members array.
|
|
19
|
+
* Access is gated by Firestore rules which check membership.
|
|
17
20
|
*/
|
|
18
21
|
listProjects(): Promise<ProjectData[]>;
|
|
19
22
|
/** Fetch a single project by ID. Returns null if not found. */
|
|
@@ -23,4 +26,16 @@ export declare class CueProjects {
|
|
|
23
26
|
* document, creating it if it doesn't exist. Intended for pre-flight checks.
|
|
24
27
|
*/
|
|
25
28
|
incrementUnitsConsumed(projectId: string, units: number, userId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Invite a user to a project by email. Returns the invited user's uid and display name.
|
|
31
|
+
*/
|
|
32
|
+
inviteUserToProject(email: string, projectId: string, role: ProjectRole): Promise<{
|
|
33
|
+
uid: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** Change an existing member's role on a project. */
|
|
37
|
+
changeUserRoleOnProject(uid: string, projectId: string, role: ProjectRole): Promise<void>;
|
|
38
|
+
/** Remove a member from a project. */
|
|
39
|
+
removeUserFromProject(uid: string, projectId: string): Promise<void>;
|
|
26
40
|
}
|
|
41
|
+
export {};
|
package/lib/schema.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CueApi } from './api';
|
|
2
|
+
import { ReadonlySignal } from './signal';
|
|
3
|
+
import { CategoryDef, QueryCache, RelationshipDef } from './models';
|
|
4
|
+
/**
|
|
5
|
+
* Holds the schema for a single project: available content categories,
|
|
6
|
+
* entity categories, and entity relationship types.
|
|
7
|
+
*
|
|
8
|
+
* Data is fetched lazily on construction and cached per language so that
|
|
9
|
+
* switching back to a previously loaded language is instant.
|
|
10
|
+
*
|
|
11
|
+
* ### Reactive paradigm
|
|
12
|
+
* All three collections are exposed as `ReadonlySignal<T>`. Framework adapters
|
|
13
|
+
* (e.g. Angular) should bridge these to their own reactive primitives using
|
|
14
|
+
* `subscribe()`.
|
|
15
|
+
*
|
|
16
|
+
* ### Lifecycle
|
|
17
|
+
* One `CueProjectSchema` instance should be created per project. It is owned
|
|
18
|
+
* by the higher-level `CueProjectView` and shares the same `CueApi` instance.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const schema = new CueProjectSchema(cue.api, projectId, 'en');
|
|
23
|
+
* schema.availableContentCategories.get(); // CategoryDef[]
|
|
24
|
+
* schema.setLanguage('da'); // loads from cache or re-fetches
|
|
25
|
+
* await schema.refresh(); // force re-fetch current language
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class CueProjectSchema {
|
|
29
|
+
private readonly _api;
|
|
30
|
+
private readonly _projectId;
|
|
31
|
+
private readonly _queryCache?;
|
|
32
|
+
private readonly _graphType?;
|
|
33
|
+
private readonly _cache;
|
|
34
|
+
private readonly _language;
|
|
35
|
+
private readonly _contentCategories;
|
|
36
|
+
private readonly _entityCategories;
|
|
37
|
+
private readonly _relationships;
|
|
38
|
+
/** Currently active content categories for the selected language. */
|
|
39
|
+
readonly availableContentCategories: ReadonlySignal<CategoryDef[]>;
|
|
40
|
+
/** Currently active entity categories for the selected language. */
|
|
41
|
+
readonly availableEntityCategories: ReadonlySignal<CategoryDef[]>;
|
|
42
|
+
/** Currently active entity relationship types for the selected language. */
|
|
43
|
+
readonly availableEntityRelationships: ReadonlySignal<RelationshipDef[]>;
|
|
44
|
+
constructor(_api: CueApi, _projectId: string, language: string, _queryCache?: QueryCache | undefined, _graphType?: string | undefined);
|
|
45
|
+
/** Returns the currently active language. */
|
|
46
|
+
get language(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Switch the active language. If the data for this language has already been
|
|
49
|
+
* fetched it is applied immediately from cache; otherwise a new SPARQL fetch
|
|
50
|
+
* is triggered.
|
|
51
|
+
*/
|
|
52
|
+
setLanguage(lang: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Force a re-fetch for the current language, bypassing the cache.
|
|
55
|
+
* Useful when the triplestore data has changed.
|
|
56
|
+
*/
|
|
57
|
+
refresh(): Promise<void>;
|
|
58
|
+
private _load;
|
|
59
|
+
private _apply;
|
|
60
|
+
private _fetchCategories;
|
|
61
|
+
private _buildCategoriesQuery;
|
|
62
|
+
private _runCategoriesQuery;
|
|
63
|
+
private _fetchRelationships;
|
|
64
|
+
private _buildRelationshipsQuery;
|
|
65
|
+
private _runRelationshipsQuery;
|
|
66
|
+
}
|
package/lib/signal.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { QueryCache } from './models';
|
|
2
|
+
/** A reactive value that can be read and subscribed to. */
|
|
3
|
+
export interface ReadonlySignal<T> {
|
|
4
|
+
/** Returns the current value. */
|
|
5
|
+
get(): T;
|
|
6
|
+
/**
|
|
7
|
+
* Register a listener that is called whenever the value changes.
|
|
8
|
+
* Returns an unsubscribe function.
|
|
9
|
+
*/
|
|
10
|
+
subscribe(listener: () => void): () => void;
|
|
11
|
+
}
|
|
12
|
+
/** A writable reactive state container. */
|
|
13
|
+
export declare class CueSignal<T> implements ReadonlySignal<T> {
|
|
14
|
+
private _value;
|
|
15
|
+
private _listeners;
|
|
16
|
+
constructor(initial: T);
|
|
17
|
+
get(): T;
|
|
18
|
+
set(value: T): void;
|
|
19
|
+
subscribe(listener: () => void): () => void;
|
|
20
|
+
/** Returns a read-only view of this signal. */
|
|
21
|
+
asReadonly(): ReadonlySignal<T>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a derived read-only signal from one or more source signals.
|
|
25
|
+
* The compute function is evaluated lazily and cached until a dependency changes.
|
|
26
|
+
*
|
|
27
|
+
* @param deps Source signals to watch.
|
|
28
|
+
* @param compute Function that computes the derived value; must be pure.
|
|
29
|
+
* @returns A `ReadonlySignal` with a `destroy()` method to stop tracking deps.
|
|
30
|
+
*/
|
|
31
|
+
export declare function cueComputed<T>(deps: ReadonlySignal<unknown>[], compute: () => T): ReadonlySignal<T> & {
|
|
32
|
+
destroy(): void;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Stale-while-revalidate helper for SPARQL queries.
|
|
36
|
+
*
|
|
37
|
+
* 1. If `cache` is provided and has a stored result for `cacheKey`, calls
|
|
38
|
+
* `onData(staleData, true)` immediately (synchronously relative to the await).
|
|
39
|
+
* 2. Fires `fetchFresh()` to get current data from the triplestore.
|
|
40
|
+
* 3. Calls `onData(freshData, false)`.
|
|
41
|
+
* 4. Writes the fresh result to `cache` only if it differs from the stale
|
|
42
|
+
* result (content-addressed via `contextBasedGuid`).
|
|
43
|
+
* 5. Returns the fresh data.
|
|
44
|
+
*
|
|
45
|
+
* If no `cache` is provided the function simply fetches and calls `onData`
|
|
46
|
+
* once, transparently.
|
|
47
|
+
*
|
|
48
|
+
* @param query The SPARQL query string — also used as cache key input.
|
|
49
|
+
* @param fetchFresh Function that executes the query and returns the result.
|
|
50
|
+
* @param onData Called once with stale data (if available) and once with
|
|
51
|
+
* fresh data.
|
|
52
|
+
* @param cache Optional {@link QueryCache} implementation.
|
|
53
|
+
*/
|
|
54
|
+
export declare function staleWhileRevalidate<T>(query: string, fetchFresh: () => Promise<T>, onData: (data: T, isStale: boolean) => void, cache?: QueryCache): Promise<T>;
|