mftsccs-browser 2.2.38-beta → 2.2.40-beta
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 +1 -1
- package/dist/main.bundle.js +1 -1
- package/dist/serviceWorker.bundle.js +1 -1
- package/dist/types/DataStructures/BaseUrl.d.ts +1 -0
- package/dist/types/DataStructures/BinaryTree.d.ts +66 -2
- package/dist/types/DataStructures/ConnectionBinaryTree/ConnectionBinaryTree.d.ts +70 -2
- package/dist/types/DataStructures/Search/FreeschemaQuery.d.ts +1 -0
- package/dist/types/DataStructures/Security/SecureStorage.d.ts +14 -0
- package/dist/types/DataStructures/Security/TokenStorage.d.ts +15 -0
- package/dist/types/Database/CacheDatabase.d.ts +57 -0
- package/dist/types/Database/indexeddb.d.ts +8 -3
- package/dist/types/Services/CacheClear.d.ts +7 -0
- package/dist/types/Services/CreateBinaryTreeFromData.d.ts +2 -1
- package/dist/types/Services/GetRelation.d.ts +1 -0
- package/dist/types/Services/User/UserFromLocalStorage.d.ts +23 -0
- package/dist/types/Services/Visualizations/VisualTree.d.ts +9 -0
- package/dist/types/Widgets/WidgetCacheManager.d.ts +100 -0
- package/dist/types/WrapperFunctions/DepenedencyObserver.d.ts +1 -1
- package/dist/types/WrapperFunctions/QueryCacheManager.d.ts +98 -0
- package/dist/types/WrapperFunctions/SchemaQueryObservable.d.ts +2 -0
- package/dist/types/app.d.ts +6 -2
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ export declare class BaseUrl {
|
|
|
10
10
|
static DOCUMENTATION_WIDGET: number;
|
|
11
11
|
static isNearestCache: boolean;
|
|
12
12
|
static ACCESS_CONTROL_BASE_URL: string;
|
|
13
|
+
static isPwa: boolean;
|
|
13
14
|
static FLAGS: any;
|
|
14
15
|
static BASE_RANDOMIZER: number;
|
|
15
16
|
static setRandomizer(id: number): void;
|
|
@@ -1,13 +1,77 @@
|
|
|
1
1
|
import { Concept } from "../DataStructures/Concept";
|
|
2
2
|
import { Node } from "./Node";
|
|
3
|
+
/**
|
|
4
|
+
* BinaryTree — In-memory concept store keyed by numeric concept ID.
|
|
5
|
+
*
|
|
6
|
+
* Backed by a Map<number, Concept> for O(1) lookups, inserts, and deletes.
|
|
7
|
+
* Also maintains the BinaryCharacterTree (character-indexed) on every insert
|
|
8
|
+
* so character-based search continues to work.
|
|
9
|
+
*
|
|
10
|
+
* All public method signatures are preserved for backward compatibility.
|
|
11
|
+
* getNodeFromTree returns a { key, value } wrapper so callers that access
|
|
12
|
+
* node.value continue to work without changes.
|
|
13
|
+
*/
|
|
3
14
|
export declare class BinaryTree {
|
|
15
|
+
/** Sentinel root — non-null when the map has data, null when empty. */
|
|
4
16
|
static root: Node | null;
|
|
5
|
-
|
|
17
|
+
/** Primary data store: concept ID → Concept object */
|
|
18
|
+
private static conceptMap;
|
|
19
|
+
/**
|
|
20
|
+
* Low-level add — stores the node's key/value in the Map.
|
|
21
|
+
* Kept for API compatibility (called internally by addConceptToTree).
|
|
22
|
+
* @param node - Node with numeric key and Concept value
|
|
23
|
+
*/
|
|
24
|
+
static addNodeToTree(node: Node): void;
|
|
25
|
+
/**
|
|
26
|
+
* Polls until IdentifierFlags.isDataLoaded is true (max 25 seconds).
|
|
27
|
+
* Used by callers that need to wait for the initial IndexedDB load to finish.
|
|
28
|
+
*/
|
|
6
29
|
static waitForDataToLoad(): Promise<unknown>;
|
|
30
|
+
/** Recursive polling helper for waitForDataToLoad */
|
|
7
31
|
static checkFlag(resolve: any): any;
|
|
32
|
+
/**
|
|
33
|
+
* Adds a concept to both the ID map and the character tree.
|
|
34
|
+
*
|
|
35
|
+
* The character tree (BinaryCharacterTree) is still an AVL tree because
|
|
36
|
+
* it supports character-based search which is out of scope for this refactor.
|
|
37
|
+
*
|
|
38
|
+
* @param concept - The Concept to store
|
|
39
|
+
*/
|
|
8
40
|
static addConceptToTree(concept: Concept): void;
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves a concept by ID from the Map.
|
|
43
|
+
*
|
|
44
|
+
* Returns a { key, value } wrapper matching the Node shape that callers expect.
|
|
45
|
+
* Callers access the returned object's .value property to get the Concept.
|
|
46
|
+
*
|
|
47
|
+
* @param id - The concept ID to look up
|
|
48
|
+
* @returns Node-like wrapper with .value = Concept, or null if not found
|
|
49
|
+
*/
|
|
9
50
|
static getNodeFromTree(id: number): Promise<Node | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Removes a concept by ID. Dispatches an event before deletion
|
|
53
|
+
* so listeners (e.g. UI components) can react to the removal.
|
|
54
|
+
*
|
|
55
|
+
* @param id - The concept ID to remove
|
|
56
|
+
*/
|
|
10
57
|
static removeNodeFromTree(id: number): Promise<void>;
|
|
11
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Bulk concept retrieval by ID list.
|
|
60
|
+
*
|
|
61
|
+
* For each ID found in the Map, pushes the Concept into conceptArray
|
|
62
|
+
* and removes the ID from the ids array. IDs remaining in the array
|
|
63
|
+
* after this call are "not found" and will be fetched from the backend.
|
|
64
|
+
*
|
|
65
|
+
* Performance: O(k) where k = ids.length (was O(N) full tree traversal).
|
|
66
|
+
*
|
|
67
|
+
* @param ids - Array of concept IDs to look up (mutated: found IDs are spliced out)
|
|
68
|
+
* @param conceptArray - Output array (mutated: found Concepts are pushed)
|
|
69
|
+
* @param remainingIds - Not used directly but kept for API compatibility
|
|
70
|
+
*/
|
|
71
|
+
static getConceptListFromIds(ids: number[], conceptArray: Concept[], remainingIds: any): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the total number of concepts stored.
|
|
74
|
+
* @returns Number of concepts in the Map
|
|
75
|
+
*/
|
|
12
76
|
static countNumberOfNodes(): number;
|
|
13
77
|
}
|
|
@@ -1,13 +1,81 @@
|
|
|
1
1
|
import { Connection } from "../../DataStructures/Connection";
|
|
2
2
|
import { ConnectionNode } from "./ConnectionNode";
|
|
3
|
+
/**
|
|
4
|
+
* ConnectionBinaryTree — In-memory connection store keyed by numeric connection ID.
|
|
5
|
+
*
|
|
6
|
+
* Backed by a Map<number, Connection> for O(1) lookups, inserts, and deletes.
|
|
7
|
+
* The secondary index trees (ConnectionTypeTree, ConnectionOfTheTree) are
|
|
8
|
+
* managed separately by ConnectionData and remain unchanged.
|
|
9
|
+
*
|
|
10
|
+
* All public method signatures are preserved for backward compatibility.
|
|
11
|
+
* getNodeFromTree returns a { key, value } wrapper so callers that access
|
|
12
|
+
* node.value continue to work without changes.
|
|
13
|
+
*/
|
|
3
14
|
export declare class ConnectionBinaryTree {
|
|
15
|
+
/** Sentinel root — non-null when the map has data, null when empty. */
|
|
4
16
|
static connectionroot: ConnectionNode | null;
|
|
5
|
-
|
|
17
|
+
/** Primary data store: connection ID → Connection object */
|
|
18
|
+
private static connectionMap;
|
|
19
|
+
/**
|
|
20
|
+
* Low-level add — stores the node's key/value in the Map.
|
|
21
|
+
* Kept for API compatibility.
|
|
22
|
+
* @param node - ConnectionNode with numeric key and Connection value
|
|
23
|
+
*/
|
|
24
|
+
static addNodeToTree(node: ConnectionNode): void;
|
|
25
|
+
/**
|
|
26
|
+
* Adds a connection to the Map and dispatches an event for the
|
|
27
|
+
* owning concept so UI listeners can react.
|
|
28
|
+
*
|
|
29
|
+
* The dispatchIdEvent(ofTheConceptId) was previously fired inside
|
|
30
|
+
* ConnectionNode.addNode when the node was placed into a null slot.
|
|
31
|
+
* We only fire it for new connections (not overwrites) to preserve
|
|
32
|
+
* the original behavior.
|
|
33
|
+
*
|
|
34
|
+
* @param connection - The Connection to store
|
|
35
|
+
*/
|
|
6
36
|
static addConnectionToTree(connection: Connection): void;
|
|
7
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Returns the total number of connections stored.
|
|
39
|
+
* @returns Number of connections in the Map
|
|
40
|
+
*/
|
|
41
|
+
static traverse(): number;
|
|
42
|
+
/**
|
|
43
|
+
* Polls until IdentifierFlags.isConnectionLoaded is true (max 25 seconds).
|
|
44
|
+
* Used by callers that need to wait for the initial IndexedDB load to finish.
|
|
45
|
+
*/
|
|
8
46
|
static waitForDataToLoad(): Promise<unknown>;
|
|
47
|
+
/** Recursive polling helper for waitForDataToLoad */
|
|
9
48
|
static checkFlag(resolve: any): any;
|
|
49
|
+
/**
|
|
50
|
+
* Removes a connection by ID. Dispatches an event for the owning concept
|
|
51
|
+
* before deletion so listeners can react to the removal.
|
|
52
|
+
*
|
|
53
|
+
* @param id - The connection ID to remove
|
|
54
|
+
*/
|
|
10
55
|
static removeNodeFromTree(id: number): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves a connection by ID from the Map.
|
|
58
|
+
*
|
|
59
|
+
* Returns a { key, value } wrapper matching the ConnectionNode shape.
|
|
60
|
+
* Also increments the connection's count field for access tracking
|
|
61
|
+
* (preserving the original ConnectionNode.getFromNode behavior).
|
|
62
|
+
*
|
|
63
|
+
* @param id - The connection ID to look up
|
|
64
|
+
* @returns ConnectionNode-like wrapper with .value = Connection, or null/undefined
|
|
65
|
+
*/
|
|
11
66
|
static getNodeFromTree(id: number): Promise<ConnectionNode | null | undefined>;
|
|
67
|
+
/**
|
|
68
|
+
* Bulk connection retrieval by ID list.
|
|
69
|
+
*
|
|
70
|
+
* For each ID found in the Map, pushes the Connection into connectionArray
|
|
71
|
+
* and removes the ID from the ids array. IDs remaining after this call
|
|
72
|
+
* are "not found" and will be fetched from the backend.
|
|
73
|
+
*
|
|
74
|
+
* Performance: O(k) where k = ids.length (was O(N) full tree traversal).
|
|
75
|
+
*
|
|
76
|
+
* @param ids - Array of connection IDs to look up (mutated: found IDs are spliced out)
|
|
77
|
+
* @param connectionArray - Output array (mutated: found Connections are pushed)
|
|
78
|
+
* @param remainingIds - Not used directly but kept for API compatibility
|
|
79
|
+
*/
|
|
12
80
|
static getConnectionListFromIds(ids: number[], connectionArray: Connection[], remainingIds: any): Promise<void>;
|
|
13
81
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypts and stores a profile object in sessionStorage.
|
|
3
|
+
* Uses AES-GCM with a browser-bound derived key so the ciphertext
|
|
4
|
+
* is not portable to other origins or browsers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function saveProfile(profile: Record<string, any>): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Decrypts and returns the stored profile, or null if absent/tampered.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadProfile(): Promise<Record<string, any> | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Removes the stored profile.
|
|
13
|
+
*/
|
|
14
|
+
export declare function clearProfile(): void;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
export declare class TokenStorage {
|
|
2
2
|
static BearerAccessToken: string;
|
|
3
|
+
static refreshToken: string;
|
|
3
4
|
static sessionId: number;
|
|
4
5
|
static setSession(sessionId: any): void;
|
|
6
|
+
/**
|
|
7
|
+
* Stores user profile securely (encrypted in sessionStorage)
|
|
8
|
+
* and keeps the token in memory for API calls.
|
|
9
|
+
*/
|
|
10
|
+
static saveUserProfile(signinResponse: any): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Restores profile metadata from encrypted sessionStorage.
|
|
13
|
+
* Tokens are NOT persisted — they must come from a fresh login or refresh.
|
|
14
|
+
*/
|
|
15
|
+
static restoreProfile(): Promise<Record<string, any> | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Clears all stored credentials and profile data.
|
|
18
|
+
*/
|
|
19
|
+
static logout(): void;
|
|
5
20
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Names of the four object stores */
|
|
2
|
+
declare const STORE_WIDGET = "widgetCache";
|
|
3
|
+
declare const STORE_LATEST = "latestWidgetCache";
|
|
4
|
+
declare const STORE_RECENT = "recentWidgetCache";
|
|
5
|
+
declare const STORE_QUERY = "queryCache";
|
|
6
|
+
/**
|
|
7
|
+
* Opens (or returns the already-opened) cache database.
|
|
8
|
+
*
|
|
9
|
+
* The database name includes the API base URL and application identifier so that
|
|
10
|
+
* different environments/applications each get their own isolated cache store,
|
|
11
|
+
* matching the naming convention used by the main database in indexeddb.ts.
|
|
12
|
+
*
|
|
13
|
+
* @returns Promise resolving to the IDBDatabase instance
|
|
14
|
+
*/
|
|
15
|
+
export declare function openCacheDatabase(): Promise<IDBDatabase>;
|
|
16
|
+
/**
|
|
17
|
+
* Retrieves a single record from the specified store by key.
|
|
18
|
+
*
|
|
19
|
+
* @param storeName - The object store to read from
|
|
20
|
+
* @param key - The key to look up (number for widget stores, string for queryCache)
|
|
21
|
+
* @returns The stored value, or null if not found
|
|
22
|
+
*/
|
|
23
|
+
export declare function cacheGet(storeName: string, key: IDBValidKey): Promise<any | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Writes a record to the specified store (insert or update).
|
|
26
|
+
*
|
|
27
|
+
* For stores with in-line keys (widget stores), the key is read from the object's
|
|
28
|
+
* "id" field. For the queryCache store (out-of-line keys), pass the key explicitly.
|
|
29
|
+
*
|
|
30
|
+
* @param storeName - The object store to write to
|
|
31
|
+
* @param value - The value to store
|
|
32
|
+
* @param key - Optional explicit key (required for queryCache which has no keyPath)
|
|
33
|
+
*/
|
|
34
|
+
export declare function cachePut(storeName: string, value: any, key?: IDBValidKey): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Deletes a single record from the specified store by key.
|
|
37
|
+
*
|
|
38
|
+
* @param storeName - The object store to delete from
|
|
39
|
+
* @param key - The key of the record to delete
|
|
40
|
+
*/
|
|
41
|
+
export declare function cacheDelete(storeName: string, key: IDBValidKey): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Clears ALL records from the specified store.
|
|
44
|
+
*
|
|
45
|
+
* @param storeName - The object store to clear
|
|
46
|
+
*/
|
|
47
|
+
export declare function cacheClear(storeName: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Retrieves ALL records from the specified store.
|
|
50
|
+
* Used during init() to load persisted cache data into memory.
|
|
51
|
+
*
|
|
52
|
+
* @param storeName - The object store to read from
|
|
53
|
+
* @returns Array of all stored records
|
|
54
|
+
*/
|
|
55
|
+
export declare function cacheGetAll(storeName: string): Promise<any[]>;
|
|
56
|
+
/** Export store name constants so callers don't need magic strings */
|
|
57
|
+
export { STORE_WIDGET, STORE_LATEST, STORE_RECENT, STORE_QUERY };
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { SettingData } from "../DataStructures/SettingData";
|
|
2
2
|
/**
|
|
3
|
-
* This class will help us store the indexdb
|
|
3
|
+
* This class will help us store the indexdb reference in memory and not go back to index db.
|
|
4
4
|
*/
|
|
5
5
|
export declare class IndexDb {
|
|
6
6
|
static db: IDBDatabase;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
+
* Opens the FreeSchema IndexedDB database (or returns the cached instance).
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* - Returns the cached db reference immediately if already open.
|
|
12
|
+
* - Deduplicates concurrent calls — only one indexedDB.open() runs at a time.
|
|
13
|
+
* - On error, rejects without deleting the database to avoid data loss.
|
|
14
|
+
*
|
|
15
|
+
* @param databaseName kept for backward compatibility (not used in db name)
|
|
16
|
+
* @returns a promise resolving to the IDBDatabase instance
|
|
12
17
|
*/
|
|
13
18
|
export declare function openDatabase(databaseName: string): Promise<IDBDatabase>;
|
|
14
19
|
/**
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clears all application caches (both in-memory and IndexedDB).
|
|
3
|
+
*
|
|
4
|
+
* Call this on user logout or when you need to force-refresh all cached data.
|
|
5
|
+
* Clears widget caches (standard, latest, recent) and query caches.
|
|
6
|
+
*/
|
|
7
|
+
export declare function clearAllCaches(): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* This function builds up the binary tree on startup from the indexdb
|
|
2
|
+
* This function builds up the binary tree on startup from the indexdb.
|
|
3
|
+
* Processes records in chunks to avoid blocking the main thread.
|
|
3
4
|
*/
|
|
4
5
|
export default function CreateConceptBinaryTreeFromIndexDb(): Promise<void>;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export declare function GetRelation(id: number, relation: string, inpage?: number, page?: number, reverse?: boolean): Promise<any>;
|
|
2
|
+
export declare function GetRelationNew(id: number, relation: string, inpage?: number, page?: number, reverse?: boolean): Promise<void>;
|
|
2
3
|
export declare function GetRelationRaw(id: number, relation: string, inpage?: number, page?: number, reverse?: boolean): Promise<any>;
|
|
@@ -1,6 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous — reads from in-memory token + falls back to plain-text
|
|
3
|
+
* localStorage("profile") for backward compatibility.
|
|
4
|
+
* @deprecated Migrate callers to getUserDetailsAsync() which uses encrypted storage.
|
|
5
|
+
*/
|
|
1
6
|
export declare function getUserDetails(): {
|
|
2
7
|
entity: number;
|
|
3
8
|
userConcept: number;
|
|
4
9
|
userId: number;
|
|
5
10
|
token: string;
|
|
6
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Async version — prefers encrypted sessionStorage, falls back to
|
|
14
|
+
* plain-text localStorage for backward compatibility.
|
|
15
|
+
* This is the recommended replacement for getUserDetails().
|
|
16
|
+
*/
|
|
17
|
+
export declare function getUserDetailsAsync(): Promise<{
|
|
18
|
+
entity: any;
|
|
19
|
+
userConcept: any;
|
|
20
|
+
userId: any;
|
|
21
|
+
token: string;
|
|
22
|
+
roles: any;
|
|
23
|
+
} | {
|
|
24
|
+
entity: any;
|
|
25
|
+
userConcept: any;
|
|
26
|
+
userId: any;
|
|
27
|
+
token: any;
|
|
28
|
+
roles: never[];
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Concept, Connection, LocalTransaction } from "../../app";
|
|
2
|
+
export declare class VisualTree {
|
|
3
|
+
static concepts: Concept[];
|
|
4
|
+
static connections: Connection[];
|
|
5
|
+
static transactions: LocalTransaction[];
|
|
6
|
+
static setTransaction(transaction: LocalTransaction): void;
|
|
7
|
+
static renderVisualTree(): void;
|
|
8
|
+
static getLocalConcepts(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WidgetCacheManager — In-memory cache with IndexedDB persistence for widget data.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* - **Reads** are synchronous from in-memory Maps (fastest possible lookup).
|
|
6
|
+
* - **Writes** update the in-memory Map immediately, then persist to IndexedDB
|
|
7
|
+
* in the background (fire-and-forget) so data survives page reloads.
|
|
8
|
+
* - **On startup**, `init()` loads all persisted data from IndexedDB into the Maps.
|
|
9
|
+
*
|
|
10
|
+
* This gives us the speed of in-memory access (no async overhead, no JSON.parse)
|
|
11
|
+
* with the durability of IndexedDB (no 5 MB limit, survives reloads).
|
|
12
|
+
*
|
|
13
|
+
* Three separate caches are maintained:
|
|
14
|
+
* - **widgetMap** — standard widget data keyed by widget ID
|
|
15
|
+
* - **latestMap** — latest published version keyed by origin ID
|
|
16
|
+
* - **recentMap** — recent published version keyed by origin ID
|
|
17
|
+
*/
|
|
18
|
+
export declare class WidgetCacheManager {
|
|
19
|
+
/** In-memory cache for standard widget data */
|
|
20
|
+
private static widgetMap;
|
|
21
|
+
/** In-memory cache for latest-version widget data */
|
|
22
|
+
private static latestMap;
|
|
23
|
+
/** In-memory cache for recent-version widget data */
|
|
24
|
+
private static recentMap;
|
|
25
|
+
/**
|
|
26
|
+
* Loads all persisted widget cache data from IndexedDB into memory.
|
|
27
|
+
* Call this once during app initialization (e.g. in init() or initConceptConnection()).
|
|
28
|
+
* Safe to call multiple times — just overwrites the Maps.
|
|
29
|
+
*/
|
|
30
|
+
static init(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves cached widget data by widget ID (synchronous, from memory).
|
|
33
|
+
* @param id - The widget ID to look up
|
|
34
|
+
* @returns The cached data object, or null if not cached
|
|
35
|
+
*/
|
|
36
|
+
static getWidget(id: number): any | null;
|
|
37
|
+
/**
|
|
38
|
+
* Stores widget data in memory and persists to IndexedDB in the background.
|
|
39
|
+
* Skips if data is identical to what's already cached (dedup guard).
|
|
40
|
+
* @param id - The widget ID
|
|
41
|
+
* @param data - The widget data object to cache
|
|
42
|
+
*/
|
|
43
|
+
static setWidget(id: number, data: any): void;
|
|
44
|
+
/**
|
|
45
|
+
* Removes a single widget entry from memory and IndexedDB.
|
|
46
|
+
* @param id - The widget ID to remove
|
|
47
|
+
*/
|
|
48
|
+
static removeWidget(id: number): void;
|
|
49
|
+
/**
|
|
50
|
+
* Retrieves cached latest-version widget data (synchronous, from memory).
|
|
51
|
+
* @param id - The origin widget ID
|
|
52
|
+
* @returns The cached data object, or null if not cached
|
|
53
|
+
*/
|
|
54
|
+
static getLatest(id: number): any | null;
|
|
55
|
+
/**
|
|
56
|
+
* Stores latest-version widget data in memory and persists to IndexedDB.
|
|
57
|
+
* Skips if data is identical to what's already cached.
|
|
58
|
+
* @param id - The origin widget ID
|
|
59
|
+
* @param data - The latest widget data to cache
|
|
60
|
+
*/
|
|
61
|
+
static setLatest(id: number, data: any): void;
|
|
62
|
+
/**
|
|
63
|
+
* Removes a single latest-version entry from memory and IndexedDB.
|
|
64
|
+
* @param id - The origin widget ID to remove
|
|
65
|
+
*/
|
|
66
|
+
static removeLatest(id: number): void;
|
|
67
|
+
/**
|
|
68
|
+
* Retrieves cached recent-version widget data (synchronous, from memory).
|
|
69
|
+
* @param id - The origin widget ID
|
|
70
|
+
* @returns The cached data object, or null if not cached
|
|
71
|
+
*/
|
|
72
|
+
static getRecent(id: number): any | null;
|
|
73
|
+
/**
|
|
74
|
+
* Stores recent-version widget data in memory and persists to IndexedDB.
|
|
75
|
+
* Skips if data is identical to what's already cached.
|
|
76
|
+
* @param id - The origin widget ID
|
|
77
|
+
* @param data - The recent widget data to cache
|
|
78
|
+
*/
|
|
79
|
+
static setRecent(id: number, data: any): void;
|
|
80
|
+
/**
|
|
81
|
+
* Removes a single recent-version entry from memory and IndexedDB.
|
|
82
|
+
* @param id - The origin widget ID to remove
|
|
83
|
+
*/
|
|
84
|
+
static removeRecent(id: number): void;
|
|
85
|
+
/**
|
|
86
|
+
* Clears all three widget caches from both memory and IndexedDB.
|
|
87
|
+
* Useful for cache invalidation on logout or environment switch.
|
|
88
|
+
*/
|
|
89
|
+
static clearAll(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Checks if the new data is identical to what's already in the Map.
|
|
92
|
+
* Prevents unnecessary IndexedDB writes when data hasn't changed.
|
|
93
|
+
*
|
|
94
|
+
* @param map - The in-memory Map to check against
|
|
95
|
+
* @param id - The key to check
|
|
96
|
+
* @param data - The new data to compare
|
|
97
|
+
* @returns true if data is a duplicate (should be skipped)
|
|
98
|
+
*/
|
|
99
|
+
private static _isDuplicate;
|
|
100
|
+
}
|
|
@@ -76,7 +76,7 @@ export declare class DependencyObserver {
|
|
|
76
76
|
* @param errorCallback - Optional function to call when errors occur
|
|
77
77
|
* @returns Result of calling the callback with current data
|
|
78
78
|
*/
|
|
79
|
-
subscribe(callback: any, errorCallback?: (error: Error) => void):
|
|
79
|
+
subscribe(callback: any, errorCallback?: (error: Error) => void): any;
|
|
80
80
|
/**
|
|
81
81
|
* Executes the observable once without subscribing to updates.
|
|
82
82
|
* @returns The executed data
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QueryCacheManager — In-memory cache with IndexedDB persistence for freeschema query results.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* - **Reads** (`get`) are synchronous from an in-memory Map — no async overhead.
|
|
6
|
+
* - **Writes** (`set`) update the Map immediately, then persist to IndexedDB
|
|
7
|
+
* in the background (fire-and-forget). Also dispatches a CustomEvent so
|
|
8
|
+
* active subscribers (SchemaQueryObservable) can re-render with fresh data.
|
|
9
|
+
* - **On startup**, `init()` loads all persisted query results from IndexedDB
|
|
10
|
+
* into the Map so cached data is available from the very first read.
|
|
11
|
+
*
|
|
12
|
+
* This gives us the speed of in-memory access with the durability of IndexedDB
|
|
13
|
+
* (no 5 MB localStorage limit, survives page reloads).
|
|
14
|
+
*
|
|
15
|
+
* The stale-while-revalidate flow in FreeschemaQueryApi:
|
|
16
|
+
* 1. `get(hash)` returns cached data synchronously from memory
|
|
17
|
+
* 2. Caller returns cached data to UI immediately
|
|
18
|
+
* 3. Background fetch gets fresh data from API
|
|
19
|
+
* 4. `set(hash, fresh)` updates memory + IndexedDB + fires CustomEvent
|
|
20
|
+
* 5. Subscribers pick up the event and re-render with fresh data
|
|
21
|
+
*/
|
|
22
|
+
export declare class QueryCacheManager {
|
|
23
|
+
/** Prefix for CustomEvent names — ensures no collision with other window events */
|
|
24
|
+
private static prefix;
|
|
25
|
+
/** In-memory cache: hash → query result data */
|
|
26
|
+
private static cacheMap;
|
|
27
|
+
/**
|
|
28
|
+
* Loads all persisted query cache data from IndexedDB into memory.
|
|
29
|
+
* Call this once during app initialization.
|
|
30
|
+
* Safe to call multiple times — just overwrites the Map.
|
|
31
|
+
*/
|
|
32
|
+
static init(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Computes a SHA-256 hash of a query object for use as a cache key.
|
|
35
|
+
*
|
|
36
|
+
* The query is canonicalized by recursively sorting all object keys before
|
|
37
|
+
* hashing, so that `{a:1, b:2}` and `{b:2, a:1}` produce the same hash.
|
|
38
|
+
*
|
|
39
|
+
* @param query - The freeschema query object to hash
|
|
40
|
+
* @returns Hex-encoded SHA-256 hash string
|
|
41
|
+
*/
|
|
42
|
+
static getHash(query: any): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves cached query results by hash key (synchronous, from memory).
|
|
45
|
+
*
|
|
46
|
+
* @param hash - The SHA-256 hash of the query (from getHash)
|
|
47
|
+
* @returns The cached result data, or null if not found
|
|
48
|
+
*/
|
|
49
|
+
static get(hash: string): any | null;
|
|
50
|
+
/**
|
|
51
|
+
* Stores query results in memory, persists to IndexedDB, and notifies subscribers.
|
|
52
|
+
*
|
|
53
|
+
* Includes a deduplication guard: if the new data serializes identically to
|
|
54
|
+
* what's already in memory, the write and event dispatch are both skipped.
|
|
55
|
+
* This prevents infinite revalidation loops (set → event → fetch → set → ...).
|
|
56
|
+
*
|
|
57
|
+
* @param hash - The SHA-256 hash key for this query
|
|
58
|
+
* @param data - The query result data to cache
|
|
59
|
+
*/
|
|
60
|
+
static set(hash: string, data: any): void;
|
|
61
|
+
/**
|
|
62
|
+
* Subscribes to cache updates for a specific query hash.
|
|
63
|
+
*
|
|
64
|
+
* Uses window CustomEvents (synchronous, in-memory) so subscribers are
|
|
65
|
+
* notified immediately when `set()` is called — no IndexedDB polling needed.
|
|
66
|
+
*
|
|
67
|
+
* @param hash - The query hash to listen for updates on
|
|
68
|
+
* @param callback - Function called with the fresh data when cache is updated
|
|
69
|
+
* @returns An unsubscribe function — call it to stop listening
|
|
70
|
+
*/
|
|
71
|
+
static subscribe(hash: string, callback: (data: any) => void): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* Removes a single cached query result from memory and IndexedDB.
|
|
74
|
+
* @param hash - The query hash key to remove
|
|
75
|
+
*/
|
|
76
|
+
static remove(hash: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Clears all cached query results from memory and IndexedDB.
|
|
79
|
+
* Useful for cache invalidation on logout or environment switch.
|
|
80
|
+
*/
|
|
81
|
+
static clearAll(): void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Computes a deterministic SHA-256 hash of any JSON-serializable object.
|
|
85
|
+
*
|
|
86
|
+
* To ensure that semantically identical objects always produce the same hash
|
|
87
|
+
* regardless of property insertion order, all object keys are recursively sorted
|
|
88
|
+
* before serialization. Arrays maintain their order (only object keys are sorted).
|
|
89
|
+
*
|
|
90
|
+
* @param obj - Any JSON-serializable value (object, array, string, number, etc.)
|
|
91
|
+
* @returns Hex-encoded SHA-256 hash string (64 characters)
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* // These produce the same hash:
|
|
95
|
+
* await hashJsonObject({ a: 1, b: 2 });
|
|
96
|
+
* await hashJsonObject({ b: 2, a: 1 });
|
|
97
|
+
*/
|
|
98
|
+
export declare function hashJsonObject(obj: any): Promise<string>;
|
|
@@ -13,6 +13,8 @@ export declare class SearchLinkMultipleAllObservable extends DependencyObserver
|
|
|
13
13
|
order: string;
|
|
14
14
|
/** Total count of matching results */
|
|
15
15
|
totalCount: number;
|
|
16
|
+
/** Cleanup function for cache subscription */
|
|
17
|
+
private unsubscribeCache;
|
|
16
18
|
/**
|
|
17
19
|
* Creates a new schema query observable.
|
|
18
20
|
* @param query - FreeschemaQuery object with search parameters
|
package/dist/types/app.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { GetCompositionWithCache, GetCompositionWithDataIdWithCache, GetComposit
|
|
|
43
43
|
export { CreateSession } from './Api/Session/CreateSession';
|
|
44
44
|
export { CreateSessionVisit } from './Api/Session/CreateSessionVisit';
|
|
45
45
|
export {} from './Api/GetConceptByCharacterAndType';
|
|
46
|
-
export { GetRelation, GetRelationRaw } from './Services/GetRelation';
|
|
46
|
+
export { GetRelation, GetRelationRaw, GetRelationNew } from './Services/GetRelation';
|
|
47
47
|
export { recursiveFetchNew } from './Services/Composition/BuildComposition';
|
|
48
48
|
export { CreateTheCompositionWithCache } from './Services/Composition/CreateCompositionCache';
|
|
49
49
|
export { CreateDefaultLConcept } from './Services/Local/CreateDefaultLConcept';
|
|
@@ -123,8 +123,10 @@ export { DeleteUser } from './Services/DeleteConcept';
|
|
|
123
123
|
export { AccessTracker } from './AccessTracker/accessTracker';
|
|
124
124
|
export { CreateConnectionBetweenEntityLocal } from './Services/CreateConnection/CreateConnectionEntity';
|
|
125
125
|
export { BuildWidgetFromId } from './Widgets/WidgetBuild';
|
|
126
|
+
export { clearAllCaches } from './Services/CacheClear';
|
|
126
127
|
export { removeAllChildren } from './Services/Common/RemoveAllChild';
|
|
127
|
-
export { getUserDetails } from './Services/User/UserFromLocalStorage';
|
|
128
|
+
export { getUserDetails, getUserDetailsAsync } from './Services/User/UserFromLocalStorage';
|
|
129
|
+
export { TokenStorage } from './DataStructures/Security/TokenStorage';
|
|
128
130
|
export { CountInfo } from './DataStructures/Count/CountInfo';
|
|
129
131
|
export { LogEvent } from './Services/Logs/LogEvent';
|
|
130
132
|
export { Selector } from './Api/Prototype/Selector';
|
|
@@ -345,8 +347,10 @@ declare function init(url?: string, aiurl?: string, accessToken?: string, nodeUr
|
|
|
345
347
|
logPackage?: boolean;
|
|
346
348
|
accessTracker?: boolean;
|
|
347
349
|
isTest?: boolean;
|
|
350
|
+
accessControl?: boolean;
|
|
348
351
|
}, parameters?: {
|
|
349
352
|
logserver?: string;
|
|
353
|
+
isPwa?: boolean;
|
|
350
354
|
}, accessControlUrl?: string): Promise<true | undefined>;
|
|
351
355
|
/**
|
|
352
356
|
* Method to send message to the service worker from main thread
|