@vellumai/assistant 0.8.9-staging.2 → 0.8.9-staging.4
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/docs/activation-funnel-telemetry.md +310 -0
- package/openapi.yaml +16 -115
- package/package.json +1 -1
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +13 -13
- package/src/__tests__/anthropic-provider.test.ts +23 -8
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/compaction-direct.test.ts +32 -18
- package/src/__tests__/compaction-events.test.ts +2 -2
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/context-overflow-reducer.test.ts +5 -5
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +5 -0
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +40 -0
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +71 -0
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +44 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/history-repair-hook.test.ts +2 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +1 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +5 -7
- package/src/__tests__/title-generate-hook.test.ts +2 -0
- package/src/__tests__/web-fetch.test.ts +45 -0
- package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
- package/src/acp/resolve-agent.test.ts +0 -56
- package/src/acp/resolve-agent.ts +10 -38
- package/src/agent/loop.ts +13 -27
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/lib/__tests__/install-from-github.test.ts +232 -29
- package/src/cli/lib/__tests__/plugin-details.test.ts +28 -19
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +57 -7
- package/src/cli/lib/__tests__/search-plugins.test.ts +17 -10
- package/src/cli/lib/install-from-github.ts +258 -41
- package/src/cli/lib/plugin-details.ts +20 -13
- package/src/cli/lib/plugin-marketplace.ts +23 -5
- package/src/cli/lib/search-plugins.ts +14 -8
- package/src/config/acp-defaults.ts +3 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +4 -17
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/call-site-defaults.ts +0 -1
- package/src/config/feature-flag-registry.json +3 -18
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/llm.ts +17 -1
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +8 -1
- package/src/daemon/conversation-agent-loop.ts +87 -95
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +14 -5
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +37 -1
- package/src/daemon/conversation-surfaces.ts +141 -3
- package/src/daemon/conversation.ts +48 -13
- package/src/daemon/external-plugins-bootstrap.ts +8 -3
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/memory/__tests__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -72
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/adapters/telegram.ts +7 -1
- package/src/plugin-api/constants.ts +2 -2
- package/src/plugin-api/index.ts +2 -2
- package/src/plugin-api/types.ts +19 -5
- package/src/plugins/defaults/compaction/compact.ts +24 -15
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +4 -4
- package/src/plugins/defaults/compaction/manager-store.ts +1 -1
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +68 -12
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +12 -18
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +19 -66
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +139 -129
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +332 -164
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +516 -293
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +51 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +66 -11
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +271 -110
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +0 -22
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +26 -62
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +3 -2
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +415 -181
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +196 -56
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +39 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +15 -7
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +75 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +111 -78
- package/src/plugins/defaults/memory-v3-shadow/types.ts +52 -19
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +4 -1
- package/src/plugins/external-api.ts +114 -0
- package/src/prompts/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +37 -2
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +22 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
- package/src/runtime/routes/acp-routes.test.ts +3 -20
- package/src/runtime/routes/app-management-routes.ts +3 -0
- package/src/runtime/routes/conversation-routes.ts +2 -0
- package/src/runtime/routes/memory-v3-routes.ts +64 -314
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/services/published-app-updater.ts +30 -8
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/list-agents.test.ts +2 -18
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +0 -10
- package/src/tools/browser/browser-execution.ts +12 -2
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/ui-surface/definitions.ts +7 -0
- package/src/acp/feature-gate.test.ts +0 -48
- package/src/acp/feature-gate.ts +0 -34
- package/src/plugins/defaults/memory-v3-shadow/__tests__/assign.test.ts +0 -242
- package/src/plugins/defaults/memory-v3-shadow/__tests__/core.test.ts +0 -39
- package/src/plugins/defaults/memory-v3-shadow/__tests__/health.test.ts +0 -219
- package/src/plugins/defaults/memory-v3-shadow/__tests__/needle.test.ts +0 -107
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +0 -13
- package/src/plugins/defaults/memory-v3-shadow/__tests__/reconcile.test.ts +0 -274
- package/src/plugins/defaults/memory-v3-shadow/__tests__/router.test.ts +0 -337
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selector.test.ts +0 -470
- package/src/plugins/defaults/memory-v3-shadow/__tests__/snapshot.test.ts +0 -168
- package/src/plugins/defaults/memory-v3-shadow/__tests__/tree.test.ts +0 -192
- package/src/plugins/defaults/memory-v3-shadow/assign.ts +0 -272
- package/src/plugins/defaults/memory-v3-shadow/core.ts +0 -26
- package/src/plugins/defaults/memory-v3-shadow/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/needle.ts +0 -115
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +0 -26
- package/src/plugins/defaults/memory-v3-shadow/reconcile.ts +0 -527
- package/src/plugins/defaults/memory-v3-shadow/router.ts +0 -190
- package/src/plugins/defaults/memory-v3-shadow/selector.ts +0 -226
- package/src/plugins/defaults/memory-v3-shadow/snapshot.ts +0 -209
- package/src/plugins/defaults/memory-v3-shadow/tree.ts +0 -174
- package/src/util/map-limit.ts +0 -27
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
3
|
-
import { dirname, join, relative, sep } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
import { parse as parseYaml } from "yaml";
|
|
7
|
-
|
|
8
|
-
import { getWorkspaceDir } from "../../../util/platform.js";
|
|
9
|
-
import type {
|
|
10
|
-
LeafFrontmatter,
|
|
11
|
-
LeafNode,
|
|
12
|
-
LeafPath,
|
|
13
|
-
LeafTree,
|
|
14
|
-
Slug,
|
|
15
|
-
} from "./types.js";
|
|
16
|
-
|
|
17
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
|
|
19
|
-
/** Bundled stub data shipped alongside the loader. */
|
|
20
|
-
const BUNDLED_DATA_DIR = join(HERE, "data");
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Resolve the directory the loaders should read leaf-tree artifacts from.
|
|
24
|
-
*
|
|
25
|
-
* Prefers a maintainer's per-instance workspace override
|
|
26
|
-
* (`<workspace>/memory/v3/data/`) when present, otherwise falls back to the
|
|
27
|
-
* generic bundled stub shipped in this package.
|
|
28
|
-
*
|
|
29
|
-
* The public {@link loadLeafTree} API still takes an explicit `dataDir` for
|
|
30
|
-
* testability; orchestrators that want the runtime default call this helper.
|
|
31
|
-
*/
|
|
32
|
-
export function resolveDataDir(): string {
|
|
33
|
-
const workspaceData = join(getWorkspaceDir(), "memory", "v3", "data");
|
|
34
|
-
if (existsSync(workspaceData)) return workspaceData;
|
|
35
|
-
return BUNDLED_DATA_DIR;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Recursively collect every `*.md` file under `dir`. */
|
|
39
|
-
async function collectMarkdownFiles(dir: string): Promise<string[]> {
|
|
40
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
41
|
-
const files: string[] = [];
|
|
42
|
-
for (const entry of entries) {
|
|
43
|
-
const full = join(dir, entry.name);
|
|
44
|
-
if (entry.isDirectory()) {
|
|
45
|
-
files.push(...(await collectMarkdownFiles(full)));
|
|
46
|
-
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
47
|
-
files.push(full);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return files;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Split a leaf `.md` file into its YAML frontmatter and body.
|
|
55
|
-
*
|
|
56
|
-
* Frontmatter is the `---`-delimited block at the top of the file; everything
|
|
57
|
-
* after the closing delimiter is the description body.
|
|
58
|
-
*/
|
|
59
|
-
function splitFrontmatter(raw: string): { frontmatter: string; body: string } {
|
|
60
|
-
const normalized = raw.replace(/^/, "");
|
|
61
|
-
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(normalized);
|
|
62
|
-
if (!match) {
|
|
63
|
-
throw new Error("leaf markdown is missing YAML frontmatter");
|
|
64
|
-
}
|
|
65
|
-
return { frontmatter: match[1], body: match[2] };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function parseLeafFrontmatter(yaml: string, file: string): LeafFrontmatter {
|
|
69
|
-
const parsed = parseYaml(yaml) as unknown;
|
|
70
|
-
if (parsed === null || typeof parsed !== "object") {
|
|
71
|
-
throw new Error(`leaf ${file} frontmatter is not a mapping`);
|
|
72
|
-
}
|
|
73
|
-
const record = parsed as Record<string, unknown>;
|
|
74
|
-
if (typeof record.path !== "string") {
|
|
75
|
-
throw new Error(`leaf ${file} frontmatter is missing a string \`path\``);
|
|
76
|
-
}
|
|
77
|
-
if (typeof record.in_core !== "boolean") {
|
|
78
|
-
throw new Error(
|
|
79
|
-
`leaf ${file} frontmatter is missing a boolean \`in_core\``,
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
path: record.path,
|
|
84
|
-
in_core: record.in_core,
|
|
85
|
-
...(typeof record.id === "string" ? { id: record.id } : {}),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Derive the canonical leaf path from a file's location under `leaves/`. */
|
|
90
|
-
function pathFromLocation(leavesDir: string, file: string): LeafPath {
|
|
91
|
-
return relative(leavesDir, file).replace(/\.md$/, "").split(sep).join("/");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Load the leaf tree from `dataDir`. READ-ONLY: walks `leaves/**\/*.md` and
|
|
96
|
-
* reads `assignments.json` without mutating anything on disk.
|
|
97
|
-
*
|
|
98
|
-
* Builds:
|
|
99
|
-
* - `leaves`: leaf path → {@link LeafNode} (frontmatter, description, domain,
|
|
100
|
-
* and the slugs assigned to it).
|
|
101
|
-
* - `byPage`: slug → the leaf paths it is assigned to (inverted assignments).
|
|
102
|
-
*
|
|
103
|
-
* Page→leaf membership precedence is per-page: when `pageLeaves` supplies a
|
|
104
|
-
* non-empty array for a slug, those frontmatter-derived leaves win for that
|
|
105
|
-
* page; slugs absent from `pageLeaves` (or mapped to an empty array) fall back
|
|
106
|
-
* to `assignments.json`. Omitting `pageLeaves` reproduces the legacy
|
|
107
|
-
* assignments.json-only behavior exactly (used by the bundled stub and tests);
|
|
108
|
-
* orchestrators supply `pageLeaves` from the page index.
|
|
109
|
-
*/
|
|
110
|
-
export async function loadLeafTree(
|
|
111
|
-
dataDir: string,
|
|
112
|
-
pageLeaves?: Map<Slug, LeafPath[]>,
|
|
113
|
-
): Promise<LeafTree> {
|
|
114
|
-
const leavesDir = join(dataDir, "leaves");
|
|
115
|
-
const files = await collectMarkdownFiles(leavesDir);
|
|
116
|
-
|
|
117
|
-
const nodes = await Promise.all(
|
|
118
|
-
files.map(async (file): Promise<LeafNode> => {
|
|
119
|
-
const raw = await readFile(file, "utf8");
|
|
120
|
-
const { frontmatter, body } = splitFrontmatter(raw);
|
|
121
|
-
const path = pathFromLocation(leavesDir, file);
|
|
122
|
-
return {
|
|
123
|
-
path,
|
|
124
|
-
frontmatter: parseLeafFrontmatter(frontmatter, file),
|
|
125
|
-
description: body.trim(),
|
|
126
|
-
members: [],
|
|
127
|
-
domain: path.split("/")[0],
|
|
128
|
-
};
|
|
129
|
-
}),
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
const leaves = new Map<LeafPath, LeafNode>(
|
|
133
|
-
nodes.map((node) => [node.path, node]),
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
const assignmentsRaw = await readFile(
|
|
137
|
-
join(dataDir, "assignments.json"),
|
|
138
|
-
"utf8",
|
|
139
|
-
);
|
|
140
|
-
const assignments = JSON.parse(assignmentsRaw) as Record<Slug, LeafPath[]>;
|
|
141
|
-
|
|
142
|
-
const slugs = new Set<Slug>(Object.keys(assignments));
|
|
143
|
-
if (pageLeaves) for (const slug of pageLeaves.keys()) slugs.add(slug);
|
|
144
|
-
|
|
145
|
-
const byPage = new Map<Slug, LeafPath[]>();
|
|
146
|
-
for (const slug of slugs) {
|
|
147
|
-
const fromFrontmatter = pageLeaves?.get(slug);
|
|
148
|
-
const leafPaths =
|
|
149
|
-
fromFrontmatter && fromFrontmatter.length > 0
|
|
150
|
-
? fromFrontmatter
|
|
151
|
-
: (assignments[slug] ?? []);
|
|
152
|
-
byPage.set(slug, [...leafPaths]);
|
|
153
|
-
for (const leafPath of leafPaths) {
|
|
154
|
-
leaves.get(leafPath)?.members.push(slug);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return { leaves, byPage };
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** The slugs assigned to a leaf. */
|
|
162
|
-
export function membersOf(tree: LeafTree, leaf: LeafPath): Slug[] {
|
|
163
|
-
return tree.leaves.get(leaf)?.members ?? [];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** The leaf paths a slug is assigned to. */
|
|
167
|
-
export function leavesOf(tree: LeafTree, slug: Slug): LeafPath[] {
|
|
168
|
-
return tree.byPage.get(slug) ?? [];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/** The unique slugs owned by every leaf in `core` (expand leaf-paths → slugs). */
|
|
172
|
-
export function coreSlugs(tree: LeafTree, core: Set<LeafPath>): Set<Slug> {
|
|
173
|
-
return new Set([...core].flatMap((leaf) => membersOf(tree, leaf)));
|
|
174
|
-
}
|
package/src/util/map-limit.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Map `fn` over `items` with bounded concurrency, preserving input order in the
|
|
3
|
-
* result array. At most `limit` invocations of `fn` are in flight at once.
|
|
4
|
-
*
|
|
5
|
-
* Each of the `min(limit, items.length)` workers pulls the next index off a
|
|
6
|
-
* shared cursor and processes it, so faster items don't block on slower ones.
|
|
7
|
-
* Results are written back to their original positions, so `out[i]` always
|
|
8
|
-
* corresponds to `items[i]` regardless of completion order.
|
|
9
|
-
*/
|
|
10
|
-
export async function mapLimit<T, R>(
|
|
11
|
-
items: T[],
|
|
12
|
-
limit: number,
|
|
13
|
-
fn: (t: T) => Promise<R>,
|
|
14
|
-
): Promise<R[]> {
|
|
15
|
-
const out: R[] = new Array(items.length);
|
|
16
|
-
let next = 0;
|
|
17
|
-
await Promise.all(
|
|
18
|
-
Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
19
|
-
while (true) {
|
|
20
|
-
const i = next++;
|
|
21
|
-
if (i >= items.length) return;
|
|
22
|
-
out[i] = await fn(items[i]!);
|
|
23
|
-
}
|
|
24
|
-
}),
|
|
25
|
-
);
|
|
26
|
-
return out;
|
|
27
|
-
}
|