Skip to content

Commit 79ed1b0

Browse files
committed
refactor
1 parent f59e00f commit 79ed1b0

17 files changed

+371
-363
lines changed

src/extension.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import setup from "./plugins/setup.ts";
99
import statusBar from "./plugins/status-bar.ts";
1010
import { PluginManager } from "./plugins.ts";
1111
import { createCliStatusTracker } from "./utils/cli.ts";
12-
import { createContainerStatusTracker } from "./utils/container-status.ts";
13-
import { createLocalStackStatusTracker } from "./utils/localstack-status.ts";
12+
import { createLocalStackContainerStatusTracker } from "./utils/localstack-container.ts";
13+
import { createLocalStackInstanceStatusTracker } from "./utils/localstack-instance.ts";
1414
import { getOrCreateExtensionSessionId } from "./utils/manage.ts";
15-
import { createSetupStatusTracker } from "./utils/setup-status.ts";
15+
import { createSetupStatusTracker } from "./utils/setup.ts";
1616
import { createTelemetry } from "./utils/telemetry.ts";
1717
import { createTimeTracker } from "./utils/time-tracker.ts";
1818

@@ -50,14 +50,14 @@ export async function activate(context: ExtensionContext) {
5050
statusBarItem.text = "$(loading~spin) LocalStack";
5151
statusBarItem.show();
5252

53-
const containerStatusTracker = createContainerStatusTracker(
53+
const containerStatusTracker = createLocalStackContainerStatusTracker(
5454
"localstack-main",
5555
outputChannel,
5656
timeTracker,
5757
);
5858
context.subscriptions.push(containerStatusTracker);
5959

60-
const localStackStatusTracker = createLocalStackStatusTracker(
60+
const localStackStatusTracker = createLocalStackInstanceStatusTracker(
6161
containerStatusTracker,
6262
outputChannel,
6363
timeTracker,

src/plugins.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import ms from "ms";
22
import type { ExtensionContext, LogOutputChannel, StatusBarItem } from "vscode";
33

44
import type { CliStatusTracker } from "./utils/cli.ts";
5-
import type { ContainerStatusTracker } from "./utils/container-status.ts";
6-
import type { LocalStackStatusTracker } from "./utils/localstack-status.ts";
7-
import type { SetupStatusTracker } from "./utils/setup-status.ts";
5+
import type { LocalStackContainerStatusTracker } from "./utils/localstack-container.ts";
6+
import type { LocalStackInstanceStatusTracker } from "./utils/localstack-instance.ts";
7+
import type { SetupStatusTracker } from "./utils/setup.ts";
88
import type { Telemetry } from "./utils/telemetry.ts";
99
import type { TimeTracker } from "./utils/time-tracker.ts";
1010

@@ -15,8 +15,8 @@ export interface PluginOptions {
1515
outputChannel: LogOutputChannel;
1616
statusBarItem: StatusBarItem;
1717
cliStatusTracker: CliStatusTracker;
18-
containerStatusTracker: ContainerStatusTracker;
19-
localStackStatusTracker: LocalStackStatusTracker;
18+
containerStatusTracker: LocalStackContainerStatusTracker;
19+
localStackStatusTracker: LocalStackInstanceStatusTracker;
2020
setupStatusTracker: SetupStatusTracker;
2121
telemetry: Telemetry;
2222
timeTracker: TimeTracker;

src/plugins/setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
checkIsLicenseValid,
1616
activateLicenseUntilValid,
1717
} from "../utils/license.ts";
18-
import { minDelay } from "../utils/promises.ts";
18+
import { minDelay } from "../utils/min-delay.ts";
1919
import { updateDockerImage } from "../utils/setup.ts";
2020
import { get_setup_ended } from "../utils/telemetry.ts";
2121

src/plugins/status-bar.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { commands, QuickPickItemKind, ThemeColor, window } from "vscode";
22
import type { QuickPickItem } from "vscode";
33

44
import { createPlugin } from "../plugins.ts";
5-
import { immediateOnce } from "../utils/immediate-once.ts";
6-
import type { LocalStackStatus } from "../utils/localstack-status.ts";
7-
import type { SetupStatus } from "../utils/setup-status.ts";
5+
import type { LocalStackInstanceStatus } from "../utils/localstack-instance.ts";
6+
import { createOnceImmediate } from "../utils/once-immediate.ts";
7+
import type { SetupStatus } from "../utils/setup.ts";
88

99
function getStatusText(options: {
1010
cliStatus: SetupStatus;
11-
localStackStatus: LocalStackStatus;
11+
localStackStatus: LocalStackInstanceStatus;
1212
cliOutdated: boolean | undefined;
1313
}) {
1414
if (options.cliStatus === "ok") {
@@ -97,7 +97,7 @@ export default createPlugin(
9797
}),
9898
);
9999

100-
const renderStatusBar = immediateOnce(() => {
100+
const renderStatusBar = createOnceImmediate(() => {
101101
const setupStatus = setupStatusTracker.status();
102102
const localStackStatus = localStackStatusTracker.status();
103103
const cliStatus = cliStatusTracker.status();

src/utils/authenticate.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import type {
1010
import { env, Uri, window } from "vscode";
1111

1212
import { assertIsError } from "./assert.ts";
13+
import { createFileStatusTracker } from "./file-status-tracker.ts";
14+
import type { StatusTracker } from "./file-status-tracker.ts";
1315

1416
/**
1517
* Registers a {@link UriHandler} that waits for an authentication token from the browser,
@@ -160,3 +162,23 @@ export async function readAuthToken(): Promise<string> {
160162
export async function checkIsAuthenticated() {
161163
return (await readAuthToken()) !== "";
162164
}
165+
166+
/**
167+
* Creates a status tracker that monitors the LocalStack authentication file for changes.
168+
* When the file is changed, the provided check function is called to determine the current setup status.
169+
* Emits status changes to registered listeners.
170+
*
171+
* @param outputChannel - Channel for logging output and trace messages.
172+
* @param outputChannel
173+
* @returns A {@link StatusTracker} instance for querying status, subscribing to changes, and disposing resources.
174+
*/
175+
export function createLocalStackAuthenticationStatusTracker(
176+
outputChannel: LogOutputChannel,
177+
): StatusTracker {
178+
return createFileStatusTracker(
179+
outputChannel,
180+
"[setup-status.localstack-authentication]",
181+
[LOCALSTACK_AUTH_FILENAME],
182+
async () => ((await checkIsAuthenticated()) ? "ok" : "setup_required"),
183+
);
184+
}

src/utils/cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { CLI_PATHS, LOCALSTACK_DOCKER_IMAGE_NAME } from "../constants.ts";
1010

1111
import { createValueEmitter } from "./emitter.ts";
1212
import { exec } from "./exec.ts";
13-
import { immediateOnce } from "./immediate-once.ts";
14-
import type { SetupStatus } from "./setup-status.ts";
13+
import { createOnceImmediate } from "./once-immediate.ts";
14+
import type { SetupStatus } from "./setup.ts";
1515
import { spawn } from "./spawn.ts";
1616
import type { SpawnOptions } from "./spawn.ts";
1717

@@ -177,7 +177,7 @@ export function createCliStatusTracker(
177177
const cliPath = createValueEmitter<string | undefined>();
178178
const outdated = createValueEmitter<boolean | undefined>();
179179

180-
const track = immediateOnce(async () => {
180+
const track = createOnceImmediate(async () => {
181181
const newCli = await findLocalStack().catch(() => undefined);
182182
outputChannel.info(`[cli]: findLocalStack = ${newCli?.cliPath}`);
183183

src/utils/configure-aws.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { window } from "vscode";
77
import type { LogOutputChannel } from "vscode";
88

99
import { readAuthToken } from "./authenticate.ts";
10+
import { createFileStatusTracker } from "./file-status-tracker.ts";
11+
import type { StatusTracker } from "./file-status-tracker.ts";
1012
import { parseIni, serializeIni, updateIniSection } from "./ini-parser.ts";
1113
import type { IniFile, IniSection } from "./ini-parser.ts";
1214
import type { Telemetry } from "./telemetry.ts";
@@ -501,3 +503,22 @@ export async function checkIsProfileConfigured(): Promise<boolean> {
501503
return false;
502504
}
503505
}
506+
507+
/**
508+
* Creates a status tracker that monitors the AWS profile files for changes.
509+
* When the file is changed, the provided check function is called to determine the current setup status.
510+
* Emits status changes to registered listeners.
511+
*
512+
* @param outputChannel - Channel for logging output and trace messages.
513+
* @returns A {@link StatusTracker} instance for querying status, subscribing to changes, and disposing resources.
514+
*/
515+
export function createAwsProfileStatusTracker(
516+
outputChannel: LogOutputChannel,
517+
): StatusTracker {
518+
return createFileStatusTracker(
519+
outputChannel,
520+
"[setup-status.aws-profile]",
521+
[AWS_CONFIG_FILENAME, AWS_CREDENTIALS_FILENAME],
522+
async () => ((await checkIsProfileConfigured()) ? "ok" : "setup_required"),
523+
);
524+
}

src/utils/emitter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { immediateOnce } from "./immediate-once.ts";
1+
import { createOnceImmediate } from "./once-immediate.ts";
22

33
export type Callback<T> = (value: T) => Promise<void> | void;
44

@@ -12,7 +12,7 @@ export function createValueEmitter<T>(): ValueEmitter<T> {
1212
let currentValue: T;
1313
const callbacks: Callback<T>[] = [];
1414

15-
const emit = immediateOnce(async () => {
15+
const emit = createOnceImmediate(async () => {
1616
for (const callback of callbacks) {
1717
try {
1818
await callback(currentValue);

src/utils/file-status-tracker.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { watch } from "chokidar";
2+
import type { LogOutputChannel } from "vscode";
3+
4+
import { createValueEmitter } from "./emitter.ts";
5+
import { createOnceImmediate } from "./once-immediate.ts";
6+
import type { SetupStatus } from "./setup.ts";
7+
8+
export interface StatusTracker {
9+
status(): SetupStatus | undefined;
10+
onChange(callback: (status: SetupStatus | undefined) => void): void;
11+
dispose(): Promise<void>;
12+
check(): void;
13+
}
14+
/**
15+
* Creates a status tracker that monitors the given files for changes.
16+
* When a file is added, changed, or deleted, the provided check function is called
17+
* to determine the current setup status. Emits status changes to registered listeners.
18+
*
19+
* @param outputChannel - Channel for logging output and trace messages.
20+
* @param outputChannelPrefix - Prefix for log messages.
21+
* @param files - Array of file paths to watch.
22+
* @param check - Function that returns the current SetupStatus (sync or async).
23+
* @returns A {@link StatusTracker} instance for querying status, subscribing to changes, and disposing resources.
24+
*/
25+
export function createFileStatusTracker(
26+
outputChannel: LogOutputChannel,
27+
outputChannelPrefix: string,
28+
files: string[],
29+
check: () => Promise<SetupStatus | undefined> | SetupStatus | undefined,
30+
): StatusTracker {
31+
// let status: SetupStatus | undefined;
32+
// const emitter = createEmitter<SetupStatus | undefined>(outputChannel);
33+
const status = createValueEmitter<SetupStatus | undefined>();
34+
35+
const updateStatus = createOnceImmediate(async () => {
36+
const newStatus = await Promise.resolve(check());
37+
status.setValue(newStatus);
38+
// if (status !== newStatus) {
39+
// status = newStatus;
40+
// outputChannel.trace(
41+
// `${outputChannelPrefix} File status changed to ${status}`,
42+
// );
43+
// await emitter.emit(status);
44+
// }
45+
});
46+
47+
const watcher = watch(files)
48+
.on("change", (path) => {
49+
outputChannel.trace(`${outputChannelPrefix} ${path} changed`);
50+
updateStatus();
51+
})
52+
.on("unlink", (path) => {
53+
outputChannel.trace(`${outputChannelPrefix} ${path} deleted`);
54+
updateStatus();
55+
})
56+
.on("add", (path) => {
57+
outputChannel.trace(`${outputChannelPrefix} ${path} added`);
58+
updateStatus();
59+
})
60+
.on("error", (error) => {
61+
outputChannel.error(`${outputChannelPrefix} Error watching file`);
62+
outputChannel.error(error instanceof Error ? error : String(error));
63+
});
64+
65+
// Update the status immediately on file tracker initialization
66+
void updateStatus();
67+
68+
return {
69+
status() {
70+
return status.value();
71+
},
72+
onChange(callback) {
73+
status.onChange(callback);
74+
// emitter.on(callback);
75+
// if (status) {
76+
// callback(status);
77+
// }
78+
},
79+
async dispose() {
80+
await watcher.close();
81+
},
82+
check() {
83+
return updateStatus();
84+
},
85+
};
86+
}

src/utils/install.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from "../constants.ts";
1414

1515
import { exec } from "./exec.ts";
16-
import { minDelay } from "./promises.ts";
16+
import { minDelay } from "./min-delay.ts";
1717
import {
1818
spawnElevatedDarwin,
1919
spawnElevatedLinux,

0 commit comments

Comments
 (0)