@harperfast/harper-pro 5.0.4 → 5.0.6
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/core/AGENTS.md +107 -0
- package/core/CLAUDE.md +1 -0
- package/core/bin/status.js +2 -2
- package/core/bin/stop.js +5 -6
- package/core/components/EntryHandler.ts +4 -2
- package/core/components/Scope.ts +1 -1
- package/core/components/componentLoader.ts +11 -4
- package/core/components/requestRestart.ts +17 -2
- package/core/dataLayer/harperBridge/TableSizeObject.ts +35 -0
- package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.ts +24 -0
- package/core/package-lock.json +1043 -112
- package/core/resources/DatabaseTransaction.ts +8 -3
- package/core/resources/Table.ts +12 -17
- package/core/resources/databases.ts +2 -2
- package/core/resources/graphql.ts +163 -165
- package/core/resources/indexes/HierarchicalNavigableSmallWorld.ts +14 -3
- package/core/resources/indexes/vector.ts +17 -0
- package/core/resources/loadEnv.ts +20 -16
- package/core/resources/login.ts +4 -3
- package/core/resources/roles.ts +60 -65
- package/core/security/auth.ts +15 -14
- package/core/security/jsLoader.ts +27 -9
- package/core/security/keys.js +1 -1
- package/core/server/REST.ts +10 -11
- package/core/server/fastifyRoutes.ts +30 -29
- package/core/server/graphqlQuerying.ts +4 -3
- package/core/server/http.ts +175 -1
- package/core/server/mqtt.ts +8 -2
- package/core/server/serverHelpers/serverUtilities.ts +2 -5
- package/core/server/threads/threadServer.js +30 -2
- package/core/server/throttle.ts +18 -0
- package/core/utility/environment/environmentManager.js +10 -4
- package/core/utility/environment/systemInformation.ts +698 -0
- package/core/utility/hdbTerms.ts +1 -0
- package/core/utility/operation_authorization.js +2 -5
- package/dist/core/bin/status.js +2 -2
- package/dist/core/bin/status.js.map +1 -1
- package/dist/core/bin/stop.js +5 -5
- package/dist/core/bin/stop.js.map +1 -1
- package/dist/core/components/EntryHandler.js +4 -2
- package/dist/core/components/EntryHandler.js.map +1 -1
- package/dist/core/components/Scope.js +1 -1
- package/dist/core/components/Scope.js.map +1 -1
- package/dist/core/components/componentLoader.js +11 -3
- package/dist/core/components/componentLoader.js.map +1 -1
- package/dist/core/components/requestRestart.js +12 -1
- package/dist/core/components/requestRestart.js.map +1 -1
- package/dist/core/dataLayer/harperBridge/TableSizeObject.js +32 -0
- package/dist/core/dataLayer/harperBridge/TableSizeObject.js.map +1 -0
- package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +18 -19
- package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js.map +1 -1
- package/dist/core/resources/DatabaseTransaction.js +6 -1
- package/dist/core/resources/DatabaseTransaction.js.map +1 -1
- package/dist/core/resources/Table.js +14 -18
- package/dist/core/resources/Table.js.map +1 -1
- package/dist/core/resources/databases.js +2 -1
- package/dist/core/resources/databases.js.map +1 -1
- package/dist/core/resources/graphql.js +176 -176
- package/dist/core/resources/graphql.js.map +1 -1
- package/dist/core/resources/indexes/HierarchicalNavigableSmallWorld.js +14 -2
- package/dist/core/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/core/resources/indexes/vector.js +14 -0
- package/dist/core/resources/indexes/vector.js.map +1 -1
- package/dist/core/resources/loadEnv.js +20 -17
- package/dist/core/resources/loadEnv.js.map +1 -1
- package/dist/core/resources/login.js +4 -4
- package/dist/core/resources/login.js.map +1 -1
- package/dist/core/resources/roles.js +64 -68
- package/dist/core/resources/roles.js.map +1 -1
- package/dist/core/security/auth.js +17 -15
- package/dist/core/security/auth.js.map +1 -1
- package/dist/core/security/jsLoader.js +29 -9
- package/dist/core/security/jsLoader.js.map +1 -1
- package/dist/core/security/keys.js +1 -1
- package/dist/core/server/REST.js +11 -11
- package/dist/core/server/REST.js.map +1 -1
- package/dist/core/server/fastifyRoutes.js +30 -29
- package/dist/core/server/fastifyRoutes.js.map +1 -1
- package/dist/core/server/graphqlQuerying.js +5 -4
- package/dist/core/server/graphqlQuerying.js.map +1 -1
- package/dist/core/server/http.js +179 -0
- package/dist/core/server/http.js.map +1 -1
- package/dist/core/server/mqtt.js +5 -3
- package/dist/core/server/mqtt.js.map +1 -1
- package/dist/core/server/serverHelpers/serverUtilities.js +2 -2
- package/dist/core/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/core/server/threads/threadServer.js +26 -2
- package/dist/core/server/threads/threadServer.js.map +1 -1
- package/dist/core/server/throttle.js +17 -0
- package/dist/core/server/throttle.js.map +1 -1
- package/dist/core/utility/environment/environmentManager.js +9 -4
- package/dist/core/utility/environment/environmentManager.js.map +1 -1
- package/dist/core/utility/environment/systemInformation.js +359 -219
- package/dist/core/utility/environment/systemInformation.js.map +1 -1
- package/dist/core/utility/hdbTerms.js +1 -0
- package/dist/core/utility/hdbTerms.js.map +1 -1
- package/dist/core/utility/operation_authorization.js +2 -2
- package/dist/core/utility/operation_authorization.js.map +1 -1
- package/dist/licensing/usageLicensing.js +1 -1
- package/dist/licensing/usageLicensing.js.map +1 -1
- package/dist/replication/replicationConnection.js +1 -0
- package/dist/replication/replicationConnection.js.map +1 -1
- package/dist/replication/setNode.js +1 -1
- package/dist/replication/setNode.js.map +1 -1
- package/dist/replication/subscriptionManager.js +1 -0
- package/dist/replication/subscriptionManager.js.map +1 -1
- package/licensing/usageLicensing.ts +1 -1
- package/npm-shrinkwrap.json +1880 -891
- package/package.json +14 -13
- package/replication/replicationConnection.ts +1 -0
- package/replication/setNode.ts +1 -1
- package/replication/subscriptionManager.ts +1 -0
- package/studio/web/assets/{index-CjeZNBFc.js → index-qbLPhOzw.js} +2 -2
- package/studio/web/assets/{index-CjeZNBFc.js.map → index-qbLPhOzw.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -25
- package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +0 -34
- package/core/utility/environment/systemInformation.js +0 -355
- package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -24
- package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js.map +0 -1
package/core/AGENTS.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What This Is
|
|
8
|
+
|
|
9
|
+
Harper is a Node.js unified development platform that fuses a document database (RocksDB-backed), in-memory cache, application runtime, and messaging broker (WebSockets, MQTT, NATS) into a single in-process runtime. This directory is the open-source core (`harper` npm package, Apache-2.0), which is the base for the enterprise `harper-pro` wrapper above it.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Build
|
|
17
|
+
npm run build # TypeScript → dist/ via tsconfig.build.json
|
|
18
|
+
npm run build:watch # Incremental watch build
|
|
19
|
+
|
|
20
|
+
# Lint / Format
|
|
21
|
+
npm run lint # oxlint (warnings = errors)
|
|
22
|
+
npm run lint:fix # Auto-fix
|
|
23
|
+
npm run format:write # Prettier
|
|
24
|
+
|
|
25
|
+
# Test — run specific suites
|
|
26
|
+
npm run test:unit # All unit tests (mocha)
|
|
27
|
+
npm run test:unit:main # Core unit tests (excludes apiTests, lmdb, resources)
|
|
28
|
+
npm run test:unit:resources # Resource layer tests
|
|
29
|
+
npm run test:unit:server # Server layer tests
|
|
30
|
+
npm run test:unit:dataLayer # Data layer tests
|
|
31
|
+
npm run test:unit:components # Component/plugin system tests
|
|
32
|
+
npm run test:unit:security # Security tests
|
|
33
|
+
npm run test:unit:apitests # API tests (stops running server first)
|
|
34
|
+
npm run test:unit:lmdb # LMDB storage engine tests
|
|
35
|
+
npm run test:integration # Full integration test suite
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Run a single test file directly:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx mocha unitTests/resources/mytest.js
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
TypeScript is stripped at runtime via `--conditions=typestrip` (Node.js native type stripping) — no compilation required for development. Use `npm run test:unit:typestrip` to run tests with this mode.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Architecture
|
|
49
|
+
|
|
50
|
+
### Layers (top to bottom)
|
|
51
|
+
|
|
52
|
+
**Components** (`components/`)
|
|
53
|
+
The plugin/application loader. Applications export a `handleApplication(scope)` function. `Scope` is the primary object passed to apps; it exposes:
|
|
54
|
+
|
|
55
|
+
- `scope.options` — `OptionsWatcher` for live-reloaded YAML config
|
|
56
|
+
- `scope.resources` — access to database tables and registered resources
|
|
57
|
+
- `scope.server` — the HTTP server handle
|
|
58
|
+
|
|
59
|
+
Files within a component are discovered via micromatch glob patterns and automatically mapped to URL paths.
|
|
60
|
+
|
|
61
|
+
**Server** (`server/`)
|
|
62
|
+
Two HTTP stacks coexist:
|
|
63
|
+
|
|
64
|
+
- **Native layer** (`server/http.ts`) — direct socket handling for HTTP/1.1, HTTPS, HTTP/2, and WebSockets in one path; highest performance
|
|
65
|
+
- **Fastify layer** (`server/fastifyRoutes.ts`) — used for legacy custom functions; wraps Fastify with autoload
|
|
66
|
+
|
|
67
|
+
All inbound protocols (REST, GraphQL, MQTT, NATS, WebSockets) eventually resolve to the same **Resource interface**.
|
|
68
|
+
|
|
69
|
+
**Resources** (`resources/`)
|
|
70
|
+
The universal abstraction. Everything that can be queried or mutated — database tables, caches, message topics, custom endpoints — extends `Resource` (`resources/Resource.ts`).
|
|
71
|
+
|
|
72
|
+
Static methods (`Resource.get`, `Resource.put`, `Resource.post`, `Resource.delete`, `Resource.patch`, `Resource.subscribe`) are the entry points and are automatically wrapped with `transactional()` for transaction management. Override instance methods (`get`, `put`, etc.) for custom behavior.
|
|
73
|
+
|
|
74
|
+
`Table.ts` is the database table implementation (~177KB) — the most complex file in the codebase.
|
|
75
|
+
|
|
76
|
+
**Data Layer** (`dataLayer/`)
|
|
77
|
+
Legacy translation modules plus SQL translation (`sqlTranslator/`) via AlaSQL; these should be avoided. The storage engine is selectable via `HARPER_STORAGE_ENGINE=lmdb`.
|
|
78
|
+
|
|
79
|
+
**Configuration** (`config/`)
|
|
80
|
+
YAML-based. `configUtils.js` parses config; `RootConfigWatcher.ts` enables hot reload. Environment variables override YAML values.
|
|
81
|
+
|
|
82
|
+
**Utility** (`utility/`)
|
|
83
|
+
Logging, error types, helpers, async utilities.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Key Patterns
|
|
88
|
+
|
|
89
|
+
**`transactional()` wrapper** — All static Resource methods go through this. It ensures async operations run inside a database transaction. Use `contextStorage` (AsyncLocalStorage) to access the current transaction context without passing it explicitly.
|
|
90
|
+
|
|
91
|
+
**Resource discovery** — A component's config file maps glob patterns to URL paths. Files matching a pattern become routable resources automatically; no explicit route registration is needed.
|
|
92
|
+
|
|
93
|
+
**Lazy loading** — GraphQL, secure sandboxing, and tarball extraction are imported on demand. Do not add top-level imports for these modules.
|
|
94
|
+
|
|
95
|
+
**TypeScript + type stripping** — Source files are `.ts` but Node.js runs them directly via type stripping in development. The `dist/` directory is the compiled production artifact. Both `.ts` and legacy `.js` files coexist; new code should be `.ts`.
|
|
96
|
+
|
|
97
|
+
**Minimal dependencies** — `dependencies.md` documents the rationale for every dependency. Adding a new dependency requires justification; implementing something ourselves is often preferred.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Non-Obvious Constraints
|
|
102
|
+
|
|
103
|
+
- `Resource` static methods must stay wrapped with `transactional()` — removing this breaks transaction isolation.
|
|
104
|
+
- Worker threads (`server/threads/`) receive `workerData.noServerStart = true` to prevent recursive server startup; never start the server inside a worker.
|
|
105
|
+
- `contextStorage` (AsyncLocalStorage) carries per-request context (user, transaction) across async boundaries — this is how authorization and transactions work without explicit parameter threading.
|
|
106
|
+
- Tests under `unitTests/apiTests/` require the server to be stopped first (`node ./dist/bin/harper.js stop`) — `test:unit:apitests` does this automatically.
|
|
107
|
+
- `@export` annotation on a schema class auto-generates a REST API for that table — this is the primary developer-facing API.
|
package/core/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Please see AGENTS.md for guidance on this project.
|
package/core/bin/status.js
CHANGED
|
@@ -6,7 +6,7 @@ const YAML = require('yaml');
|
|
|
6
6
|
|
|
7
7
|
const hdbTerms = require('../utility/hdbTerms.ts');
|
|
8
8
|
const hdbLog = require('../utility/logging/harper_logger.js');
|
|
9
|
-
const
|
|
9
|
+
const systemInformation = require('../utility/environment/systemInformation.ts');
|
|
10
10
|
const envMgr = require('../utility/environment/environmentManager.js');
|
|
11
11
|
const installation = require('../utility/installation.ts');
|
|
12
12
|
envMgr.initSync();
|
|
@@ -51,7 +51,7 @@ async function status() {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Check the saved pid against any running hdb processes
|
|
54
|
-
const hdbSysInfo = await
|
|
54
|
+
const hdbSysInfo = await systemInformation.getHDBProcessInfo();
|
|
55
55
|
for (const proc of hdbSysInfo.core) {
|
|
56
56
|
if (proc.pid === hdbPid) {
|
|
57
57
|
status.harperdb.status = STATUSES.RUNNING;
|
package/core/bin/stop.js
CHANGED
|
@@ -4,7 +4,7 @@ const hdbLogger = require('../utility/logging/harper_logger.js');
|
|
|
4
4
|
const util = require('util');
|
|
5
5
|
const childProcess = require('child_process');
|
|
6
6
|
const exec = util.promisify(childProcess.exec);
|
|
7
|
-
const
|
|
7
|
+
const systemInformation = require('../utility/environment/systemInformation.ts');
|
|
8
8
|
|
|
9
9
|
const STOP_MSG = 'Stopping Harper Pro.';
|
|
10
10
|
|
|
@@ -14,9 +14,8 @@ async function stop() {
|
|
|
14
14
|
console.log(STOP_MSG);
|
|
15
15
|
hdbLogger.notify(STOP_MSG);
|
|
16
16
|
|
|
17
|
-
const processes = await
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
17
|
+
const processes = await systemInformation.getHDBProcessInfo();
|
|
18
|
+
for (const { pid } of processes.core) {
|
|
19
|
+
exec(`kill ${pid}`);
|
|
20
|
+
}
|
|
22
21
|
}
|
|
@@ -189,12 +189,14 @@ export class EntryHandler extends EventEmitter<EntryHandlerEventMap> {
|
|
|
189
189
|
.watch(this.#component.commonPatternBase, {
|
|
190
190
|
cwd: this.#component.directory,
|
|
191
191
|
persistent: false,
|
|
192
|
+
followSymlinks: false,
|
|
192
193
|
ignored: (path) => {
|
|
193
194
|
const normalizedPath = path.replace(/\\/g, '/');
|
|
194
195
|
const normalizedBases = allowedBases.map((base) => base.replace(/\\/g, '/'));
|
|
195
196
|
return (
|
|
196
|
-
normalizedPath
|
|
197
|
-
|
|
197
|
+
normalizedPath.includes('/node_modules') ||
|
|
198
|
+
(normalizedPath !== this.#component.directory.replace(/\\/g, '/') &&
|
|
199
|
+
normalizedBases.every((base) => !normalizedPath.startsWith(base)))
|
|
198
200
|
);
|
|
199
201
|
},
|
|
200
202
|
})
|
package/core/components/Scope.ts
CHANGED
|
@@ -63,7 +63,7 @@ export class Scope extends EventEmitter<ScopeEventsMap> {
|
|
|
63
63
|
this.#pluginName = pluginName;
|
|
64
64
|
this.#directory = directory;
|
|
65
65
|
this.#configFilePath = configFilePath;
|
|
66
|
-
this.#logger =
|
|
66
|
+
this.#logger = loggerWithTag(this.#appName);
|
|
67
67
|
|
|
68
68
|
this.databaseEvents = databaseEventsEmitter;
|
|
69
69
|
this.applicationScope = applicationScope;
|
|
@@ -17,7 +17,8 @@ import * as staticFiles from '../server/static.ts';
|
|
|
17
17
|
import * as loadEnv from '../resources/loadEnv.ts';
|
|
18
18
|
import harperLogger from '../utility/logging/harper_logger.js';
|
|
19
19
|
import * as dataLoader from '../resources/dataLoader.ts';
|
|
20
|
-
import {
|
|
20
|
+
import { restartWorkers, getWorkerIndex } from '../server/threads/manageThreads.js';
|
|
21
|
+
import { resetRestartNeeded, subscribeToRestartRequests } from './requestRestart.ts';
|
|
21
22
|
import { scopedImport } from '../security/jsLoader.ts';
|
|
22
23
|
import { server } from '../server/Server.ts';
|
|
23
24
|
import { Resources } from '../resources/Resources.ts';
|
|
@@ -515,10 +516,16 @@ export async function loadComponent(
|
|
|
515
516
|
}
|
|
516
517
|
|
|
517
518
|
compName = parentCompName;
|
|
518
|
-
// Auto restart threads on changes to any app folder. TODO: Make this configurable
|
|
519
519
|
if (isMainThread && !watchesSetup && autoReload) {
|
|
520
|
-
|
|
521
|
-
|
|
520
|
+
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
521
|
+
subscribeToRestartRequests(() => {
|
|
522
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
523
|
+
debounceTimer = setTimeout(async () => {
|
|
524
|
+
debounceTimer = null;
|
|
525
|
+
resetRestartNeeded();
|
|
526
|
+
await loadComponentDirectories();
|
|
527
|
+
restartWorkers();
|
|
528
|
+
}, 500);
|
|
522
529
|
});
|
|
523
530
|
}
|
|
524
531
|
if ((config.extensionModule || config.pluginModule) && (!isMainThread || config.runOnMainThread)) {
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Status } from '../server/status/index.ts';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface NotifyingArrayBuffer extends ArrayBuffer {
|
|
4
|
+
notify(): void;
|
|
5
|
+
cancel(): void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let restartArrayBuffer: NotifyingArrayBuffer;
|
|
4
9
|
let restartNeededArray: Uint8Array;
|
|
10
|
+
let onRestartRequestedCallback: (() => void) | null = null;
|
|
5
11
|
|
|
6
12
|
function ensureInitialized() {
|
|
7
13
|
if (!restartArrayBuffer) {
|
|
8
|
-
restartArrayBuffer = Status.primaryStore.getUserSharedBuffer('restart-needed', new ArrayBuffer(1)
|
|
14
|
+
restartArrayBuffer = Status.primaryStore.getUserSharedBuffer('restart-needed', new ArrayBuffer(1), {
|
|
15
|
+
callback: () => onRestartRequestedCallback?.(),
|
|
16
|
+
}) as NotifyingArrayBuffer;
|
|
9
17
|
restartNeededArray = new Uint8Array(restartArrayBuffer);
|
|
10
18
|
}
|
|
11
19
|
}
|
|
@@ -13,6 +21,7 @@ function ensureInitialized() {
|
|
|
13
21
|
export function requestRestart() {
|
|
14
22
|
ensureInitialized();
|
|
15
23
|
restartNeededArray[0] = 1;
|
|
24
|
+
restartArrayBuffer.notify();
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
export function restartNeeded() {
|
|
@@ -24,3 +33,9 @@ export function resetRestartNeeded() {
|
|
|
24
33
|
ensureInitialized();
|
|
25
34
|
restartNeededArray[0] = 0;
|
|
26
35
|
}
|
|
36
|
+
|
|
37
|
+
export function subscribeToRestartRequests(callback: () => void) {
|
|
38
|
+
ensureInitialized();
|
|
39
|
+
if (onRestartRequestedCallback) throw new Error('A restart-request subscriber is already registered');
|
|
40
|
+
onRestartRequestedCallback = callback;
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the table size entry for a RocksDB or LMDB table.
|
|
3
|
+
*/
|
|
4
|
+
export class TableSizeObject {
|
|
5
|
+
schema: string;
|
|
6
|
+
table: string;
|
|
7
|
+
tableSize: number;
|
|
8
|
+
recordCount: number;
|
|
9
|
+
transactionLogSize: number;
|
|
10
|
+
transactionLogRecordCount?: number;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param schema - The schema of the table
|
|
14
|
+
* @param table - The name of the table
|
|
15
|
+
* @param tableSize - The data size of the table in bytes
|
|
16
|
+
* @param recordCount - The number of entries in the table
|
|
17
|
+
* @param transactionLogSize - The number of entries in the transaction log
|
|
18
|
+
* @param transactionLogRecordCount - The data size of the transaction log in bytes
|
|
19
|
+
*/
|
|
20
|
+
constructor(
|
|
21
|
+
schema: string,
|
|
22
|
+
table: string,
|
|
23
|
+
tableSize: number = 0,
|
|
24
|
+
recordCount: number = 0,
|
|
25
|
+
transactionLogSize: number = 0,
|
|
26
|
+
transactionLogRecordCount?: number
|
|
27
|
+
) {
|
|
28
|
+
this.schema = schema;
|
|
29
|
+
this.table = table;
|
|
30
|
+
this.tableSize = tableSize;
|
|
31
|
+
this.recordCount = recordCount;
|
|
32
|
+
this.transactionLogSize = transactionLogSize;
|
|
33
|
+
this.transactionLogRecordCount = transactionLogRecordCount;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TableSizeObject } from '../../TableSizeObject.ts';
|
|
2
|
+
import logger from '../../../../utility/logging/harper_logger.js';
|
|
3
|
+
import type { Table } from '../../../../resources/databases.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the number of entries & data size in bytes for a table & its transaction log
|
|
7
|
+
* @param table
|
|
8
|
+
* @returns {TableSizeObject}
|
|
9
|
+
*/
|
|
10
|
+
export function lmdbGetTableSize(table: Table) {
|
|
11
|
+
const tableStats = new TableSizeObject(table.databaseName, table.tableName);
|
|
12
|
+
try {
|
|
13
|
+
const dbiStat = table.primaryStore.getStats();
|
|
14
|
+
|
|
15
|
+
//get the txn log record count
|
|
16
|
+
const txnDbiStat = table.auditStore?.getStats();
|
|
17
|
+
|
|
18
|
+
tableStats.recordCount = dbiStat.entryCount;
|
|
19
|
+
tableStats.transactionLogRecordCount = txnDbiStat.entryCount;
|
|
20
|
+
} catch (e) {
|
|
21
|
+
logger.warn(`unable to stat table dbi due to ${e}`);
|
|
22
|
+
}
|
|
23
|
+
return tableStats;
|
|
24
|
+
}
|