@danielsimonjr/memoryjs 2.6.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +65 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +198 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +162 -1
- package/dist/index.d.ts +162 -1
- package/dist/index.js +195 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3416,6 +3416,144 @@ var init_WorkerPoolManager = __esm({
|
|
|
3416
3416
|
}
|
|
3417
3417
|
});
|
|
3418
3418
|
|
|
3419
|
+
// src/utils/WorkerTaskManager.ts
|
|
3420
|
+
function getWorkerTaskManager() {
|
|
3421
|
+
if (!DEFAULT_INSTANCE) DEFAULT_INSTANCE = new WorkerTaskManager();
|
|
3422
|
+
return DEFAULT_INSTANCE;
|
|
3423
|
+
}
|
|
3424
|
+
async function batchProcessViaWorkers(items, workerType, methodName, mapArgs, opts = {}) {
|
|
3425
|
+
if (items.length === 0) return [];
|
|
3426
|
+
const wtm = getWorkerTaskManager();
|
|
3427
|
+
const promises = items.map(
|
|
3428
|
+
(item, i) => wtm.submit(workerType, methodName, mapArgs(item, i), opts)
|
|
3429
|
+
);
|
|
3430
|
+
return Promise.all(promises);
|
|
3431
|
+
}
|
|
3432
|
+
var SUBMISSION_COUNTER, WorkerTaskManager, DEFAULT_INSTANCE;
|
|
3433
|
+
var init_WorkerTaskManager = __esm({
|
|
3434
|
+
"src/utils/WorkerTaskManager.ts"() {
|
|
3435
|
+
"use strict";
|
|
3436
|
+
init_cjs_shims();
|
|
3437
|
+
init_taskScheduler();
|
|
3438
|
+
init_WorkerPoolManager();
|
|
3439
|
+
init_logger();
|
|
3440
|
+
SUBMISSION_COUNTER = 0;
|
|
3441
|
+
WorkerTaskManager = class {
|
|
3442
|
+
queue;
|
|
3443
|
+
poolManager;
|
|
3444
|
+
touchedPoolIds = /* @__PURE__ */ new Set();
|
|
3445
|
+
cancelledTaskIds = /* @__PURE__ */ new Set();
|
|
3446
|
+
handleStatus = /* @__PURE__ */ new Map();
|
|
3447
|
+
constructor(opts = {}) {
|
|
3448
|
+
this.queue = new TaskQueue({
|
|
3449
|
+
concurrency: opts.concurrency,
|
|
3450
|
+
timeout: opts.defaultTimeout,
|
|
3451
|
+
// We dispatch to WorkerPoolManager ourselves — the queue's
|
|
3452
|
+
// internal-worker-pool path would double-up.
|
|
3453
|
+
useWorkerPool: false
|
|
3454
|
+
});
|
|
3455
|
+
this.poolManager = getWorkerPoolManager();
|
|
3456
|
+
}
|
|
3457
|
+
/**
|
|
3458
|
+
* Submit a task and await its result. Throws on failure / cancellation.
|
|
3459
|
+
*
|
|
3460
|
+
* @param workerType — routing key. Maps to a named `WorkerPoolManager` pool.
|
|
3461
|
+
* @param methodName — function name exposed by the worker module.
|
|
3462
|
+
* @param args — positional arguments passed to the worker function.
|
|
3463
|
+
*/
|
|
3464
|
+
async submit(workerType, methodName, args, opts = {}) {
|
|
3465
|
+
const handle = this.submitWithHandle(workerType, methodName, args, opts);
|
|
3466
|
+
return handle.result;
|
|
3467
|
+
}
|
|
3468
|
+
/**
|
|
3469
|
+
* Submit a task and return a handle for cancellation + status polling.
|
|
3470
|
+
*/
|
|
3471
|
+
submitWithHandle(workerType, methodName, args, opts = {}) {
|
|
3472
|
+
const id = `wtm-${Date.now()}-${++SUBMISSION_COUNTER}`;
|
|
3473
|
+
this.handleStatus.set(id, "pending" /* PENDING */);
|
|
3474
|
+
const task = {
|
|
3475
|
+
id,
|
|
3476
|
+
priority: opts.priority ?? 1 /* NORMAL */,
|
|
3477
|
+
timeout: opts.timeout,
|
|
3478
|
+
input: { workerType, methodName, args },
|
|
3479
|
+
fn: async (input) => {
|
|
3480
|
+
if (this.cancelledTaskIds.has(id)) {
|
|
3481
|
+
throw new Error(`Task ${id} cancelled before dispatch`);
|
|
3482
|
+
}
|
|
3483
|
+
this.handleStatus.set(id, "running" /* RUNNING */);
|
|
3484
|
+
const pool = this.poolManager.getPool(input.workerType, opts.poolConfig);
|
|
3485
|
+
this.touchedPoolIds.add(input.workerType);
|
|
3486
|
+
return await pool.exec(input.methodName, input.args);
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
const result = this.queue.enqueue(task).then(async (res) => {
|
|
3490
|
+
this.handleStatus.set(id, res.status);
|
|
3491
|
+
if (res.status === "completed" /* COMPLETED */) {
|
|
3492
|
+
return res.result;
|
|
3493
|
+
}
|
|
3494
|
+
if (res.status === "cancelled" /* CANCELLED */ || this.cancelledTaskIds.has(id)) {
|
|
3495
|
+
throw new Error(`Task ${id} cancelled`);
|
|
3496
|
+
}
|
|
3497
|
+
const err2 = res.error ?? new Error(`Task ${id} failed: ${res.status}`);
|
|
3498
|
+
throw err2;
|
|
3499
|
+
});
|
|
3500
|
+
return {
|
|
3501
|
+
id,
|
|
3502
|
+
result,
|
|
3503
|
+
cancel: () => {
|
|
3504
|
+
this.cancelledTaskIds.add(id);
|
|
3505
|
+
const evicted = this.queue.cancel(id);
|
|
3506
|
+
if (evicted) {
|
|
3507
|
+
this.handleStatus.set(id, "cancelled" /* CANCELLED */);
|
|
3508
|
+
}
|
|
3509
|
+
return evicted;
|
|
3510
|
+
},
|
|
3511
|
+
status: () => this.handleStatus.get(id) ?? "pending" /* PENDING */
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
/**
|
|
3515
|
+
* Aggregated stats across the queue + touched pools.
|
|
3516
|
+
*/
|
|
3517
|
+
getStats() {
|
|
3518
|
+
const pools = [];
|
|
3519
|
+
for (const poolId of this.touchedPoolIds) {
|
|
3520
|
+
const stats = this.poolManager.getPoolStats(poolId);
|
|
3521
|
+
if (stats) {
|
|
3522
|
+
pools.push({
|
|
3523
|
+
poolId,
|
|
3524
|
+
workers: stats.totalWorkers,
|
|
3525
|
+
activeTasks: stats.activeTasks,
|
|
3526
|
+
pendingTasks: stats.pendingTasks,
|
|
3527
|
+
totalTasksExecuted: stats.totalTasksExecuted
|
|
3528
|
+
});
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
return { queue: this.queue.getStats(), pools };
|
|
3532
|
+
}
|
|
3533
|
+
/**
|
|
3534
|
+
* Drain the queue (wait for all pending + running tasks) and return their
|
|
3535
|
+
* results in completion order. Pool workers are NOT terminated — call
|
|
3536
|
+
* `shutdown()` for that.
|
|
3537
|
+
*/
|
|
3538
|
+
async drain() {
|
|
3539
|
+
return this.queue.drain();
|
|
3540
|
+
}
|
|
3541
|
+
/**
|
|
3542
|
+
* Shut down the queue + the underlying WorkerPoolManager pools touched by
|
|
3543
|
+
* this instance. Idempotent. Returns after every owned worker has exited.
|
|
3544
|
+
*/
|
|
3545
|
+
async shutdown() {
|
|
3546
|
+
try {
|
|
3547
|
+
await this.queue.shutdown();
|
|
3548
|
+
} catch (e) {
|
|
3549
|
+
logger.warn("[WorkerTaskManager.shutdown] queue.shutdown failed:", e);
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
};
|
|
3553
|
+
DEFAULT_INSTANCE = null;
|
|
3554
|
+
}
|
|
3555
|
+
});
|
|
3556
|
+
|
|
3419
3557
|
// src/utils/BatchProcessor.ts
|
|
3420
3558
|
async function processBatch(items, processor, options = {}) {
|
|
3421
3559
|
const batchProcessor = new BatchProcessor(options);
|
|
@@ -11270,6 +11408,7 @@ var init_utils = __esm({
|
|
|
11270
11408
|
init_taskScheduler();
|
|
11271
11409
|
init_operationUtils();
|
|
11272
11410
|
init_WorkerPoolManager();
|
|
11411
|
+
init_WorkerTaskManager();
|
|
11273
11412
|
init_BatchProcessor();
|
|
11274
11413
|
init_MemoryMonitor();
|
|
11275
11414
|
init_relationHelpers();
|
|
@@ -13775,6 +13914,7 @@ __export(index_exports, {
|
|
|
13775
13914
|
VisibilityResolver: () => VisibilityResolver,
|
|
13776
13915
|
WorkThreadManager: () => WorkThreadManager,
|
|
13777
13916
|
WorkerPoolManager: () => WorkerPoolManager,
|
|
13917
|
+
WorkerTaskManager: () => WorkerTaskManager,
|
|
13778
13918
|
WorkingMemoryManager: () => WorkingMemoryManager,
|
|
13779
13919
|
WorldModelManager: () => WorldModelManager,
|
|
13780
13920
|
WorldStateSnapshot: () => WorldStateSnapshot,
|
|
@@ -13784,6 +13924,7 @@ __export(index_exports, {
|
|
|
13784
13924
|
applyPagination: () => applyPagination,
|
|
13785
13925
|
asWarning: () => asWarning,
|
|
13786
13926
|
batchProcess: () => batchProcess,
|
|
13927
|
+
batchProcessViaWorkers: () => batchProcessViaWorkers,
|
|
13787
13928
|
buildTFVector: () => buildTFVector,
|
|
13788
13929
|
calculateIDF: () => calculateIDF,
|
|
13789
13930
|
calculateIDFFromTokenSets: () => calculateIDFFromTokenSets,
|
|
@@ -13854,6 +13995,7 @@ __export(index_exports, {
|
|
|
13854
13995
|
getQuickHint: () => getQuickHint,
|
|
13855
13996
|
getRoleProfile: () => getRoleProfile,
|
|
13856
13997
|
getWorkerPoolManager: () => getWorkerPoolManager,
|
|
13998
|
+
getWorkerTaskManager: () => getWorkerTaskManager,
|
|
13857
13999
|
globalMemoryMonitor: () => globalMemoryMonitor,
|
|
13858
14000
|
groupEntitiesByType: () => groupEntitiesByType,
|
|
13859
14001
|
hasAllTags: () => hasAllTags,
|
|
@@ -21114,6 +21256,27 @@ CREATE INDEX IF NOT EXISTS idx_entities_project_id ON entities(project_id);
|
|
|
21114
21256
|
CREATE INDEX IF NOT EXISTS idx_entities_content_hash ON entities(content_hash);
|
|
21115
21257
|
CREATE INDEX IF NOT EXISTS idx_entities_tags_gin ON entities USING GIN(tags);
|
|
21116
21258
|
|
|
21259
|
+
-- v2.8.0 \u2014 generated tsvector column for full-text search.
|
|
21260
|
+
-- name is weighted A (highest), observations B, tags C. PostgreSQL 12+
|
|
21261
|
+
-- supports GENERATED ALWAYS AS ... STORED; the DO block makes the column
|
|
21262
|
+
-- add idempotent on older + newer servers without requiring CREATE OR
|
|
21263
|
+
-- REPLACE semantics on ALTER.
|
|
21264
|
+
DO $$ BEGIN
|
|
21265
|
+
IF NOT EXISTS (
|
|
21266
|
+
SELECT 1 FROM information_schema.columns
|
|
21267
|
+
WHERE table_name = 'entities' AND column_name = 'fts_vector'
|
|
21268
|
+
) THEN
|
|
21269
|
+
ALTER TABLE entities ADD COLUMN fts_vector tsvector
|
|
21270
|
+
GENERATED ALWAYS AS (
|
|
21271
|
+
setweight(to_tsvector('english', name), 'A') ||
|
|
21272
|
+
setweight(to_tsvector('english', coalesce(array_to_string(observations, ' '), '')), 'B') ||
|
|
21273
|
+
setweight(to_tsvector('english', coalesce(array_to_string(tags, ' '), '')), 'C')
|
|
21274
|
+
) STORED;
|
|
21275
|
+
END IF;
|
|
21276
|
+
END $$;
|
|
21277
|
+
|
|
21278
|
+
CREATE INDEX IF NOT EXISTS idx_entities_fts_gin ON entities USING GIN(fts_vector);
|
|
21279
|
+
|
|
21117
21280
|
CREATE TABLE IF NOT EXISTS relations (
|
|
21118
21281
|
from_name TEXT NOT NULL,
|
|
21119
21282
|
to_name TEXT NOT NULL,
|
|
@@ -21433,6 +21596,38 @@ var PostgreSQLStorage = class {
|
|
|
21433
21596
|
hasRelations(entityName) {
|
|
21434
21597
|
return (this.outgoingRelations.get(entityName)?.length ?? 0) + (this.incomingRelations.get(entityName)?.length ?? 0) > 0;
|
|
21435
21598
|
}
|
|
21599
|
+
// ==================== Full-text search ====================
|
|
21600
|
+
/**
|
|
21601
|
+
* tsvector-backed full-text search. Uses `plainto_tsquery` so the input is
|
|
21602
|
+
* free-form (no boolean operator syntax required); ranks via `ts_rank` on
|
|
21603
|
+
* the weighted `fts_vector` column (name × A, observations × B, tags × C).
|
|
21604
|
+
*
|
|
21605
|
+
* Results are ordered by descending score and capped at `options.limit`
|
|
21606
|
+
* (default 50). Empty / whitespace-only queries return `[]` without
|
|
21607
|
+
* issuing a SQL call.
|
|
21608
|
+
*
|
|
21609
|
+
* @example
|
|
21610
|
+
* ```typescript
|
|
21611
|
+
* const matches = await storage.fullTextSearch('authentication flow', { limit: 10 });
|
|
21612
|
+
* // → [{ name: 'AuthService', score: 0.62 }, ...]
|
|
21613
|
+
* ```
|
|
21614
|
+
*/
|
|
21615
|
+
async fullTextSearch(query, options = {}) {
|
|
21616
|
+
const trimmed = query.trim();
|
|
21617
|
+
if (trimmed.length === 0) return [];
|
|
21618
|
+
await this.initSchema();
|
|
21619
|
+
const pool = await this.getPool();
|
|
21620
|
+
const limit = options.limit ?? 50;
|
|
21621
|
+
const res = await pool.query(
|
|
21622
|
+
`SELECT name, ts_rank(fts_vector, plainto_tsquery('english', $1))::float AS score
|
|
21623
|
+
FROM entities
|
|
21624
|
+
WHERE fts_vector @@ plainto_tsquery('english', $1)
|
|
21625
|
+
ORDER BY score DESC
|
|
21626
|
+
LIMIT $2`,
|
|
21627
|
+
[trimmed, limit]
|
|
21628
|
+
);
|
|
21629
|
+
return res.rows.map((r) => ({ name: r.name, score: Number(r.score) }));
|
|
21630
|
+
}
|
|
21436
21631
|
// ==================== Utility ====================
|
|
21437
21632
|
getFilePath() {
|
|
21438
21633
|
return this.connectionString;
|
|
@@ -52171,6 +52366,7 @@ function extractRoleAndContent(entity) {
|
|
|
52171
52366
|
VisibilityResolver,
|
|
52172
52367
|
WorkThreadManager,
|
|
52173
52368
|
WorkerPoolManager,
|
|
52369
|
+
WorkerTaskManager,
|
|
52174
52370
|
WorkingMemoryManager,
|
|
52175
52371
|
WorldModelManager,
|
|
52176
52372
|
WorldStateSnapshot,
|
|
@@ -52180,6 +52376,7 @@ function extractRoleAndContent(entity) {
|
|
|
52180
52376
|
applyPagination,
|
|
52181
52377
|
asWarning,
|
|
52182
52378
|
batchProcess,
|
|
52379
|
+
batchProcessViaWorkers,
|
|
52183
52380
|
buildTFVector,
|
|
52184
52381
|
calculateIDF,
|
|
52185
52382
|
calculateIDFFromTokenSets,
|
|
@@ -52250,6 +52447,7 @@ function extractRoleAndContent(entity) {
|
|
|
52250
52447
|
getQuickHint,
|
|
52251
52448
|
getRoleProfile,
|
|
52252
52449
|
getWorkerPoolManager,
|
|
52450
|
+
getWorkerTaskManager,
|
|
52253
52451
|
globalMemoryMonitor,
|
|
52254
52452
|
groupEntitiesByType,
|
|
52255
52453
|
hasAllTags,
|