@descryy/core 0.1.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/LICENSE +21 -0
- package/dist/capabilities/index.d.ts +3 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +2 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/preconditions.d.ts +99 -0
- package/dist/capabilities/preconditions.d.ts.map +1 -0
- package/dist/capabilities/preconditions.js +94 -0
- package/dist/capabilities/preconditions.js.map +1 -0
- package/dist/contracts/engine.d.ts +90 -0
- package/dist/contracts/engine.d.ts.map +1 -0
- package/dist/contracts/engine.js +291 -0
- package/dist/contracts/engine.js.map +1 -0
- package/dist/contracts/index.d.ts +9 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +5 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/orphans.d.ts +96 -0
- package/dist/contracts/orphans.d.ts.map +1 -0
- package/dist/contracts/orphans.js +241 -0
- package/dist/contracts/orphans.js.map +1 -0
- package/dist/contracts/paths.d.ts +132 -0
- package/dist/contracts/paths.d.ts.map +1 -0
- package/dist/contracts/paths.js +245 -0
- package/dist/contracts/paths.js.map +1 -0
- package/dist/contracts/shapes.d.ts +99 -0
- package/dist/contracts/shapes.d.ts.map +1 -0
- package/dist/contracts/shapes.js +196 -0
- package/dist/contracts/shapes.js.map +1 -0
- package/dist/governance/budget.d.ts +89 -0
- package/dist/governance/budget.d.ts.map +1 -0
- package/dist/governance/budget.js +101 -0
- package/dist/governance/budget.js.map +1 -0
- package/dist/governance/candidate-boundary.d.ts +49 -0
- package/dist/governance/candidate-boundary.d.ts.map +1 -0
- package/dist/governance/candidate-boundary.js +51 -0
- package/dist/governance/candidate-boundary.js.map +1 -0
- package/dist/governance/escalation.d.ts +63 -0
- package/dist/governance/escalation.d.ts.map +1 -0
- package/dist/governance/escalation.js +72 -0
- package/dist/governance/escalation.js.map +1 -0
- package/dist/governance/fact-boundary.d.ts +77 -0
- package/dist/governance/fact-boundary.d.ts.map +1 -0
- package/dist/governance/fact-boundary.js +91 -0
- package/dist/governance/fact-boundary.js.map +1 -0
- package/dist/governance/finding-funnel.d.ts +109 -0
- package/dist/governance/finding-funnel.d.ts.map +1 -0
- package/dist/governance/finding-funnel.js +137 -0
- package/dist/governance/finding-funnel.js.map +1 -0
- package/dist/governance/index.d.ts +11 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +6 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/graph/build.d.ts +127 -0
- package/dist/graph/build.d.ts.map +1 -0
- package/dist/graph/build.js +0 -0
- package/dist/graph/build.js.map +1 -0
- package/dist/graph/cross-language.d.ts +70 -0
- package/dist/graph/cross-language.d.ts.map +1 -0
- package/dist/graph/cross-language.js +104 -0
- package/dist/graph/cross-language.js.map +1 -0
- package/dist/graph/index.d.ts +11 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +6 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/merge.d.ts +95 -0
- package/dist/graph/merge.d.ts.map +1 -0
- package/dist/graph/merge.js +131 -0
- package/dist/graph/merge.js.map +1 -0
- package/dist/graph/persist.d.ts +42 -0
- package/dist/graph/persist.d.ts.map +1 -0
- package/dist/graph/persist.js +52 -0
- package/dist/graph/persist.js.map +1 -0
- package/dist/graph/runtime-confirmation.d.ts +169 -0
- package/dist/graph/runtime-confirmation.d.ts.map +1 -0
- package/dist/graph/runtime-confirmation.js +318 -0
- package/dist/graph/runtime-confirmation.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/index.d.ts +5 -0
- package/dist/ledger/index.d.ts.map +1 -0
- package/dist/ledger/index.js +3 -0
- package/dist/ledger/index.js.map +1 -0
- package/dist/ledger/mint.d.ts +81 -0
- package/dist/ledger/mint.d.ts.map +1 -0
- package/dist/ledger/mint.js +138 -0
- package/dist/ledger/mint.js.map +1 -0
- package/dist/ledger/resolve.d.ts +124 -0
- package/dist/ledger/resolve.d.ts.map +1 -0
- package/dist/ledger/resolve.js +290 -0
- package/dist/ledger/resolve.js.map +1 -0
- package/dist/multipr/fingerprint.d.ts +56 -0
- package/dist/multipr/fingerprint.d.ts.map +1 -0
- package/dist/multipr/fingerprint.js +169 -0
- package/dist/multipr/fingerprint.js.map +1 -0
- package/dist/multipr/hidden-dependency.d.ts +120 -0
- package/dist/multipr/hidden-dependency.d.ts.map +1 -0
- package/dist/multipr/hidden-dependency.js +185 -0
- package/dist/multipr/hidden-dependency.js.map +1 -0
- package/dist/multipr/index.d.ts +14 -0
- package/dist/multipr/index.d.ts.map +1 -0
- package/dist/multipr/index.js +8 -0
- package/dist/multipr/index.js.map +1 -0
- package/dist/multipr/mechanical.d.ts +239 -0
- package/dist/multipr/mechanical.d.ts.map +1 -0
- package/dist/multipr/mechanical.js +333 -0
- package/dist/multipr/mechanical.js.map +1 -0
- package/dist/multipr/migration-heads.d.ts +160 -0
- package/dist/multipr/migration-heads.d.ts.map +1 -0
- package/dist/multipr/migration-heads.js +212 -0
- package/dist/multipr/migration-heads.js.map +1 -0
- package/dist/multipr/overlap.d.ts +186 -0
- package/dist/multipr/overlap.d.ts.map +1 -0
- package/dist/multipr/overlap.js +254 -0
- package/dist/multipr/overlap.js.map +1 -0
- package/dist/multipr/scope-store.d.ts +105 -0
- package/dist/multipr/scope-store.d.ts.map +1 -0
- package/dist/multipr/scope-store.js +182 -0
- package/dist/multipr/scope-store.js.map +1 -0
- package/dist/multipr/superseded.d.ts +133 -0
- package/dist/multipr/superseded.d.ts.map +1 -0
- package/dist/multipr/superseded.js +128 -0
- package/dist/multipr/superseded.js.map +1 -0
- package/dist/query/confirmed-facts.d.ts +56 -0
- package/dist/query/confirmed-facts.d.ts.map +1 -0
- package/dist/query/confirmed-facts.js +64 -0
- package/dist/query/confirmed-facts.js.map +1 -0
- package/dist/query/declared-value-closure.d.ts +126 -0
- package/dist/query/declared-value-closure.d.ts.map +1 -0
- package/dist/query/declared-value-closure.js +156 -0
- package/dist/query/declared-value-closure.js.map +1 -0
- package/dist/query/index.d.ts +28 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +15 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/memory.d.ts +20 -0
- package/dist/query/memory.d.ts.map +1 -0
- package/dist/query/memory.js +55 -0
- package/dist/query/memory.js.map +1 -0
- package/dist/query/provider.d.ts +127 -0
- package/dist/query/provider.d.ts.map +1 -0
- package/dist/query/provider.js +54 -0
- package/dist/query/provider.js.map +1 -0
- package/dist/query/queries.d.ts +119 -0
- package/dist/query/queries.d.ts.map +1 -0
- package/dist/query/queries.js +267 -0
- package/dist/query/queries.js.map +1 -0
- package/dist/query/refusal-fetch.d.ts +114 -0
- package/dist/query/refusal-fetch.d.ts.map +1 -0
- package/dist/query/refusal-fetch.js +200 -0
- package/dist/query/refusal-fetch.js.map +1 -0
- package/dist/query/refusal-questions.d.ts +123 -0
- package/dist/query/refusal-questions.d.ts.map +1 -0
- package/dist/query/refusal-questions.js +122 -0
- package/dist/query/refusal-questions.js.map +1 -0
- package/dist/query/root-cause-score.d.ts +218 -0
- package/dist/query/root-cause-score.d.ts.map +1 -0
- package/dist/query/root-cause-score.js +251 -0
- package/dist/query/root-cause-score.js.map +1 -0
- package/dist/query/row-closure-picture.d.ts +108 -0
- package/dist/query/row-closure-picture.d.ts.map +1 -0
- package/dist/query/row-closure-picture.js +131 -0
- package/dist/query/row-closure-picture.js.map +1 -0
- package/dist/query/similar-incidents.d.ts +76 -0
- package/dist/query/similar-incidents.d.ts.map +1 -0
- package/dist/query/similar-incidents.js +169 -0
- package/dist/query/similar-incidents.js.map +1 -0
- package/dist/query/sqlite.d.ts +13 -0
- package/dist/query/sqlite.d.ts.map +1 -0
- package/dist/query/sqlite.js +54 -0
- package/dist/query/sqlite.js.map +1 -0
- package/dist/query/traverse.d.ts +110 -0
- package/dist/query/traverse.d.ts.map +1 -0
- package/dist/query/traverse.js +0 -0
- package/dist/query/traverse.js.map +1 -0
- package/dist/query/unresolved.d.ts +195 -0
- package/dist/query/unresolved.d.ts.map +1 -0
- package/dist/query/unresolved.js +225 -0
- package/dist/query/unresolved.js.map +1 -0
- package/dist/query/verification-status.d.ts +134 -0
- package/dist/query/verification-status.d.ts.map +1 -0
- package/dist/query/verification-status.js +163 -0
- package/dist/query/verification-status.js.map +1 -0
- package/dist/recording/index.d.ts +26 -0
- package/dist/recording/index.d.ts.map +1 -0
- package/dist/recording/index.js +30 -0
- package/dist/recording/index.js.map +1 -0
- package/dist/recording/migrate.d.ts +22 -0
- package/dist/recording/migrate.d.ts.map +1 -0
- package/dist/recording/migrate.js +51 -0
- package/dist/recording/migrate.js.map +1 -0
- package/dist/recording/reader.d.ts +27 -0
- package/dist/recording/reader.d.ts.map +1 -0
- package/dist/recording/reader.js +55 -0
- package/dist/recording/reader.js.map +1 -0
- package/dist/recording/redact.d.ts +63 -0
- package/dist/recording/redact.d.ts.map +1 -0
- package/dist/recording/redact.js +98 -0
- package/dist/recording/redact.js.map +1 -0
- package/dist/recording/schema.d.ts +41 -0
- package/dist/recording/schema.d.ts.map +1 -0
- package/dist/recording/schema.js +104 -0
- package/dist/recording/schema.js.map +1 -0
- package/dist/recording/writer.d.ts +120 -0
- package/dist/recording/writer.d.ts.map +1 -0
- package/dist/recording/writer.js +81 -0
- package/dist/recording/writer.js.map +1 -0
- package/dist/scoping/fanout.d.ts +86 -0
- package/dist/scoping/fanout.d.ts.map +1 -0
- package/dist/scoping/fanout.js +95 -0
- package/dist/scoping/fanout.js.map +1 -0
- package/dist/scoping/index.d.ts +10 -0
- package/dist/scoping/index.d.ts.map +1 -0
- package/dist/scoping/index.js +6 -0
- package/dist/scoping/index.js.map +1 -0
- package/dist/scoping/score.d.ts +83 -0
- package/dist/scoping/score.d.ts.map +1 -0
- package/dist/scoping/score.js +125 -0
- package/dist/scoping/score.js.map +1 -0
- package/dist/scoping/tiers.d.ts +32 -0
- package/dist/scoping/tiers.d.ts.map +1 -0
- package/dist/scoping/tiers.js +35 -0
- package/dist/scoping/tiers.js.map +1 -0
- package/dist/scoping/traverse.d.ts +60 -0
- package/dist/scoping/traverse.d.ts.map +1 -0
- package/dist/scoping/traverse.js +172 -0
- package/dist/scoping/traverse.js.map +1 -0
- package/dist/scoping/weights.d.ts +97 -0
- package/dist/scoping/weights.d.ts.map +1 -0
- package/dist/scoping/weights.js +167 -0
- package/dist/scoping/weights.js.map +1 -0
- package/dist/sources/git/diff.d.ts +53 -0
- package/dist/sources/git/diff.d.ts.map +1 -0
- package/dist/sources/git/diff.js +140 -0
- package/dist/sources/git/diff.js.map +1 -0
- package/dist/sources/git/env.d.ts +2 -0
- package/dist/sources/git/env.d.ts.map +1 -0
- package/dist/sources/git/env.js +21 -0
- package/dist/sources/git/env.js.map +1 -0
- package/dist/sources/git/history.d.ts +140 -0
- package/dist/sources/git/history.d.ts.map +1 -0
- package/dist/sources/git/history.js +314 -0
- package/dist/sources/git/history.js.map +1 -0
- package/dist/sources/git/index.d.ts +7 -0
- package/dist/sources/git/index.d.ts.map +1 -0
- package/dist/sources/git/index.js +4 -0
- package/dist/sources/git/index.js.map +1 -0
- package/dist/sources/git/source.d.ts +95 -0
- package/dist/sources/git/source.d.ts.map +1 -0
- package/dist/sources/git/source.js +0 -0
- package/dist/sources/git/source.js.map +1 -0
- package/dist/sources/migrations/dialects.d.ts +59 -0
- package/dist/sources/migrations/dialects.d.ts.map +1 -0
- package/dist/sources/migrations/dialects.js +84 -0
- package/dist/sources/migrations/dialects.js.map +1 -0
- package/dist/sources/migrations/index.d.ts +3 -0
- package/dist/sources/migrations/index.d.ts.map +1 -0
- package/dist/sources/migrations/index.js +2 -0
- package/dist/sources/migrations/index.js.map +1 -0
- package/dist/sources/migrations/read.d.ts +113 -0
- package/dist/sources/migrations/read.d.ts.map +1 -0
- package/dist/sources/migrations/read.js +270 -0
- package/dist/sources/migrations/read.js.map +1 -0
- package/dist/sources/workspace/index.d.ts +3 -0
- package/dist/sources/workspace/index.d.ts.map +1 -0
- package/dist/sources/workspace/index.js +2 -0
- package/dist/sources/workspace/index.js.map +1 -0
- package/dist/sources/workspace/workspace.d.ts +64 -0
- package/dist/sources/workspace/workspace.d.ts.map +1 -0
- package/dist/sources/workspace/workspace.js +294 -0
- package/dist/sources/workspace/workspace.js.map +1 -0
- package/dist/store/driver/driver.d.ts +82 -0
- package/dist/store/driver/driver.d.ts.map +1 -0
- package/dist/store/driver/driver.js +31 -0
- package/dist/store/driver/driver.js.map +1 -0
- package/dist/store/driver/node-sqlite.d.ts +28 -0
- package/dist/store/driver/node-sqlite.d.ts.map +1 -0
- package/dist/store/driver/node-sqlite.js +188 -0
- package/dist/store/driver/node-sqlite.js.map +1 -0
- package/dist/store/index.d.ts +33 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +46 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/migrate.d.ts +68 -0
- package/dist/store/migrate.d.ts.map +1 -0
- package/dist/store/migrate.js +140 -0
- package/dist/store/migrate.js.map +1 -0
- package/dist/store/reader.d.ts +127 -0
- package/dist/store/reader.d.ts.map +1 -0
- package/dist/store/reader.js +269 -0
- package/dist/store/reader.js.map +1 -0
- package/dist/store/schema.d.ts +87 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +322 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store/writer.d.ts +116 -0
- package/dist/store/writer.d.ts.map +1 -0
- package/dist/store/writer.js +279 -0
- package/dist/store/writer.js.map +1 -0
- package/dist/tiers/certify.d.ts +375 -0
- package/dist/tiers/certify.d.ts.map +1 -0
- package/dist/tiers/certify.js +434 -0
- package/dist/tiers/certify.js.map +1 -0
- package/dist/tiers/index.d.ts +5 -0
- package/dist/tiers/index.d.ts.map +1 -0
- package/dist/tiers/index.js +3 -0
- package/dist/tiers/index.js.map +1 -0
- package/dist/tiers/ladder.d.ts +73 -0
- package/dist/tiers/ladder.d.ts.map +1 -0
- package/dist/tiers/ladder.js +197 -0
- package/dist/tiers/ladder.js.map +1 -0
- package/dist/validation/config-graph.d.ts +104 -0
- package/dist/validation/config-graph.d.ts.map +1 -0
- package/dist/validation/config-graph.js +205 -0
- package/dist/validation/config-graph.js.map +1 -0
- package/dist/validation/env.d.ts +243 -0
- package/dist/validation/env.d.ts.map +1 -0
- package/dist/validation/env.js +447 -0
- package/dist/validation/env.js.map +1 -0
- package/dist/validation/index.d.ts +16 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +9 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/join-substitution.d.ts +186 -0
- package/dist/validation/join-substitution.d.ts.map +1 -0
- package/dist/validation/join-substitution.js +191 -0
- package/dist/validation/join-substitution.js.map +1 -0
- package/dist/validation/migrations.d.ts +133 -0
- package/dist/validation/migrations.d.ts.map +1 -0
- package/dist/validation/migrations.js +315 -0
- package/dist/validation/migrations.js.map +1 -0
- package/dist/validation/nodes.d.ts +32 -0
- package/dist/validation/nodes.d.ts.map +1 -0
- package/dist/validation/nodes.js +45 -0
- package/dist/validation/nodes.js.map +1 -0
- package/dist/validation/rollback.d.ts +124 -0
- package/dist/validation/rollback.d.ts.map +1 -0
- package/dist/validation/rollback.js +302 -0
- package/dist/validation/rollback.js.map +1 -0
- package/dist/validation/route-drift.d.ts +108 -0
- package/dist/validation/route-drift.d.ts.map +1 -0
- package/dist/validation/route-drift.js +103 -0
- package/dist/validation/route-drift.js.map +1 -0
- package/dist/validation/sources.d.ts +153 -0
- package/dist/validation/sources.d.ts.map +1 -0
- package/dist/validation/sources.js +409 -0
- package/dist/validation/sources.js.map +1 -0
- package/dist/worker/index.d.ts +5 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +3 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/pool.d.ts +73 -0
- package/dist/worker/pool.d.ts.map +1 -0
- package/dist/worker/pool.js +203 -0
- package/dist/worker/pool.js.map +1 -0
- package/dist/worker/protocol.d.ts +91 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +19 -0
- package/dist/worker/protocol.js.map +1 -0
- package/dist/worker/traversal.worker.d.ts +25 -0
- package/dist/worker/traversal.worker.d.ts.map +1 -0
- package/dist/worker/traversal.worker.js +124 -0
- package/dist/worker/traversal.worker.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A warm pool of traversal workers.
|
|
3
|
+
*
|
|
4
|
+
* ## Why warm, measured rather than assumed
|
|
5
|
+
*
|
|
6
|
+
* On this machine (Node v22.23.1, 16 cores):
|
|
7
|
+
*
|
|
8
|
+
* | | |
|
|
9
|
+
* | --- | --- |
|
|
10
|
+
* | cold worker spawn to ready | **~98–122 ms** |
|
|
11
|
+
* | round-trip on a warm worker | **~0.06 ms** |
|
|
12
|
+
* | a 200-node traversal | ~3 ms |
|
|
13
|
+
*
|
|
14
|
+
* The build plan estimated spawn at ~30 ms; it is three to four times that. A
|
|
15
|
+
* worker spawned per query would make the pre-push fast path **thirty times
|
|
16
|
+
* slower**, which is the opposite of the reason for having workers at all.
|
|
17
|
+
*
|
|
18
|
+
* The same numbers settle the other half: at 0.06 ms, dispatch is free relative
|
|
19
|
+
* to any traversal worth dispatching, so there is no main-thread fast path and
|
|
20
|
+
* no threshold to tune. Everything goes to the pool.
|
|
21
|
+
*
|
|
22
|
+
* ## The entry-point trap
|
|
23
|
+
*
|
|
24
|
+
* The worker file is `traversal.worker.ts` under Node's type stripping and
|
|
25
|
+
* `traversal.worker.js` after `tsc`. Hardcoding either breaks the other, and
|
|
26
|
+
* chasing that is — per the build plan — the most common reason a project gives
|
|
27
|
+
* up and adds a bundler. The fix is three lines: this module knows which form
|
|
28
|
+
* *it* is running as, from its own `import.meta.url`, and the worker beside it
|
|
29
|
+
* is always the same form.
|
|
30
|
+
*/
|
|
31
|
+
import type { ReachedWire, TraversalRequest } from "./protocol.ts";
|
|
32
|
+
/**
|
|
33
|
+
* The worker entry beside this module, in whichever form this module is running.
|
|
34
|
+
*
|
|
35
|
+
* `import.meta.url` ends `.ts` when Node is stripping types and `.js` when
|
|
36
|
+
* running compiled output, and the worker is emitted next to it either way.
|
|
37
|
+
*/
|
|
38
|
+
export declare function workerEntryUrl(): URL;
|
|
39
|
+
export interface TraversalPoolOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Path to the graph. Must be a file — `:memory:` is per-connection, so a
|
|
42
|
+
* worker opening it would get its own empty database rather than the graph.
|
|
43
|
+
*/
|
|
44
|
+
readonly databasePath: string;
|
|
45
|
+
readonly size?: number;
|
|
46
|
+
readonly taskTimeoutMs?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface PoolTraversalResult {
|
|
49
|
+
readonly reached: readonly ReachedWire[];
|
|
50
|
+
readonly truncated: boolean;
|
|
51
|
+
readonly resolutionFloor: 0 | 1 | 2 | 3 | 4;
|
|
52
|
+
readonly path?: readonly {
|
|
53
|
+
from: string;
|
|
54
|
+
to: string;
|
|
55
|
+
type: string;
|
|
56
|
+
}[];
|
|
57
|
+
}
|
|
58
|
+
export interface TraversalPool {
|
|
59
|
+
readonly size: number;
|
|
60
|
+
/**
|
|
61
|
+
* Run a traversal on a pooled worker.
|
|
62
|
+
*
|
|
63
|
+
* `onChunk` fires as partial results arrive, which is the point of chunking:
|
|
64
|
+
* a caller streaming to an MCP client can emit the first rows long before the
|
|
65
|
+
* traversal finishes.
|
|
66
|
+
*/
|
|
67
|
+
run(request: Omit<TraversalRequest, "id">, onChunk?: (items: readonly ReachedWire[]) => void): Promise<PoolTraversalResult>;
|
|
68
|
+
/** Round-trips every worker. Returns the ones that answered. */
|
|
69
|
+
healthCheck(): Promise<number>;
|
|
70
|
+
dispose(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
export declare function createTraversalPool(options: TraversalPoolOptions): Promise<TraversalPool>;
|
|
73
|
+
//# sourceMappingURL=pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/worker/pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,KAAK,EAEV,WAAW,EACX,gBAAgB,EAEjB,MAAM,eAAe,CAAC;AAEvB;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,GAAG,CAIpC;AAED,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvE;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,GAAG,CACD,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,EACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,KAAK,IAAI,GAChD,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,gEAAgE;IAChE,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA6BD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAgKxB"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A warm pool of traversal workers.
|
|
3
|
+
*
|
|
4
|
+
* ## Why warm, measured rather than assumed
|
|
5
|
+
*
|
|
6
|
+
* On this machine (Node v22.23.1, 16 cores):
|
|
7
|
+
*
|
|
8
|
+
* | | |
|
|
9
|
+
* | --- | --- |
|
|
10
|
+
* | cold worker spawn to ready | **~98–122 ms** |
|
|
11
|
+
* | round-trip on a warm worker | **~0.06 ms** |
|
|
12
|
+
* | a 200-node traversal | ~3 ms |
|
|
13
|
+
*
|
|
14
|
+
* The build plan estimated spawn at ~30 ms; it is three to four times that. A
|
|
15
|
+
* worker spawned per query would make the pre-push fast path **thirty times
|
|
16
|
+
* slower**, which is the opposite of the reason for having workers at all.
|
|
17
|
+
*
|
|
18
|
+
* The same numbers settle the other half: at 0.06 ms, dispatch is free relative
|
|
19
|
+
* to any traversal worth dispatching, so there is no main-thread fast path and
|
|
20
|
+
* no threshold to tune. Everything goes to the pool.
|
|
21
|
+
*
|
|
22
|
+
* ## The entry-point trap
|
|
23
|
+
*
|
|
24
|
+
* The worker file is `traversal.worker.ts` under Node's type stripping and
|
|
25
|
+
* `traversal.worker.js` after `tsc`. Hardcoding either breaks the other, and
|
|
26
|
+
* chasing that is — per the build plan — the most common reason a project gives
|
|
27
|
+
* up and adds a bundler. The fix is three lines: this module knows which form
|
|
28
|
+
* *it* is running as, from its own `import.meta.url`, and the worker beside it
|
|
29
|
+
* is always the same form.
|
|
30
|
+
*/
|
|
31
|
+
import { Worker } from "node:worker_threads";
|
|
32
|
+
import { cpus } from "node:os";
|
|
33
|
+
/**
|
|
34
|
+
* The worker entry beside this module, in whichever form this module is running.
|
|
35
|
+
*
|
|
36
|
+
* `import.meta.url` ends `.ts` when Node is stripping types and `.js` when
|
|
37
|
+
* running compiled output, and the worker is emitted next to it either way.
|
|
38
|
+
*/
|
|
39
|
+
export function workerEntryUrl() {
|
|
40
|
+
const self = import.meta.url;
|
|
41
|
+
const extension = self.endsWith(".ts") ? ".ts" : ".js";
|
|
42
|
+
return new URL(`./traversal.worker${extension}`, self);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Default pool size.
|
|
46
|
+
*
|
|
47
|
+
* Leaves headroom for the main thread and for the parser pool that Stage 1 will
|
|
48
|
+
* add: this process is not the only thing that wants a core. Capped at 4 because
|
|
49
|
+
* traversal is memory-bound on the adjacency index rather than CPU-bound, so
|
|
50
|
+
* more threads mostly buys more open database handles.
|
|
51
|
+
*/
|
|
52
|
+
function defaultSize() {
|
|
53
|
+
return Math.max(1, Math.min(4, cpus().length - 2));
|
|
54
|
+
}
|
|
55
|
+
export async function createTraversalPool(options) {
|
|
56
|
+
const size = options.size ?? defaultSize();
|
|
57
|
+
const timeoutMs = options.taskTimeoutMs ?? 30_000;
|
|
58
|
+
const entry = workerEntryUrl();
|
|
59
|
+
const slots = [];
|
|
60
|
+
const pending = new Map();
|
|
61
|
+
const queue = [];
|
|
62
|
+
let nextId = 1;
|
|
63
|
+
let disposed = false;
|
|
64
|
+
function attach(slot) {
|
|
65
|
+
slot.worker.on("message", (message) => {
|
|
66
|
+
if (message.kind === "ready" || message.kind === "pong")
|
|
67
|
+
return;
|
|
68
|
+
const task = pending.get(message.id);
|
|
69
|
+
if (task === undefined)
|
|
70
|
+
return;
|
|
71
|
+
if (message.kind === "chunk") {
|
|
72
|
+
task.chunks.push(...message.items);
|
|
73
|
+
task.onChunk?.(message.items);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
clearTimeout(task.timer);
|
|
77
|
+
pending.delete(message.id);
|
|
78
|
+
slot.busy = false;
|
|
79
|
+
if (message.kind === "failed")
|
|
80
|
+
task.reject(new Error(message.message));
|
|
81
|
+
else
|
|
82
|
+
task.resolve({
|
|
83
|
+
reached: task.chunks,
|
|
84
|
+
truncated: message.truncated,
|
|
85
|
+
resolutionFloor: message.resolutionFloor,
|
|
86
|
+
...(message.path === undefined ? {} : { path: message.path }),
|
|
87
|
+
});
|
|
88
|
+
queue.shift()?.();
|
|
89
|
+
});
|
|
90
|
+
slot.worker.on("error", (cause) => {
|
|
91
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
92
|
+
// The worker died. Fail whatever it was holding rather than letting the
|
|
93
|
+
// caller wait for a timeout, then replace it — a dead slot that stays in
|
|
94
|
+
// the pool silently reduces capacity until nothing is left.
|
|
95
|
+
slot.dead = true;
|
|
96
|
+
for (const [id, task] of pending) {
|
|
97
|
+
clearTimeout(task.timer);
|
|
98
|
+
task.reject(error);
|
|
99
|
+
pending.delete(id);
|
|
100
|
+
}
|
|
101
|
+
if (!disposed)
|
|
102
|
+
void replace(slot);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function spawn() {
|
|
106
|
+
const worker = new Worker(entry, { workerData: { databasePath: options.databasePath } });
|
|
107
|
+
await new Promise((resolve, reject) => {
|
|
108
|
+
const onMessage = (message) => {
|
|
109
|
+
if (message.kind === "ready") {
|
|
110
|
+
worker.off("error", onError);
|
|
111
|
+
resolve();
|
|
112
|
+
}
|
|
113
|
+
else if (message.kind === "failed") {
|
|
114
|
+
reject(new Error(message.message));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const onError = (error) => reject(error);
|
|
118
|
+
worker.once("message", onMessage);
|
|
119
|
+
worker.once("error", onError);
|
|
120
|
+
});
|
|
121
|
+
return worker;
|
|
122
|
+
}
|
|
123
|
+
async function replace(slot) {
|
|
124
|
+
await slot.worker.terminate().catch(() => undefined);
|
|
125
|
+
slot.worker = await spawn();
|
|
126
|
+
slot.busy = false;
|
|
127
|
+
slot.dead = false;
|
|
128
|
+
attach(slot);
|
|
129
|
+
queue.shift()?.();
|
|
130
|
+
}
|
|
131
|
+
for (let i = 0; i < size; i += 1) {
|
|
132
|
+
const slot = { worker: await spawn(), busy: false, dead: false };
|
|
133
|
+
attach(slot);
|
|
134
|
+
slots.push(slot);
|
|
135
|
+
}
|
|
136
|
+
function freeSlot() {
|
|
137
|
+
return slots.find((s) => !s.busy && !s.dead);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
size,
|
|
141
|
+
async run(request, onChunk) {
|
|
142
|
+
if (disposed)
|
|
143
|
+
throw new Error("traversal pool is disposed");
|
|
144
|
+
const slot = freeSlot() ?? (await new Promise((resolve) => {
|
|
145
|
+
queue.push(() => {
|
|
146
|
+
const next = freeSlot();
|
|
147
|
+
if (next !== undefined)
|
|
148
|
+
resolve(next);
|
|
149
|
+
else
|
|
150
|
+
queue.push(() => resolve(freeSlot()));
|
|
151
|
+
});
|
|
152
|
+
}));
|
|
153
|
+
const id = nextId++;
|
|
154
|
+
slot.busy = true;
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
const timer = setTimeout(() => {
|
|
157
|
+
pending.delete(id);
|
|
158
|
+
slot.busy = false;
|
|
159
|
+
reject(new Error(`traversal timed out after ${timeoutMs}ms`));
|
|
160
|
+
queue.shift()?.();
|
|
161
|
+
}, timeoutMs);
|
|
162
|
+
// Do not hold the process open for a pending traversal.
|
|
163
|
+
timer.unref?.();
|
|
164
|
+
pending.set(id, { resolve, reject, onChunk, chunks: [], timer });
|
|
165
|
+
slot.worker.postMessage({
|
|
166
|
+
kind: "traverse",
|
|
167
|
+
request: { ...request, id },
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
},
|
|
171
|
+
async healthCheck() {
|
|
172
|
+
const results = await Promise.all(slots.map((slot) => new Promise((resolve) => {
|
|
173
|
+
if (slot.dead)
|
|
174
|
+
return resolve(false);
|
|
175
|
+
const id = nextId++;
|
|
176
|
+
const timer = setTimeout(() => resolve(false), 2_000);
|
|
177
|
+
timer.unref?.();
|
|
178
|
+
const onMessage = (message) => {
|
|
179
|
+
if (message.kind !== "pong" || message.id !== id)
|
|
180
|
+
return;
|
|
181
|
+
clearTimeout(timer);
|
|
182
|
+
slot.worker.off("message", onMessage);
|
|
183
|
+
resolve(true);
|
|
184
|
+
};
|
|
185
|
+
slot.worker.on("message", onMessage);
|
|
186
|
+
slot.worker.postMessage({ kind: "ping", id });
|
|
187
|
+
})));
|
|
188
|
+
return results.filter(Boolean).length;
|
|
189
|
+
},
|
|
190
|
+
async dispose() {
|
|
191
|
+
// Mandatory, not hygiene: each worker holds an open database handle, and
|
|
192
|
+
// a leaked pool is four of them plus four threads per repo.
|
|
193
|
+
disposed = true;
|
|
194
|
+
for (const task of pending.values()) {
|
|
195
|
+
clearTimeout(task.timer);
|
|
196
|
+
task.reject(new Error("traversal pool disposed"));
|
|
197
|
+
}
|
|
198
|
+
pending.clear();
|
|
199
|
+
await Promise.all(slots.map((s) => s.worker.terminate().catch(() => undefined)));
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/worker/pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The main-thread ↔ worker message protocol.
|
|
3
|
+
*
|
|
4
|
+
* Everything crossing the boundary must survive structured clone, which rules
|
|
5
|
+
* out the one thing Step 9's traversal API takes: `weightFor` is a function.
|
|
6
|
+
* It is replaced here by an **edge-weight table**, which is what §12.4 actually
|
|
7
|
+
* specifies — `EdgeWeight` is tuning config keyed by edge *type*, never a
|
|
8
|
+
* per-edge value. So the serialisable form is not a compromise; it is the shape
|
|
9
|
+
* the architecture asked for, and passing a closure was the shortcut.
|
|
10
|
+
*/
|
|
11
|
+
import type { EdgeType, ResolutionLevel } from "@descryy/ir";
|
|
12
|
+
import type { Direction } from "../query/traverse.ts";
|
|
13
|
+
/** Serialisable stand-in for `WeightedOptions.weightFor`. */
|
|
14
|
+
export interface EdgeWeightTable {
|
|
15
|
+
/** Per edge type. Absent types fall back to `fallback`. */
|
|
16
|
+
readonly weights: Partial<Record<EdgeType, number>>;
|
|
17
|
+
readonly fallback: number;
|
|
18
|
+
/**
|
|
19
|
+
* Multiply the type weight by the edge's own confidence, per §12.4's
|
|
20
|
+
* `EdgeConfidence` term. On by default: a guessed edge should propagate less
|
|
21
|
+
* impact than a proven one.
|
|
22
|
+
*/
|
|
23
|
+
readonly useConfidence?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface TraversalRequest {
|
|
26
|
+
readonly id: number;
|
|
27
|
+
readonly kind: "bfs" | "weightedBfs" | "findPath";
|
|
28
|
+
readonly seeds: readonly string[];
|
|
29
|
+
/** `findPath` only. */
|
|
30
|
+
readonly target?: string;
|
|
31
|
+
readonly types?: readonly EdgeType[];
|
|
32
|
+
readonly direction?: Direction;
|
|
33
|
+
readonly maxDepth?: number;
|
|
34
|
+
readonly budget?: number;
|
|
35
|
+
readonly minConfidence?: number;
|
|
36
|
+
readonly perNodeLimit?: number;
|
|
37
|
+
readonly minScore?: number;
|
|
38
|
+
readonly edgeWeights?: EdgeWeightTable;
|
|
39
|
+
/**
|
|
40
|
+
* Rows per `postMessage`. Results are chunked rather than sent whole so a
|
|
41
|
+
* 5,000-node answer reaches the caller progressively — the streaming-first
|
|
42
|
+
* requirement is about when the first row arrives, not the last.
|
|
43
|
+
*/
|
|
44
|
+
readonly chunkSize?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ReachedWire {
|
|
47
|
+
readonly id: string;
|
|
48
|
+
readonly depth: number;
|
|
49
|
+
readonly score: number;
|
|
50
|
+
readonly viaType: EdgeType | null;
|
|
51
|
+
readonly viaFrom: string | null;
|
|
52
|
+
readonly viaTo: string | null;
|
|
53
|
+
}
|
|
54
|
+
export type WorkerMessage = {
|
|
55
|
+
readonly kind: "ready";
|
|
56
|
+
} | {
|
|
57
|
+
readonly kind: "pong";
|
|
58
|
+
readonly id: number;
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: "chunk";
|
|
61
|
+
readonly id: number;
|
|
62
|
+
readonly items: readonly ReachedWire[];
|
|
63
|
+
} | {
|
|
64
|
+
readonly kind: "done";
|
|
65
|
+
readonly id: number;
|
|
66
|
+
readonly truncated: boolean;
|
|
67
|
+
readonly resolutionFloor: ResolutionLevel;
|
|
68
|
+
/** `findPath` only: the edges of the path, in order. */
|
|
69
|
+
readonly path?: readonly {
|
|
70
|
+
from: string;
|
|
71
|
+
to: string;
|
|
72
|
+
type: EdgeType;
|
|
73
|
+
}[];
|
|
74
|
+
} | {
|
|
75
|
+
readonly kind: "failed";
|
|
76
|
+
readonly id: number;
|
|
77
|
+
readonly message: string;
|
|
78
|
+
};
|
|
79
|
+
export type MainMessage = {
|
|
80
|
+
readonly kind: "traverse";
|
|
81
|
+
readonly request: TraversalRequest;
|
|
82
|
+
} | {
|
|
83
|
+
readonly kind: "ping";
|
|
84
|
+
readonly id: number;
|
|
85
|
+
};
|
|
86
|
+
/** Build a `weightFor` from the serialisable table. Shared by worker and tests. */
|
|
87
|
+
export declare function weightFromTable(table: EdgeWeightTable): (edge: {
|
|
88
|
+
type: EdgeType;
|
|
89
|
+
confidence: number;
|
|
90
|
+
}) => number;
|
|
91
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/worker/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The main-thread ↔ worker message protocol.
|
|
3
|
+
*
|
|
4
|
+
* Everything crossing the boundary must survive structured clone, which rules
|
|
5
|
+
* out the one thing Step 9's traversal API takes: `weightFor` is a function.
|
|
6
|
+
* It is replaced here by an **edge-weight table**, which is what §12.4 actually
|
|
7
|
+
* specifies — `EdgeWeight` is tuning config keyed by edge *type*, never a
|
|
8
|
+
* per-edge value. So the serialisable form is not a compromise; it is the shape
|
|
9
|
+
* the architecture asked for, and passing a closure was the shortcut.
|
|
10
|
+
*/
|
|
11
|
+
/** Build a `weightFor` from the serialisable table. Shared by worker and tests. */
|
|
12
|
+
export function weightFromTable(table) {
|
|
13
|
+
const useConfidence = table.useConfidence ?? true;
|
|
14
|
+
return (edge) => {
|
|
15
|
+
const base = table.weights[edge.type] ?? table.fallback;
|
|
16
|
+
return useConfidence ? base * edge.confidence : base;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/worker/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAoEH,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,KAAsB;IACpD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC;IAClD,OAAO,CAAC,IAA4C,EAAU,EAAE;QAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC;QACxD,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The traversal worker.
|
|
3
|
+
*
|
|
4
|
+
* `node:sqlite` is a **synchronous** API, so a 5,000-node traversal on the main
|
|
5
|
+
* thread holds the event loop for its whole duration — which blocks the MCP
|
|
6
|
+
* stream and breaks the streaming-first promise at exactly the moment the answer
|
|
7
|
+
* is most worth streaming.
|
|
8
|
+
*
|
|
9
|
+
* Two constraints shape this file:
|
|
10
|
+
*
|
|
11
|
+
* 1. **The database handle is opened here, not passed in.** Handles are not
|
|
12
|
+
* structured-cloneable and cannot cross a thread boundary. The worker takes a
|
|
13
|
+
* path and opens its own read-only handle — which is also why WAL matters:
|
|
14
|
+
* without it a writer on the main thread blocks this reader.
|
|
15
|
+
*
|
|
16
|
+
* 2. **The handle is read-only, so `migrate` cannot run.** Even
|
|
17
|
+
* `CREATE TABLE IF NOT EXISTS` needs write permission, so the ordinary open
|
|
18
|
+
* path would fail on a perfectly healthy graph. `verifyReadOnly` performs the
|
|
19
|
+
* same DEC-017 version check with reads only.
|
|
20
|
+
*
|
|
21
|
+
* Results are chunked rather than returned whole: streaming-first is about when
|
|
22
|
+
* the *first* row arrives, not the last.
|
|
23
|
+
*/
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=traversal.worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traversal.worker.d.ts","sourceRoot":"","sources":["../../src/worker/traversal.worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The traversal worker.
|
|
3
|
+
*
|
|
4
|
+
* `node:sqlite` is a **synchronous** API, so a 5,000-node traversal on the main
|
|
5
|
+
* thread holds the event loop for its whole duration — which blocks the MCP
|
|
6
|
+
* stream and breaks the streaming-first promise at exactly the moment the answer
|
|
7
|
+
* is most worth streaming.
|
|
8
|
+
*
|
|
9
|
+
* Two constraints shape this file:
|
|
10
|
+
*
|
|
11
|
+
* 1. **The database handle is opened here, not passed in.** Handles are not
|
|
12
|
+
* structured-cloneable and cannot cross a thread boundary. The worker takes a
|
|
13
|
+
* path and opens its own read-only handle — which is also why WAL matters:
|
|
14
|
+
* without it a writer on the main thread blocks this reader.
|
|
15
|
+
*
|
|
16
|
+
* 2. **The handle is read-only, so `migrate` cannot run.** Even
|
|
17
|
+
* `CREATE TABLE IF NOT EXISTS` needs write permission, so the ordinary open
|
|
18
|
+
* path would fail on a perfectly healthy graph. `verifyReadOnly` performs the
|
|
19
|
+
* same DEC-017 version check with reads only.
|
|
20
|
+
*
|
|
21
|
+
* Results are chunked rather than returned whole: streaming-first is about when
|
|
22
|
+
* the *first* row arrives, not the last.
|
|
23
|
+
*/
|
|
24
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
25
|
+
import { openStore } from "../store/index.js";
|
|
26
|
+
import { createStoreProvider } from "../query/sqlite.js";
|
|
27
|
+
import { bfs, findPath, weightedBfs } from "../query/traverse.js";
|
|
28
|
+
import { weightFromTable } from "./protocol.js";
|
|
29
|
+
const port = parentPort;
|
|
30
|
+
if (port === null)
|
|
31
|
+
throw new Error("traversal.worker must be run as a worker thread");
|
|
32
|
+
const init = workerData;
|
|
33
|
+
let store;
|
|
34
|
+
try {
|
|
35
|
+
store = openStore(init.databasePath, { readOnly: true });
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
port.postMessage({
|
|
39
|
+
kind: "failed",
|
|
40
|
+
id: -1,
|
|
41
|
+
message: error instanceof Error ? error.message : String(error),
|
|
42
|
+
});
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
const provider = createStoreProvider(store.driver);
|
|
46
|
+
function baseOptions(request) {
|
|
47
|
+
return {
|
|
48
|
+
...(request.types === undefined ? {} : { types: request.types }),
|
|
49
|
+
...(request.direction === undefined ? {} : { direction: request.direction }),
|
|
50
|
+
...(request.maxDepth === undefined ? {} : { maxDepth: request.maxDepth }),
|
|
51
|
+
...(request.budget === undefined ? {} : { budget: request.budget }),
|
|
52
|
+
...(request.minConfidence === undefined ? {} : { minConfidence: request.minConfidence }),
|
|
53
|
+
...(request.perNodeLimit === undefined ? {} : { perNodeLimit: request.perNodeLimit }),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function send(message) {
|
|
57
|
+
port.postMessage(message);
|
|
58
|
+
}
|
|
59
|
+
function handle(request) {
|
|
60
|
+
const chunkSize = request.chunkSize ?? 500;
|
|
61
|
+
if (request.kind === "findPath") {
|
|
62
|
+
const target = request.target;
|
|
63
|
+
const seed = request.seeds[0];
|
|
64
|
+
if (seed === undefined || target === undefined) {
|
|
65
|
+
send({ kind: "failed", id: request.id, message: "findPath needs a seed and a target" });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const path = findPath(provider, seed, target, baseOptions(request));
|
|
69
|
+
send({
|
|
70
|
+
kind: "done",
|
|
71
|
+
id: request.id,
|
|
72
|
+
truncated: false,
|
|
73
|
+
resolutionFloor: path.reduce((floor, e) => (e.resolution < floor ? e.resolution : floor), 4),
|
|
74
|
+
path: path.map((e) => ({ from: e.from, to: e.to, type: e.type })),
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const outcome = request.kind === "weightedBfs"
|
|
79
|
+
? weightedBfs(provider, request.seeds, {
|
|
80
|
+
...baseOptions(request),
|
|
81
|
+
...(request.minScore === undefined ? {} : { minScore: request.minScore }),
|
|
82
|
+
...(request.edgeWeights === undefined
|
|
83
|
+
? {}
|
|
84
|
+
: { weightFor: weightFromTable(request.edgeWeights) }),
|
|
85
|
+
})
|
|
86
|
+
: bfs(provider, request.seeds, baseOptions(request));
|
|
87
|
+
for (let i = 0; i < outcome.reached.length; i += chunkSize) {
|
|
88
|
+
const items = outcome.reached.slice(i, i + chunkSize).map((r) => ({
|
|
89
|
+
id: r.id,
|
|
90
|
+
depth: r.depth,
|
|
91
|
+
score: r.score,
|
|
92
|
+
viaType: r.via?.type ?? null,
|
|
93
|
+
viaFrom: r.via?.from ?? null,
|
|
94
|
+
viaTo: r.via?.to ?? null,
|
|
95
|
+
}));
|
|
96
|
+
send({ kind: "chunk", id: request.id, items });
|
|
97
|
+
}
|
|
98
|
+
send({
|
|
99
|
+
kind: "done",
|
|
100
|
+
id: request.id,
|
|
101
|
+
truncated: outcome.truncated,
|
|
102
|
+
resolutionFloor: outcome.resolutionFloor,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
port.on("message", (message) => {
|
|
106
|
+
if (message.kind === "ping") {
|
|
107
|
+
send({ kind: "pong", id: message.id });
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
handle(message.request);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// A failed traversal must not take the worker with it — the pool would then
|
|
115
|
+
// pay a ~100ms respawn for what may be one malformed request.
|
|
116
|
+
send({
|
|
117
|
+
kind: "failed",
|
|
118
|
+
id: message.request.id,
|
|
119
|
+
message: error instanceof Error ? error.message : String(error),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
send({ kind: "ready" });
|
|
124
|
+
//# sourceMappingURL=traversal.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traversal.worker.js","sourceRoot":"","sources":["../../src/worker/traversal.worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@descryy/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Descry graph engine: storage, graph builder, query layer, traversal, diff scoping, git source, MCP server.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.5"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"registry": "https://registry.npmjs.org",
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -b"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@descryy/ir": "0.1.0"
|
|
28
|
+
}
|
|
29
|
+
}
|