Skip to content

Commit 3e7eb35

Browse files
committed
codex: address PR review feedback (#1155)
1 parent a111204 commit 3e7eb35

3 files changed

Lines changed: 60 additions & 54 deletions

File tree

src/engine/SingleMacroEngine.member-access.test.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ describe("SingleMacroEngine member access", () => {
250250
expect(engineInstance.runSubset).toHaveBeenNthCalledWith(2, [postCommand]);
251251
expect(engineInstance.setOutput).toHaveBeenCalledWith("export-result");
252252
expect(result).toBe("export-result");
253-
expect(mockGetUserScript).toHaveBeenCalledTimes(2);
253+
expect(mockGetUserScript).toHaveBeenCalledTimes(3);
254254
expect(mockGetUserScript).toHaveBeenCalledWith(firstScript, app);
255255
expect(mockGetUserScript).toHaveBeenCalledWith(secondScript, app);
256256
});
@@ -328,6 +328,52 @@ describe("SingleMacroEngine member access", () => {
328328
expect(mockGetUserScript).toHaveBeenCalledWith(scriptB, app);
329329
});
330330

331+
it("loads a selector-targeted script after pre-commands run", async () => {
332+
const preCommand = {
333+
id: "wait-1",
334+
name: "Wait",
335+
type: CommandType.Wait,
336+
} as ICommand;
337+
const scriptA = createUserScript("script-a", "a.js", {
338+
name: "Alpha Script",
339+
});
340+
const scriptB = createUserScript("script-b", "b.js", {
341+
name: "Beta Script",
342+
});
343+
344+
let ready = false;
345+
const engineInstance = macroEngineFactory();
346+
engineInstance.runSubset = vi.fn().mockImplementation(async () => {
347+
ready = true;
348+
});
349+
macroEngineFactory = () => engineInstance;
350+
351+
mockGetUserScript.mockImplementation(async (command: IUserScript) => {
352+
if (command.id !== "script-b") {
353+
return { alpha: vi.fn() };
354+
}
355+
356+
return ready
357+
? { beta: () => "late-bound-result" }
358+
: { alpha: vi.fn() };
359+
});
360+
361+
const engine = new SingleMacroEngine(
362+
app,
363+
plugin,
364+
[baseMacroChoice([preCommand, scriptA, scriptB])],
365+
choiceExecutor,
366+
);
367+
368+
const result = await engine.runAndGetOutput(
369+
"My Macro::Beta Script::beta",
370+
);
371+
372+
expect(result).toBe("late-bound-result");
373+
expect(mockGetUserScript).toHaveBeenCalledTimes(1);
374+
expect(mockGetUserScript).toHaveBeenCalledWith(scriptB, app);
375+
});
376+
331377
it("aborts when a selector matches duplicate script names", async () => {
332378
const scriptA = createUserScript("script-a", "a.js", {
333379
name: "Shared Script",
@@ -383,7 +429,7 @@ describe("SingleMacroEngine member access", () => {
383429
const result = await engine.runAndGetOutput("My Macro::NotAScript::beta");
384430

385431
expect(result).toBe("nested-result");
386-
expect(mockGetUserScript).toHaveBeenCalledTimes(2);
432+
expect(mockGetUserScript).toHaveBeenCalledTimes(3);
387433
});
388434

389435
it("aborts when a selected script does not export the requested member", async () => {
@@ -411,7 +457,7 @@ describe("SingleMacroEngine member access", () => {
411457

412458
await expect(
413459
engine.runAndGetOutput("My Macro::Alpha Script::beta"),
414-
).rejects.toThrow("targeted script 'Alpha Script'");
460+
).rejects.toThrow("routes member access to 'Alpha Script'");
415461
});
416462

417463
it("propagates aborts when the export aborts", async () => {

src/engine/SingleMacroEngine.ts

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import { MacroAbortError } from "../errors/MacroAbortError";
1616
type UserScriptCandidate = {
1717
command: IUserScript;
1818
index: number;
19-
exportsRef?: unknown;
20-
resolvedMember: { found: boolean; value?: unknown };
2119
};
2220

2321
type MemberAccessSelection = {
@@ -98,16 +96,14 @@ export class SingleMacroEngine {
9896
throw new Error(`macro '${macroName}' does not exist.`);
9997
}
10098

101-
const preloadedScripts = new Map<string, unknown>();
102-
10399
// Create a dedicated engine for this macro
104100
const engine = new MacroChoiceEngine(
105101
this.app,
106102
this.plugin,
107103
macroChoice,
108104
this.choiceExecutor,
109105
this.variables,
110-
preloadedScripts,
106+
undefined,
111107
context?.label,
112108
);
113109

@@ -116,7 +112,6 @@ export class SingleMacroEngine {
116112
engine,
117113
macroChoice,
118114
memberAccess,
119-
preloadedScripts,
120115
);
121116

122117
this.ensureNotAborted();
@@ -154,7 +149,6 @@ export class SingleMacroEngine {
154149
engine: MacroChoiceEngine,
155150
macroChoice: IMacroChoice,
156151
memberAccess: string[],
157-
preloadedScripts: Map<string, unknown>,
158152
): Promise<{ executed: boolean; result?: unknown }> {
159153
const originalCommands = macroChoice.macro?.commands;
160154
if (!originalCommands?.length) {
@@ -176,7 +170,6 @@ export class SingleMacroEngine {
176170
macroChoice,
177171
userScriptCommands,
178172
memberAccess,
179-
preloadedScripts,
180173
);
181174
const preCommands = originalCommands.slice(0, selection.candidate.index);
182175

@@ -199,22 +192,14 @@ export class SingleMacroEngine {
199192
userScriptCommand.settings = {};
200193
}
201194

202-
const exportsRef =
203-
selection.candidate.exportsRef !== undefined
204-
? selection.candidate.exportsRef
205-
: await getUserScript(userScriptCommand, this.app);
195+
const exportsRef = await getUserScript(userScriptCommand, this.app);
206196

207197
if (exportsRef === undefined || exportsRef === null) {
208198
throw new MacroAbortError(
209199
`Macro '${macroChoice.name}' could not load '${userScriptCommand.name}' for member access.`,
210200
);
211201
}
212202

213-
const cacheKey = userScriptCommand.path ?? userScriptCommand.id;
214-
if (cacheKey && exportsRef !== undefined && exportsRef !== null) {
215-
preloadedScripts.set(cacheKey, exportsRef);
216-
}
217-
218203
const settingsExport =
219204
typeof exportsRef === "object" || typeof exportsRef === "function"
220205
? (exportsRef as Record<string, unknown>).settings
@@ -227,10 +212,10 @@ export class SingleMacroEngine {
227212
);
228213
}
229214

230-
const resolvedMember =
231-
selection.candidate.exportsRef !== undefined
232-
? selection.candidate.resolvedMember
233-
: this.resolveMemberAccess(exportsRef, selection.memberAccess);
215+
const resolvedMember = this.resolveMemberAccess(
216+
exportsRef,
217+
selection.memberAccess,
218+
);
234219

235220
if (!resolvedMember.found) {
236221
throw new MacroAbortError(
@@ -327,14 +312,12 @@ export class SingleMacroEngine {
327312
macroChoice: IMacroChoice,
328313
userScriptCommands: Array<{ command: IUserScript; index: number }>,
329314
memberAccess: string[],
330-
preloadedScripts: Map<string, unknown>,
331315
): Promise<MemberAccessSelection> {
332316
if (userScriptCommands.length === 1) {
333317
return {
334318
candidate: {
335319
command: userScriptCommands[0].command,
336320
index: userScriptCommands[0].index,
337-
resolvedMember: { found: false },
338321
},
339322
memberAccess,
340323
};
@@ -347,48 +330,24 @@ export class SingleMacroEngine {
347330
);
348331

349332
if (selectorMatch) {
350-
const exportsRef = await getUserScript(selectorMatch.command, this.app);
351-
const cacheKey = selectorMatch.command.path ?? selectorMatch.command.id;
352-
if (cacheKey && exportsRef !== undefined && exportsRef !== null) {
353-
preloadedScripts.set(cacheKey, exportsRef);
354-
}
355-
356-
const resolvedMember = this.resolveMemberAccess(
357-
exportsRef,
358-
selectorMatch.memberAccess,
359-
);
360-
if (!resolvedMember.found) {
361-
throw new MacroAbortError(
362-
`Macro '${macroChoice.name}' targeted script '${selectorMatch.command.name}', but that script does not export '${selectorMatch.memberAccess.join(
363-
"::",
364-
)}'.`,
365-
);
366-
}
367-
368333
return {
369334
candidate: {
370335
command: selectorMatch.command,
371336
index: selectorMatch.index,
372-
exportsRef,
373-
resolvedMember,
374337
},
375338
memberAccess: selectorMatch.memberAccess,
376339
};
377340
}
378341

379-
const candidates: UserScriptCandidate[] = [];
342+
const candidates: Array<
343+
UserScriptCandidate & { resolvedMember: { found: boolean; value?: unknown } }
344+
> = [];
380345

381346
for (const entry of userScriptCommands) {
382347
const exportsRef = await getUserScript(entry.command, this.app);
383-
const cacheKey = entry.command.path ?? entry.command.id;
384-
if (cacheKey && exportsRef !== undefined && exportsRef !== null) {
385-
preloadedScripts.set(cacheKey, exportsRef);
386-
}
387-
388348
candidates.push({
389349
command: entry.command,
390350
index: entry.index,
391-
exportsRef,
392351
resolvedMember: this.resolveMemberAccess(exportsRef, memberAccess),
393352
});
394353
}

tests/e2e/macro-member-access.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import type {
1515

1616
const VAULT = "dev";
1717
const PLUGIN_ID = "quickadd";
18-
const WAIT_OPTS = { timeoutMs: 10_000, intervalMs: 200 };
18+
const waitTimeoutMs = Number(process.env.E2E_TIMEOUT_MS) || 15_000;
19+
const WAIT_OPTS = { timeoutMs: waitTimeoutMs, intervalMs: 200 };
1920
const TEST_PREFIX = "__qa-test-964-";
2021

2122
let obsidian: ObsidianClient;

0 commit comments

Comments
 (0)