mftsccs-browser 2.2.39-beta → 2.2.41-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/bundle-report.html +39 -0
- package/dist/main.bundle.js +1 -1
- package/dist/main.bundle.js.map +1 -0
- package/dist/serviceWorker.bundle.js +1 -1
- package/dist/serviceWorker.bundle.js.map +1 -0
- package/dist/types/Api/GetConnections/GetConnectionsByTypesApi.d.ts +3 -0
- package/dist/types/DataStructures/BinaryTree.d.ts +66 -2
- package/dist/types/DataStructures/ConnectionBinaryTree/ConnectionBinaryTree.d.ts +70 -2
- package/dist/types/DataStructures/ConnectionByType/GetConnectionsByType.d.ts +4 -0
- package/dist/types/DataStructures/PwaStorageManager.d.ts +25 -0
- 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 +18 -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/Delete/DeleteConnectionByIdLocal.d.ts +1 -0
- package/dist/types/Services/Search/DataFormat.d.ts +23 -0
- package/dist/types/Services/User/UserFromLocalStorage.d.ts +5 -6
- package/dist/types/Services/automated/auotmated-update.d.ts +2 -0
- package/dist/types/Widgets/BuilderStatefulWidget.d.ts +1 -1
- package/dist/types/Widgets/WidgetCacheManager.d.ts +90 -7
- package/dist/types/WrapperFunctions/DepenedencyObserver.d.ts +1 -1
- package/dist/types/WrapperFunctions/QueryCacheManager.d.ts +88 -0
- package/dist/types/app.d.ts +3 -0
- package/package.json +1 -2
|
@@ -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,25 @@
|
|
|
1
|
+
import { Concept } from "./Concept";
|
|
2
|
+
import { Connection } from "./Connection";
|
|
3
|
+
/**
|
|
4
|
+
* Manages localStorage persistence for PWA mode.
|
|
5
|
+
*
|
|
6
|
+
* Strategy:
|
|
7
|
+
* - Reads: always from memory (BinaryTree), never from localStorage at runtime
|
|
8
|
+
* - Writes: batched and deferred to avoid blocking the main thread
|
|
9
|
+
* - Startup: bulk load from localStorage into memory once
|
|
10
|
+
*/
|
|
11
|
+
export declare class PwaStorageManager {
|
|
12
|
+
private static CONCEPT_PREFIX;
|
|
13
|
+
private static CONNECTION_PREFIX;
|
|
14
|
+
private static writeQueue;
|
|
15
|
+
private static deleteQueue;
|
|
16
|
+
private static flushTimer;
|
|
17
|
+
private static scheduleFlush;
|
|
18
|
+
static saveConcept(concept: Concept): void;
|
|
19
|
+
static saveConnection(connection: Connection): void;
|
|
20
|
+
static removeConcept(id: number): void;
|
|
21
|
+
static removeConnection(id: number): void;
|
|
22
|
+
static loadAllConcepts(): Concept[];
|
|
23
|
+
static loadAllConnections(): Connection[];
|
|
24
|
+
static clearAll(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypts and stores a profile object in localStorage.
|
|
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,23 @@
|
|
|
1
1
|
export declare class TokenStorage {
|
|
2
2
|
static BearerAccessToken: string;
|
|
3
|
+
static refreshToken: string;
|
|
3
4
|
static sessionId: number;
|
|
5
|
+
/** In-memory cache of the decrypted profile — populated by saveUserProfile or hydrateProfile */
|
|
6
|
+
static profileCache: Record<string, any> | null;
|
|
4
7
|
static setSession(sessionId: any): void;
|
|
8
|
+
/**
|
|
9
|
+
* Stores user profile securely (encrypted in sessionStorage)
|
|
10
|
+
* and keeps the token in memory for API calls.
|
|
11
|
+
* Also populates profileCache so getUserDetails() works synchronously.
|
|
12
|
+
*/
|
|
13
|
+
static saveUserProfile(signinResponse: any): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Call once at app startup (e.g. in init()) to decrypt the stored profile
|
|
16
|
+
* into memory so that getUserDetails() can read it synchronously.
|
|
17
|
+
*/
|
|
18
|
+
static hydrateProfile(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Clears all stored credentials and profile data.
|
|
21
|
+
*/
|
|
22
|
+
static logout(): void;
|
|
5
23
|
}
|
|
@@ -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>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function DeleteConnectionByIdLocal(toDeleteIds: number[]): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Connection } from "../../app";
|
|
2
|
+
/**
|
|
3
|
+
* ## Format Just-Id ##
|
|
4
|
+
* this function takes in connections and creates a single level objects so that all the data are added to its object/ array.
|
|
5
|
+
* This is then passed on further for stiching.
|
|
6
|
+
* @param connections
|
|
7
|
+
* @param compositionData
|
|
8
|
+
* @param reverse
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export declare function FormatFunctionDataForClean(connections: Connection[], compositionData: any[], reverse?: number[]): Promise<any[]>;
|
|
12
|
+
/**
|
|
13
|
+
* ############ Format is Just Id and is used for list. ############
|
|
14
|
+
* This is helpful in building a format that has multiple mainCompositions i.e. in the context of the list
|
|
15
|
+
* The list format is helpful because you do not have to go over each individual query.
|
|
16
|
+
* @param connections the type connections that need (external connections) to be passed
|
|
17
|
+
* @param compositionData this is a dictionary type of format that has all the build compositions {id: { actual data}}
|
|
18
|
+
* @param mainComposition this is list of ids of the main composition that builds the tree
|
|
19
|
+
* @param reverse this is the list of connections ids that needs to go to the reverse direction (to---->from)
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export declare function FormatFromConnectionsAlteredArrayExternalClean(connections: Connection[], compositionData: any[], mainComposition: number[], reverse: number[] | undefined, CountDictionary: any[]): Promise<any[]>;
|
|
23
|
+
export declare function AddCount(ofTheConceptId: number, CountDictionary: any, newData: any): void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Returns user details synchronously.
|
|
3
|
+
* Priority: in-memory profileCache (encrypted) → legacy localStorage("profile") fallback.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getUserDetails(): Record<string, any>;
|
|
@@ -108,7 +108,7 @@ export declare class BuilderStatefulWidget extends StatefulWidget {
|
|
|
108
108
|
* const userId = await widget.getUserId();
|
|
109
109
|
* console.log('Current user:', userId);
|
|
110
110
|
*/
|
|
111
|
-
getUserId():
|
|
111
|
+
getUserId(): any;
|
|
112
112
|
/**
|
|
113
113
|
* Fetches a list of type values from the backend based on the widget's type.
|
|
114
114
|
*
|
|
@@ -1,17 +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
|
+
*/
|
|
1
18
|
export declare class WidgetCacheManager {
|
|
2
|
-
|
|
3
|
-
private static
|
|
4
|
-
|
|
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
|
+
*/
|
|
5
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
|
+
*/
|
|
6
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
|
+
*/
|
|
7
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
|
+
*/
|
|
8
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
|
+
*/
|
|
9
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
|
+
*/
|
|
10
79
|
static setRecent(id: number, data: any): void;
|
|
11
|
-
|
|
12
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Removes a single recent-version entry from memory and IndexedDB.
|
|
82
|
+
* @param id - The origin widget ID to remove
|
|
83
|
+
*/
|
|
13
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
|
+
*/
|
|
14
89
|
static clearAll(): void;
|
|
15
|
-
|
|
16
|
-
|
|
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;
|
|
17
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
|
|
@@ -1,10 +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
|
+
*/
|
|
1
22
|
export declare class QueryCacheManager {
|
|
23
|
+
/** Prefix for CustomEvent names — ensures no collision with other window events */
|
|
2
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
|
+
*/
|
|
3
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
|
+
*/
|
|
4
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
|
+
*/
|
|
5
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
|
+
*/
|
|
6
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
|
+
*/
|
|
7
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
|
+
*/
|
|
8
81
|
static clearAll(): void;
|
|
9
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
|
+
*/
|
|
10
98
|
export declare function hashJsonObject(obj: any): Promise<string>;
|
package/dist/types/app.d.ts
CHANGED
|
@@ -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
128
|
export { getUserDetails } 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,6 +347,7 @@ 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;
|
|
350
353
|
isPwa?: boolean;
|