@equationalapplications/core-llm-wiki 7.12.0 → 7.13.1
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/{chunk-KN4XSLLB.mjs → chunk-PCRYIUV5.mjs} +232 -18
- package/dist/chunk-PCRYIUV5.mjs.map +1 -0
- package/dist/index.d.mts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +730 -146
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +502 -133
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-7d76Ptlq.d.mts → testing-CqsXv2_l.d.mts} +111 -18
- package/dist/{testing-7d76Ptlq.d.ts → testing-CqsXv2_l.d.ts} +111 -18
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +80 -15
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +3 -3
- package/dist/chunk-KN4XSLLB.mjs.map +0 -1
|
@@ -379,6 +379,19 @@ interface WikiConfig {
|
|
|
379
379
|
* @default 'allow'
|
|
380
380
|
*/
|
|
381
381
|
migrations?: MigrationPolicy;
|
|
382
|
+
/**
|
|
383
|
+
* Wall-time budget (ms) for each keyword-index quantum: one per `setup()`
|
|
384
|
+
* (shared by the whole open — the deadline is captured when setup() starts)
|
|
385
|
+
* and one per no-arg `syncSearchIndex()`. Checked between chunk
|
|
386
|
+
* transactions, so one quantum can overrun it by up to two chunks. Ids a
|
|
387
|
+
* write stashed for the call (see `upsertGraph`) drain before the quantum
|
|
388
|
+
* and outside the budget. An index reset runs as one unchunked transaction and is
|
|
389
|
+
* not bounded by it either.
|
|
390
|
+
* Convergence of a large backlog or rebuild continues on later opens and
|
|
391
|
+
* `syncSearchIndex()` calls. Must be a positive finite number.
|
|
392
|
+
* @default 1500 (DEFAULT_SETUP_BUDGET_MS)
|
|
393
|
+
*/
|
|
394
|
+
setupBudgetMs?: number;
|
|
382
395
|
}
|
|
383
396
|
interface ReadOptions {
|
|
384
397
|
maxResults?: number;
|
|
@@ -2026,6 +2039,25 @@ interface IndexSearchResult {
|
|
|
2026
2039
|
*/
|
|
2027
2040
|
entity_id: string;
|
|
2028
2041
|
}
|
|
2042
|
+
/** One drain turn's shape (spec #280 Change 3 "drain interface"). */
|
|
2043
|
+
interface DrainOptions {
|
|
2044
|
+
/** `monotonicNow()` timestamp, checked between chunk transactions. Full mode only; default now + the strategy's budget. */
|
|
2045
|
+
deadline?: number;
|
|
2046
|
+
/**
|
|
2047
|
+
* `'ledger'` (write turns): `ids` to completion, then at most ONE foreign
|
|
2048
|
+
* chunk. `'full'` (setup(), no-arg syncSearchIndex()): `ids`, then the
|
|
2049
|
+
* ledger until the deadline, then rebuild work. Default `'full'`.
|
|
2050
|
+
*/
|
|
2051
|
+
mode?: 'ledger' | 'full';
|
|
2052
|
+
/**
|
|
2053
|
+
* The caller's own ledger ids: drained first, to completion, ≤500 per
|
|
2054
|
+
* transaction. Not deadline-bound: the cost is proportional to a write the
|
|
2055
|
+
* caller already made.
|
|
2056
|
+
*/
|
|
2057
|
+
ids?: readonly string[];
|
|
2058
|
+
/** With empty `ids` in ledger mode, the one foreign chunk is `fts_pending WHERE entity_id = ?`. */
|
|
2059
|
+
entityId?: string;
|
|
2060
|
+
}
|
|
2029
2061
|
/**
|
|
2030
2062
|
* Keyword-index abstraction. The strategy owns its own backing store
|
|
2031
2063
|
* (in-RAM MiniSearch vs on-disk FTS5) and is responsible for keeping it
|
|
@@ -2092,8 +2124,11 @@ interface IndexStrategy {
|
|
|
2092
2124
|
/**
|
|
2093
2125
|
* Create or verify the strategy's backing schema and run state changes.
|
|
2094
2126
|
* Called once by `createIndexStrategy`, before the strategy is installed.
|
|
2127
|
+
* `entriesExisted: false` marks a store `setup()` just created: FTS starts `live` with nothing to index.
|
|
2095
2128
|
*/
|
|
2096
|
-
init?(
|
|
2129
|
+
init?(opts?: {
|
|
2130
|
+
entriesExisted?: boolean;
|
|
2131
|
+
}): Promise<void>;
|
|
2097
2132
|
/**
|
|
2098
2133
|
* Apply every change recorded in the strategy's durable ledger, in bounded
|
|
2099
2134
|
* chunks. A strategy that implements this keeps itself consistent with
|
|
@@ -2102,9 +2137,7 @@ interface IndexStrategy {
|
|
|
2102
2137
|
* called from inside a `withTransactionAsync` callback; it opens its own
|
|
2103
2138
|
* transactions.
|
|
2104
2139
|
*/
|
|
2105
|
-
drain?(): Promise<void>;
|
|
2106
|
-
/** Rebuild entirely in SQL from the source tables; no rows pass through JS. */
|
|
2107
|
-
rebuildFromSource?(): Promise<void>;
|
|
2140
|
+
drain?(opts?: DrainOptions): Promise<void>;
|
|
2108
2141
|
}
|
|
2109
2142
|
|
|
2110
2143
|
interface ScoredRow {
|
|
@@ -2179,10 +2212,13 @@ declare class SearchService {
|
|
|
2179
2212
|
setIndexStrategy(strategy: IndexStrategy): void;
|
|
2180
2213
|
/** False while the installed strategy is the degraded UnavailableIndexStrategy (spec #280 Change 4). */
|
|
2181
2214
|
isKeywordAvailable(): boolean;
|
|
2215
|
+
/** True when the installed strategy drains a durable ledger (FTS5, or the degraded stand-in). */
|
|
2216
|
+
hasLedger(): boolean;
|
|
2182
2217
|
/**
|
|
2183
2218
|
* One serialized drain turn for strategies with a durable ledger. Like
|
|
2184
2219
|
* sync(), it never rejects: the keyword index is rebuildable, and a failed
|
|
2185
|
-
* drain leaves the ledger rows in place for the next turn.
|
|
2220
|
+
* drain leaves the ledger rows in place for the next turn. Resolves false
|
|
2221
|
+
* when the drain failed.
|
|
2186
2222
|
*/
|
|
2187
2223
|
private drainTurn;
|
|
2188
2224
|
/**
|
|
@@ -2192,8 +2228,17 @@ declare class SearchService {
|
|
|
2192
2228
|
* Rebuilds are serialized per instance and never reject: the keyword index
|
|
2193
2229
|
* is a rebuildable cache over SQLite, so degraded keyword search is the
|
|
2194
2230
|
* correct failure mode and killing the host process is not.
|
|
2231
|
+
*
|
|
2232
|
+
* With a ledger strategy, `sync()` runs one full quantum bounded by
|
|
2233
|
+
* `opts.deadline`; `sync(entityId)` is a write turn (ledger only).
|
|
2234
|
+
* `opts.ids` are the caller's touched ids: a ledger strategy drains them
|
|
2235
|
+
* first, to completion; MiniSearch ignores them and rebuilds the entity in
|
|
2236
|
+
* one scan.
|
|
2195
2237
|
*/
|
|
2196
|
-
sync(entityId?: string
|
|
2238
|
+
sync(entityId?: string, opts?: {
|
|
2239
|
+
deadline?: number;
|
|
2240
|
+
ids?: readonly string[];
|
|
2241
|
+
}): Promise<void>;
|
|
2197
2242
|
/**
|
|
2198
2243
|
* Re-indexes only `ids` for `entityId`: drops each from the index, then
|
|
2199
2244
|
* re-adds the ones still live in SQLite, so soft-deleted or missing ids end
|
|
@@ -2205,8 +2250,11 @@ declare class SearchService {
|
|
|
2205
2250
|
* — including on an empty `ids` list, which is a no-op only for an entity
|
|
2206
2251
|
* the index already tracks, and even then one that waits for rebuilds
|
|
2207
2252
|
* already queued on the chain.
|
|
2253
|
+
*
|
|
2254
|
+
* Resolves false only when a ledger drain failed: the caller's ids were not
|
|
2255
|
+
* applied (their ledger rows remain), so a caller holding them retries.
|
|
2208
2256
|
*/
|
|
2209
|
-
syncEntries(entityId: string, ids: Iterable<string>): Promise<
|
|
2257
|
+
syncEntries(entityId: string, ids: Iterable<string>): Promise<boolean>;
|
|
2210
2258
|
/**
|
|
2211
2259
|
* Forces the entity's next syncEntries to rebuild it in full. For writes core
|
|
2212
2260
|
* cannot index itself, such as upsertGraph inside a host transaction.
|
|
@@ -2217,8 +2265,11 @@ declare class SearchService {
|
|
|
2217
2265
|
* so only those entities are rebuilt. Each rebuild still takes its own turn
|
|
2218
2266
|
* on the sync chain, and like syncEntries this never rejects. With nothing
|
|
2219
2267
|
* stale it resolves at once, without waiting on work already on the chain.
|
|
2268
|
+
* Resolves false only when a ledger drain failed (see syncEntries).
|
|
2220
2269
|
*/
|
|
2221
|
-
syncStale(
|
|
2270
|
+
syncStale(opts?: {
|
|
2271
|
+
ids?: readonly string[];
|
|
2272
|
+
}): Promise<boolean>;
|
|
2222
2273
|
/**
|
|
2223
2274
|
* Clears the parsed vector cache. Useful for mid-loop flush guarantees
|
|
2224
2275
|
* or memory pressure evictions.
|
|
@@ -2810,7 +2861,8 @@ declare class IngestionService {
|
|
|
2810
2861
|
*
|
|
2811
2862
|
* @returns Counts: nodesWritten (validated nodes persisted), edgesWritten
|
|
2812
2863
|
* (manifest-valid edges persisted), superseded (prior facts soft-deleted
|
|
2813
|
-
* plus prior source-ref edges hard-deleted)
|
|
2864
|
+
* plus prior source-ref edges hard-deleted), and supersededFactIds (the
|
|
2865
|
+
* ids of those soft-deleted facts, for the caller's post-commit index sync).
|
|
2814
2866
|
*
|
|
2815
2867
|
* Node-ownership pre-flight (spec §3, REQ-GRAPH-01): the first statement
|
|
2816
2868
|
* is `assertGraphNodeOwnership(entityId, params.nodes, tx)`, which runs
|
|
@@ -2851,6 +2903,7 @@ declare class IngestionService {
|
|
|
2851
2903
|
nodesWritten: number;
|
|
2852
2904
|
edgesWritten: number;
|
|
2853
2905
|
superseded: number;
|
|
2906
|
+
supersededFactIds: string[];
|
|
2854
2907
|
}>;
|
|
2855
2908
|
/**
|
|
2856
2909
|
* Full supersession + ownership path: identical to the pre-issue-#92 behavior
|
|
@@ -3515,6 +3568,28 @@ declare class WikiMemory {
|
|
|
3515
3568
|
* If `NODE_ENV` is not `"test"`, emits a single `console.warn` per instance (skipped when `process` is undefined).
|
|
3516
3569
|
*/
|
|
3517
3570
|
get __testAccess(): WikiMemoryTestAccess;
|
|
3571
|
+
/** Max upsertGraph node ids held for their post-commit sync (spec #280 id threading). */
|
|
3572
|
+
static readonly UPSERT_ID_STASH_CAP = 10000;
|
|
3573
|
+
/**
|
|
3574
|
+
* upsertGraph node and superseded-fact ids per entity, awaiting syncSearchIndex(), each with the
|
|
3575
|
+
* generation of its latest stash. Ids leave the stash only once a drain
|
|
3576
|
+
* succeeded, so a failed drain retries them next call.
|
|
3577
|
+
*/
|
|
3578
|
+
private upsertIdStash;
|
|
3579
|
+
/** Total ids across upsertIdStash, kept in step so the cap check is O(1). */
|
|
3580
|
+
private upsertIdStashSize;
|
|
3581
|
+
/** Bumped per stashed id; a re-stash during an in-flight drain outlives that drain's drop. */
|
|
3582
|
+
private upsertIdStashGen;
|
|
3583
|
+
private stashUpsertIds;
|
|
3584
|
+
/** Snapshot of the stash (one entity, or all) with generations, without removing anything. */
|
|
3585
|
+
private peekStashedIds;
|
|
3586
|
+
/**
|
|
3587
|
+
* Removes a drained snapshot. An id re-stashed after the peek has a newer
|
|
3588
|
+
* generation and stays: the drain may have run before that write committed.
|
|
3589
|
+
*/
|
|
3590
|
+
private dropStashedIds;
|
|
3591
|
+
/** `config.setupBudgetMs` or the default, validated: a positive finite number. */
|
|
3592
|
+
private setupBudgetMs;
|
|
3518
3593
|
private reinitSearch;
|
|
3519
3594
|
/** Monotonic time before which a no-arg syncSearchIndex() skips the re-init (0 = no cooldown). */
|
|
3520
3595
|
private reinitRetryAt;
|
|
@@ -3530,6 +3605,11 @@ declare class WikiMemory {
|
|
|
3530
3605
|
* Pass `{ migrations: 'refuse' }` from inside a writer lease: pending one-time
|
|
3531
3606
|
* work then throws WikiMigrationRequiredError before any mutation, and the
|
|
3532
3607
|
* host runs a plain `setup()` outside the lease.
|
|
3608
|
+
*
|
|
3609
|
+
* Keyword-index catch-up work is bounded by `config.setupBudgetMs`; anything
|
|
3610
|
+
* left converges on later opens and no-arg `syncSearchIndex()` calls. Not
|
|
3611
|
+
* bounded: an index reset (tokenizer change, re-attach after detach, a lost
|
|
3612
|
+
* or inconsistent index), which runs as one unchunked transaction.
|
|
3533
3613
|
*/
|
|
3534
3614
|
setup(opts?: {
|
|
3535
3615
|
migrations?: MigrationPolicy;
|
|
@@ -3716,14 +3796,18 @@ declare class WikiMemory {
|
|
|
3716
3796
|
* commit, so without this the nodes stay out of keyword, hybrid and
|
|
3717
3797
|
* fallback retrieval until the entity's next core write.
|
|
3718
3798
|
*
|
|
3719
|
-
* With `entityId
|
|
3720
|
-
*
|
|
3721
|
-
*
|
|
3722
|
-
*
|
|
3723
|
-
*
|
|
3724
|
-
*
|
|
3725
|
-
*
|
|
3726
|
-
*
|
|
3799
|
+
* With `entityId`: drains that entity's pending `upsertGraph` ids (its new
|
|
3800
|
+
* nodes and the facts they superseded) first, to completion, then at most
|
|
3801
|
+
* one more ledger chunk — so its new nodes are searchable, and the
|
|
3802
|
+
* superseded facts gone, when the call resolves, under any backlog. Without an
|
|
3803
|
+
* argument: drains every stashed `upsertGraph` id across entities first,
|
|
3804
|
+
* then runs one keyword-index quantum bounded by `config.setupBudgetMs`
|
|
3805
|
+
* (backlog drain, then rebuild work while the index is rebuilding). Hosts
|
|
3806
|
+
* with a long-lived process should call the no-arg form on their own
|
|
3807
|
+
* schedule: that is what converges a rebuilding index. While keyword search
|
|
3808
|
+
* is unavailable it first retries the index init; after a failed attempt it
|
|
3809
|
+
* waits at least 5 s, doubling per consecutive failure up to 5 min (longer
|
|
3810
|
+
* when an attempt is itself slow), before retrying again.
|
|
3727
3811
|
*
|
|
3728
3812
|
* Call only after the host's transaction commits: called inside it, the
|
|
3729
3813
|
* rebuild may index rows that later roll back, or miss them and clear the
|
|
@@ -3740,6 +3824,12 @@ declare class WikiMemory {
|
|
|
3740
3824
|
* @throws {TypeError} when `entityId` is given but is not a non-empty string.
|
|
3741
3825
|
*/
|
|
3742
3826
|
syncSearchIndex(entityId?: string): Promise<void>;
|
|
3827
|
+
/**
|
|
3828
|
+
* True when a sync applied the stashed ids. While keyword search is
|
|
3829
|
+
* unavailable the stand-in strategy's drain is a no-op that reports success,
|
|
3830
|
+
* so the ids stay stashed for the first sync after a re-init (#284 review).
|
|
3831
|
+
*/
|
|
3832
|
+
private syncDrained;
|
|
3743
3833
|
exportDump(entityIds?: string[]): Promise<MemoryDump>;
|
|
3744
3834
|
/** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */
|
|
3745
3835
|
getEntitySummary(entityId: string): Promise<string | null>;
|
|
@@ -3805,7 +3895,10 @@ declare class WikiMemory {
|
|
|
3805
3895
|
* post-commit work (search sync, embedding, cache eviction). After the
|
|
3806
3896
|
* transaction commits, call `syncSearchIndex(entityId)` — or
|
|
3807
3897
|
* `syncSearchIndex()` after writing several entities in one transaction —
|
|
3808
|
-
* to make the new nodes keyword-searchable
|
|
3898
|
+
* to make the new nodes keyword-searchable: both forms drain this call's node ids
|
|
3899
|
+
* first, to completion, so the nodes are searchable under any backlog (up to
|
|
3900
|
+
* `WikiMemory.UPSERT_ID_STASH_CAP` pending ids; beyond that they converge with
|
|
3901
|
+
* the backlog). Embeddings still come from the maintenance
|
|
3809
3902
|
* sweep (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,
|
|
3810
3903
|
* scoped via `listEntityIds`).
|
|
3811
3904
|
*
|
|
@@ -379,6 +379,19 @@ interface WikiConfig {
|
|
|
379
379
|
* @default 'allow'
|
|
380
380
|
*/
|
|
381
381
|
migrations?: MigrationPolicy;
|
|
382
|
+
/**
|
|
383
|
+
* Wall-time budget (ms) for each keyword-index quantum: one per `setup()`
|
|
384
|
+
* (shared by the whole open — the deadline is captured when setup() starts)
|
|
385
|
+
* and one per no-arg `syncSearchIndex()`. Checked between chunk
|
|
386
|
+
* transactions, so one quantum can overrun it by up to two chunks. Ids a
|
|
387
|
+
* write stashed for the call (see `upsertGraph`) drain before the quantum
|
|
388
|
+
* and outside the budget. An index reset runs as one unchunked transaction and is
|
|
389
|
+
* not bounded by it either.
|
|
390
|
+
* Convergence of a large backlog or rebuild continues on later opens and
|
|
391
|
+
* `syncSearchIndex()` calls. Must be a positive finite number.
|
|
392
|
+
* @default 1500 (DEFAULT_SETUP_BUDGET_MS)
|
|
393
|
+
*/
|
|
394
|
+
setupBudgetMs?: number;
|
|
382
395
|
}
|
|
383
396
|
interface ReadOptions {
|
|
384
397
|
maxResults?: number;
|
|
@@ -2026,6 +2039,25 @@ interface IndexSearchResult {
|
|
|
2026
2039
|
*/
|
|
2027
2040
|
entity_id: string;
|
|
2028
2041
|
}
|
|
2042
|
+
/** One drain turn's shape (spec #280 Change 3 "drain interface"). */
|
|
2043
|
+
interface DrainOptions {
|
|
2044
|
+
/** `monotonicNow()` timestamp, checked between chunk transactions. Full mode only; default now + the strategy's budget. */
|
|
2045
|
+
deadline?: number;
|
|
2046
|
+
/**
|
|
2047
|
+
* `'ledger'` (write turns): `ids` to completion, then at most ONE foreign
|
|
2048
|
+
* chunk. `'full'` (setup(), no-arg syncSearchIndex()): `ids`, then the
|
|
2049
|
+
* ledger until the deadline, then rebuild work. Default `'full'`.
|
|
2050
|
+
*/
|
|
2051
|
+
mode?: 'ledger' | 'full';
|
|
2052
|
+
/**
|
|
2053
|
+
* The caller's own ledger ids: drained first, to completion, ≤500 per
|
|
2054
|
+
* transaction. Not deadline-bound: the cost is proportional to a write the
|
|
2055
|
+
* caller already made.
|
|
2056
|
+
*/
|
|
2057
|
+
ids?: readonly string[];
|
|
2058
|
+
/** With empty `ids` in ledger mode, the one foreign chunk is `fts_pending WHERE entity_id = ?`. */
|
|
2059
|
+
entityId?: string;
|
|
2060
|
+
}
|
|
2029
2061
|
/**
|
|
2030
2062
|
* Keyword-index abstraction. The strategy owns its own backing store
|
|
2031
2063
|
* (in-RAM MiniSearch vs on-disk FTS5) and is responsible for keeping it
|
|
@@ -2092,8 +2124,11 @@ interface IndexStrategy {
|
|
|
2092
2124
|
/**
|
|
2093
2125
|
* Create or verify the strategy's backing schema and run state changes.
|
|
2094
2126
|
* Called once by `createIndexStrategy`, before the strategy is installed.
|
|
2127
|
+
* `entriesExisted: false` marks a store `setup()` just created: FTS starts `live` with nothing to index.
|
|
2095
2128
|
*/
|
|
2096
|
-
init?(
|
|
2129
|
+
init?(opts?: {
|
|
2130
|
+
entriesExisted?: boolean;
|
|
2131
|
+
}): Promise<void>;
|
|
2097
2132
|
/**
|
|
2098
2133
|
* Apply every change recorded in the strategy's durable ledger, in bounded
|
|
2099
2134
|
* chunks. A strategy that implements this keeps itself consistent with
|
|
@@ -2102,9 +2137,7 @@ interface IndexStrategy {
|
|
|
2102
2137
|
* called from inside a `withTransactionAsync` callback; it opens its own
|
|
2103
2138
|
* transactions.
|
|
2104
2139
|
*/
|
|
2105
|
-
drain?(): Promise<void>;
|
|
2106
|
-
/** Rebuild entirely in SQL from the source tables; no rows pass through JS. */
|
|
2107
|
-
rebuildFromSource?(): Promise<void>;
|
|
2140
|
+
drain?(opts?: DrainOptions): Promise<void>;
|
|
2108
2141
|
}
|
|
2109
2142
|
|
|
2110
2143
|
interface ScoredRow {
|
|
@@ -2179,10 +2212,13 @@ declare class SearchService {
|
|
|
2179
2212
|
setIndexStrategy(strategy: IndexStrategy): void;
|
|
2180
2213
|
/** False while the installed strategy is the degraded UnavailableIndexStrategy (spec #280 Change 4). */
|
|
2181
2214
|
isKeywordAvailable(): boolean;
|
|
2215
|
+
/** True when the installed strategy drains a durable ledger (FTS5, or the degraded stand-in). */
|
|
2216
|
+
hasLedger(): boolean;
|
|
2182
2217
|
/**
|
|
2183
2218
|
* One serialized drain turn for strategies with a durable ledger. Like
|
|
2184
2219
|
* sync(), it never rejects: the keyword index is rebuildable, and a failed
|
|
2185
|
-
* drain leaves the ledger rows in place for the next turn.
|
|
2220
|
+
* drain leaves the ledger rows in place for the next turn. Resolves false
|
|
2221
|
+
* when the drain failed.
|
|
2186
2222
|
*/
|
|
2187
2223
|
private drainTurn;
|
|
2188
2224
|
/**
|
|
@@ -2192,8 +2228,17 @@ declare class SearchService {
|
|
|
2192
2228
|
* Rebuilds are serialized per instance and never reject: the keyword index
|
|
2193
2229
|
* is a rebuildable cache over SQLite, so degraded keyword search is the
|
|
2194
2230
|
* correct failure mode and killing the host process is not.
|
|
2231
|
+
*
|
|
2232
|
+
* With a ledger strategy, `sync()` runs one full quantum bounded by
|
|
2233
|
+
* `opts.deadline`; `sync(entityId)` is a write turn (ledger only).
|
|
2234
|
+
* `opts.ids` are the caller's touched ids: a ledger strategy drains them
|
|
2235
|
+
* first, to completion; MiniSearch ignores them and rebuilds the entity in
|
|
2236
|
+
* one scan.
|
|
2195
2237
|
*/
|
|
2196
|
-
sync(entityId?: string
|
|
2238
|
+
sync(entityId?: string, opts?: {
|
|
2239
|
+
deadline?: number;
|
|
2240
|
+
ids?: readonly string[];
|
|
2241
|
+
}): Promise<void>;
|
|
2197
2242
|
/**
|
|
2198
2243
|
* Re-indexes only `ids` for `entityId`: drops each from the index, then
|
|
2199
2244
|
* re-adds the ones still live in SQLite, so soft-deleted or missing ids end
|
|
@@ -2205,8 +2250,11 @@ declare class SearchService {
|
|
|
2205
2250
|
* — including on an empty `ids` list, which is a no-op only for an entity
|
|
2206
2251
|
* the index already tracks, and even then one that waits for rebuilds
|
|
2207
2252
|
* already queued on the chain.
|
|
2253
|
+
*
|
|
2254
|
+
* Resolves false only when a ledger drain failed: the caller's ids were not
|
|
2255
|
+
* applied (their ledger rows remain), so a caller holding them retries.
|
|
2208
2256
|
*/
|
|
2209
|
-
syncEntries(entityId: string, ids: Iterable<string>): Promise<
|
|
2257
|
+
syncEntries(entityId: string, ids: Iterable<string>): Promise<boolean>;
|
|
2210
2258
|
/**
|
|
2211
2259
|
* Forces the entity's next syncEntries to rebuild it in full. For writes core
|
|
2212
2260
|
* cannot index itself, such as upsertGraph inside a host transaction.
|
|
@@ -2217,8 +2265,11 @@ declare class SearchService {
|
|
|
2217
2265
|
* so only those entities are rebuilt. Each rebuild still takes its own turn
|
|
2218
2266
|
* on the sync chain, and like syncEntries this never rejects. With nothing
|
|
2219
2267
|
* stale it resolves at once, without waiting on work already on the chain.
|
|
2268
|
+
* Resolves false only when a ledger drain failed (see syncEntries).
|
|
2220
2269
|
*/
|
|
2221
|
-
syncStale(
|
|
2270
|
+
syncStale(opts?: {
|
|
2271
|
+
ids?: readonly string[];
|
|
2272
|
+
}): Promise<boolean>;
|
|
2222
2273
|
/**
|
|
2223
2274
|
* Clears the parsed vector cache. Useful for mid-loop flush guarantees
|
|
2224
2275
|
* or memory pressure evictions.
|
|
@@ -2810,7 +2861,8 @@ declare class IngestionService {
|
|
|
2810
2861
|
*
|
|
2811
2862
|
* @returns Counts: nodesWritten (validated nodes persisted), edgesWritten
|
|
2812
2863
|
* (manifest-valid edges persisted), superseded (prior facts soft-deleted
|
|
2813
|
-
* plus prior source-ref edges hard-deleted)
|
|
2864
|
+
* plus prior source-ref edges hard-deleted), and supersededFactIds (the
|
|
2865
|
+
* ids of those soft-deleted facts, for the caller's post-commit index sync).
|
|
2814
2866
|
*
|
|
2815
2867
|
* Node-ownership pre-flight (spec §3, REQ-GRAPH-01): the first statement
|
|
2816
2868
|
* is `assertGraphNodeOwnership(entityId, params.nodes, tx)`, which runs
|
|
@@ -2851,6 +2903,7 @@ declare class IngestionService {
|
|
|
2851
2903
|
nodesWritten: number;
|
|
2852
2904
|
edgesWritten: number;
|
|
2853
2905
|
superseded: number;
|
|
2906
|
+
supersededFactIds: string[];
|
|
2854
2907
|
}>;
|
|
2855
2908
|
/**
|
|
2856
2909
|
* Full supersession + ownership path: identical to the pre-issue-#92 behavior
|
|
@@ -3515,6 +3568,28 @@ declare class WikiMemory {
|
|
|
3515
3568
|
* If `NODE_ENV` is not `"test"`, emits a single `console.warn` per instance (skipped when `process` is undefined).
|
|
3516
3569
|
*/
|
|
3517
3570
|
get __testAccess(): WikiMemoryTestAccess;
|
|
3571
|
+
/** Max upsertGraph node ids held for their post-commit sync (spec #280 id threading). */
|
|
3572
|
+
static readonly UPSERT_ID_STASH_CAP = 10000;
|
|
3573
|
+
/**
|
|
3574
|
+
* upsertGraph node and superseded-fact ids per entity, awaiting syncSearchIndex(), each with the
|
|
3575
|
+
* generation of its latest stash. Ids leave the stash only once a drain
|
|
3576
|
+
* succeeded, so a failed drain retries them next call.
|
|
3577
|
+
*/
|
|
3578
|
+
private upsertIdStash;
|
|
3579
|
+
/** Total ids across upsertIdStash, kept in step so the cap check is O(1). */
|
|
3580
|
+
private upsertIdStashSize;
|
|
3581
|
+
/** Bumped per stashed id; a re-stash during an in-flight drain outlives that drain's drop. */
|
|
3582
|
+
private upsertIdStashGen;
|
|
3583
|
+
private stashUpsertIds;
|
|
3584
|
+
/** Snapshot of the stash (one entity, or all) with generations, without removing anything. */
|
|
3585
|
+
private peekStashedIds;
|
|
3586
|
+
/**
|
|
3587
|
+
* Removes a drained snapshot. An id re-stashed after the peek has a newer
|
|
3588
|
+
* generation and stays: the drain may have run before that write committed.
|
|
3589
|
+
*/
|
|
3590
|
+
private dropStashedIds;
|
|
3591
|
+
/** `config.setupBudgetMs` or the default, validated: a positive finite number. */
|
|
3592
|
+
private setupBudgetMs;
|
|
3518
3593
|
private reinitSearch;
|
|
3519
3594
|
/** Monotonic time before which a no-arg syncSearchIndex() skips the re-init (0 = no cooldown). */
|
|
3520
3595
|
private reinitRetryAt;
|
|
@@ -3530,6 +3605,11 @@ declare class WikiMemory {
|
|
|
3530
3605
|
* Pass `{ migrations: 'refuse' }` from inside a writer lease: pending one-time
|
|
3531
3606
|
* work then throws WikiMigrationRequiredError before any mutation, and the
|
|
3532
3607
|
* host runs a plain `setup()` outside the lease.
|
|
3608
|
+
*
|
|
3609
|
+
* Keyword-index catch-up work is bounded by `config.setupBudgetMs`; anything
|
|
3610
|
+
* left converges on later opens and no-arg `syncSearchIndex()` calls. Not
|
|
3611
|
+
* bounded: an index reset (tokenizer change, re-attach after detach, a lost
|
|
3612
|
+
* or inconsistent index), which runs as one unchunked transaction.
|
|
3533
3613
|
*/
|
|
3534
3614
|
setup(opts?: {
|
|
3535
3615
|
migrations?: MigrationPolicy;
|
|
@@ -3716,14 +3796,18 @@ declare class WikiMemory {
|
|
|
3716
3796
|
* commit, so without this the nodes stay out of keyword, hybrid and
|
|
3717
3797
|
* fallback retrieval until the entity's next core write.
|
|
3718
3798
|
*
|
|
3719
|
-
* With `entityId
|
|
3720
|
-
*
|
|
3721
|
-
*
|
|
3722
|
-
*
|
|
3723
|
-
*
|
|
3724
|
-
*
|
|
3725
|
-
*
|
|
3726
|
-
*
|
|
3799
|
+
* With `entityId`: drains that entity's pending `upsertGraph` ids (its new
|
|
3800
|
+
* nodes and the facts they superseded) first, to completion, then at most
|
|
3801
|
+
* one more ledger chunk — so its new nodes are searchable, and the
|
|
3802
|
+
* superseded facts gone, when the call resolves, under any backlog. Without an
|
|
3803
|
+
* argument: drains every stashed `upsertGraph` id across entities first,
|
|
3804
|
+
* then runs one keyword-index quantum bounded by `config.setupBudgetMs`
|
|
3805
|
+
* (backlog drain, then rebuild work while the index is rebuilding). Hosts
|
|
3806
|
+
* with a long-lived process should call the no-arg form on their own
|
|
3807
|
+
* schedule: that is what converges a rebuilding index. While keyword search
|
|
3808
|
+
* is unavailable it first retries the index init; after a failed attempt it
|
|
3809
|
+
* waits at least 5 s, doubling per consecutive failure up to 5 min (longer
|
|
3810
|
+
* when an attempt is itself slow), before retrying again.
|
|
3727
3811
|
*
|
|
3728
3812
|
* Call only after the host's transaction commits: called inside it, the
|
|
3729
3813
|
* rebuild may index rows that later roll back, or miss them and clear the
|
|
@@ -3740,6 +3824,12 @@ declare class WikiMemory {
|
|
|
3740
3824
|
* @throws {TypeError} when `entityId` is given but is not a non-empty string.
|
|
3741
3825
|
*/
|
|
3742
3826
|
syncSearchIndex(entityId?: string): Promise<void>;
|
|
3827
|
+
/**
|
|
3828
|
+
* True when a sync applied the stashed ids. While keyword search is
|
|
3829
|
+
* unavailable the stand-in strategy's drain is a no-op that reports success,
|
|
3830
|
+
* so the ids stay stashed for the first sync after a re-init (#284 review).
|
|
3831
|
+
*/
|
|
3832
|
+
private syncDrained;
|
|
3743
3833
|
exportDump(entityIds?: string[]): Promise<MemoryDump>;
|
|
3744
3834
|
/** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */
|
|
3745
3835
|
getEntitySummary(entityId: string): Promise<string | null>;
|
|
@@ -3805,7 +3895,10 @@ declare class WikiMemory {
|
|
|
3805
3895
|
* post-commit work (search sync, embedding, cache eviction). After the
|
|
3806
3896
|
* transaction commits, call `syncSearchIndex(entityId)` — or
|
|
3807
3897
|
* `syncSearchIndex()` after writing several entities in one transaction —
|
|
3808
|
-
* to make the new nodes keyword-searchable
|
|
3898
|
+
* to make the new nodes keyword-searchable: both forms drain this call's node ids
|
|
3899
|
+
* first, to completion, so the nodes are searchable under any backlog (up to
|
|
3900
|
+
* `WikiMemory.UPSERT_ID_STASH_CAP` pending ids; beyond that they converge with
|
|
3901
|
+
* the backlog). Embeddings still come from the maintenance
|
|
3809
3902
|
* sweep (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,
|
|
3810
3903
|
* scoped via `listEntityIds`).
|
|
3811
3904
|
*
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { aG as EmbeddingService, aH as ImportExportService, aI as IngestionService, aJ as JobManager, aJ as JobManagerType, aK as MaintenanceService, aL as RetrievalService, aM as SearchService, aM as SearchServiceType, at as WikiMemoryTestAccess, aN as WriteService } from './testing-
|
|
1
|
+
export { aG as EmbeddingService, aH as ImportExportService, aI as IngestionService, aJ as JobManager, aJ as JobManagerType, aK as MaintenanceService, aL as RetrievalService, aM as SearchService, aM as SearchServiceType, at as WikiMemoryTestAccess, aN as WriteService } from './testing-CqsXv2_l.mjs';
|
|
2
2
|
import '@equationalapplications/core-okf';
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { aG as EmbeddingService, aH as ImportExportService, aI as IngestionService, aJ as JobManager, aJ as JobManagerType, aK as MaintenanceService, aL as RetrievalService, aM as SearchService, aM as SearchServiceType, at as WikiMemoryTestAccess, aN as WriteService } from './testing-
|
|
1
|
+
export { aG as EmbeddingService, aH as ImportExportService, aI as IngestionService, aJ as JobManager, aJ as JobManagerType, aK as MaintenanceService, aL as RetrievalService, aM as SearchService, aM as SearchServiceType, at as WikiMemoryTestAccess, aN as WriteService } from './testing-CqsXv2_l.js';
|
|
2
2
|
import '@equationalapplications/core-okf';
|