Skip to content

Commit b79c121

Browse files
committed
refactor(cli): update notification handling to use startNotificationFetch
1 parent 4eba496 commit b79c121

2 files changed

Lines changed: 54 additions & 32 deletions

File tree

packages/cli/src/actions/action-utils.ts

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -219,39 +219,60 @@ export async function getZenStackPackages(
219219
return result.filter((p) => !!p);
220220
}
221221

222-
const FETCH_CLI_CONFIG_TIMEOUT = 500;
223-
const CLI_CONFIG_ENDPOINT = 'https://zenstack.dev/config/cli.json';
222+
const FETCH_CLI_MAX_TIME = 1000;
223+
const CLI_CONFIG_ENDPOINT = 'https://zenstack.dev/config/cli-v3.json';
224224

225-
export async function showNotification() {
226-
try {
227-
const fetchResult = await fetch(CLI_CONFIG_ENDPOINT, {
228-
headers: { accept: 'application/json' },
229-
signal: AbortSignal.timeout(FETCH_CLI_CONFIG_TIMEOUT),
230-
});
225+
const notificationSchema = z.object({
226+
notifications: z.array(z.object({ title: z.string(), url: z.url().optional(), active: z.boolean() })),
227+
});
231228

232-
if (!fetchResult.ok) {
233-
return;
234-
}
229+
/**
230+
* Starts the notification fetch in the background. Returns a callback that,
231+
* when invoked check if the fetch is complete. If not complete, it will wait until the max time is reached.
232+
* After that, if fetch is still not complete, just return.
233+
*/
234+
export function startNotificationFetch() {
235+
let fetchedData: z.infer<typeof notificationSchema> | undefined = undefined;
236+
let fetchComplete = false;
235237

236-
const data = await fetchResult.json();
237-
const schema = z.object({
238-
notifications: z.array(z.object({ title: z.string(), url: z.url().optional(), active: z.boolean() })),
238+
const start = Date.now();
239+
240+
fetch(CLI_CONFIG_ENDPOINT, {
241+
headers: { accept: 'application/json' },
242+
})
243+
.then(async (res) => {
244+
if (!res.ok) return;
245+
const data = await res.json();
246+
const parseResult = notificationSchema.safeParse(data);
247+
if (parseResult.success) {
248+
fetchedData = parseResult.data;
249+
}
250+
})
251+
.catch(() => {
252+
// noop
253+
})
254+
.finally(() => {
255+
fetchComplete = true;
239256
});
240-
const parseResult = schema.safeParse(data);
241257

242-
if (parseResult.success) {
243-
const activeItems = parseResult.data.notifications.filter((item) => item.active);
244-
// return a random active item
245-
if (activeItems.length > 0) {
246-
const item = activeItems[Math.floor(Math.random() * activeItems.length)]!;
247-
if (item.url) {
248-
console.log(terminalLink(item.title, item.url));
249-
} else {
250-
console.log(item.title);
251-
}
258+
return async () => {
259+
const elapsed = Date.now() - start;
260+
261+
if (!fetchComplete && elapsed < FETCH_CLI_MAX_TIME) {
262+
// wait for the timeout
263+
await new Promise((resolve) => setTimeout(resolve, FETCH_CLI_MAX_TIME - elapsed));
264+
}
265+
266+
if (!fetchComplete || !fetchedData) return;
267+
const activeItems = fetchedData.notifications.filter((item) => item.active);
268+
// show a random active item
269+
if (activeItems.length > 0) {
270+
const item = activeItems[Math.floor(Math.random() * activeItems.length)]!;
271+
if (item.url) {
272+
console.log(terminalLink(item.title, item.url));
273+
} else {
274+
console.log(item.title);
252275
}
253276
}
254-
} catch {
255-
// noop
256-
}
277+
};
257278
}

packages/cli/src/actions/generate.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { CliError } from '../cli-error';
1414
import * as corePlugins from '../plugins';
1515
import { getOutputPath, getSchemaFile, getZenStackPackages, loadSchemaDocument } from './action-utils';
1616
import semver from 'semver';
17-
import { showNotification } from './action-utils';
17+
import { startNotificationFetch } from './action-utils';
1818

1919
type Options = {
2020
schema?: string;
@@ -37,11 +37,12 @@ export async function run(options: Options) {
3737
} catch (err) {
3838
console.warn(colors.yellow(`Failed to check for mismatched ZenStack packages: ${err}`));
3939
}
40+
41+
const maybeShowNotification = !options.offline && !options.silent ? startNotificationFetch() : undefined;
42+
4043
const model = await pureGenerate(options, false);
4144

42-
if (!options.offline && !options.silent) {
43-
await showNotification();
44-
}
45+
await maybeShowNotification?.();
4546

4647
if (options.watch) {
4748
const logsEnabled = !options.silent;

0 commit comments

Comments
 (0)