@epic-web/workshop-utils 5.0.0 → 5.0.2
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/dist/esm/apps.server.d.ts +9 -2
- package/dist/esm/apps.server.d.ts.map +1 -1
- package/dist/esm/apps.server.js +153 -79
- package/dist/esm/apps.server.js.map +1 -1
- package/dist/esm/cache.server.d.ts +6 -0
- package/dist/esm/cache.server.d.ts.map +1 -1
- package/dist/esm/cache.server.js +1 -0
- package/dist/esm/cache.server.js.map +1 -1
- package/dist/esm/compile-mdx.server.d.ts.map +1 -1
- package/dist/esm/compile-mdx.server.js +1 -4
- package/dist/esm/compile-mdx.server.js.map +1 -1
- package/dist/esm/config.server.d.ts +0 -1
- package/dist/esm/config.server.d.ts.map +1 -1
- package/dist/esm/config.server.js +11 -7
- package/dist/esm/config.server.js.map +1 -1
- package/dist/esm/modified-time.server.d.ts +7 -0
- package/dist/esm/modified-time.server.d.ts.map +1 -0
- package/dist/esm/modified-time.server.js +80 -0
- package/dist/esm/modified-time.server.js.map +1 -0
- package/package.json +10 -10
- package/dist/esm/change-tracker.server.d.ts +0 -8
- package/dist/esm/change-tracker.server.d.ts.map +0 -1
- package/dist/esm/change-tracker.server.js +0 -32
- package/dist/esm/change-tracker.server.js.map +0 -1
|
@@ -2,6 +2,9 @@ import { type CacheEntry } from '@epic-web/cachified';
|
|
|
2
2
|
import '@total-typescript/ts-reset';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { type Timings } from './timing.server.js';
|
|
5
|
+
declare global {
|
|
6
|
+
var __epicshop_apps_initialized__: boolean | undefined;
|
|
7
|
+
}
|
|
5
8
|
export declare const workshopRoot: string;
|
|
6
9
|
type CachifiedOptions = {
|
|
7
10
|
timings?: Timings;
|
|
@@ -3138,8 +3141,8 @@ export declare function isPlaygroundApp(app: any): app is PlaygroundApp;
|
|
|
3138
3141
|
export declare function isExampleApp(app: any): app is ExampleApp;
|
|
3139
3142
|
export declare function isExerciseStepApp(app: any): app is ExerciseStepApp;
|
|
3140
3143
|
export declare const modifiedTimes: Map<string, number>;
|
|
3141
|
-
export declare function init(): void
|
|
3142
|
-
export declare function
|
|
3144
|
+
export declare function init(): Promise<void>;
|
|
3145
|
+
export declare function setModifiedTimesForAppDirs(...filePaths: Array<string>): void;
|
|
3143
3146
|
export declare function getForceFreshForDir(cacheEntry: CacheEntry | null | undefined, ...dirs: Array<string | undefined | null>): true | undefined;
|
|
3144
3147
|
export declare function getExercises({ timings, request, }?: CachifiedOptions): Promise<Array<Exercise>>;
|
|
3145
3148
|
export declare function getApps({ timings, request, forceFresh, }?: CachifiedOptions & {
|
|
@@ -4179,5 +4182,9 @@ export declare function getWorkshopFinished({ request, }?: {
|
|
|
4179
4182
|
readonly relativePath: "exercises/finished.mdx";
|
|
4180
4183
|
}>;
|
|
4181
4184
|
export declare function getRelativePath(filePath: string): string;
|
|
4185
|
+
/**
|
|
4186
|
+
* Given a file path, this will determine the path to the app that file belongs to.
|
|
4187
|
+
*/
|
|
4188
|
+
export declare function getAppPathFromFilePath(filePath: string): string | null;
|
|
4182
4189
|
export {};
|
|
4183
4190
|
//# sourceMappingURL=apps.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.server.d.ts","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"apps.server.d.ts","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAIrD,OAAO,4BAA4B,CAAA;AAKnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAuBvB,OAAO,EAA6B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,6BAA6B,EAAE,OAAO,GAAG,SAAS,CAAA;CACtD;AAGD,eAAO,MAAM,YAAY,QAC0B,CAAA;AAUnD,KAAK,gBAAgB,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAkChE,QAAA,MAAM,yBAAyB;IA/B9B,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BtI,CAAA;AAEF,QAAA,MAAM,gBAAgB;IApCrB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCtI,CAAA;AAEF,QAAA,MAAM,iBAAiB;IAzCtB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCtI,CAAA;AAEF,QAAA,MAAM,gBAAgB;IA9CrB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CtI,CAAA;AAEF,QAAA,MAAM,mBAAmB;IAlDxB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDtI,CAAA;AAEF,QAAA,MAAM,cAAc;IACnB,2CAA2C;;IAE3C,uIAAuI;;IAEvI,oFAAoF;;;;;;;;;YA7DpF,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAJvI,sCAAsC;;QAEtC,qFAAqF;;QAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAJvI,sCAAsC;;QAEtC,qFAAqF;;QAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFtI,CAAA;AAEF,QAAA,MAAM,qBAAqB;IA1F1B,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsF5D,CAAA;AAE5E,QAAA,MAAM,SAAS;IA5Fd,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4FtI,CAAA;AAIF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAC3E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAC3C,MAAM,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;AAEjC,KAAK,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE9C,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,CAE1C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,UAAU,CAExD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,WAAW,CAE1D;AAED,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,GAAG,GACN,GAAG,IAAI,UAAU,GAAG;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAEvC;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,GAAG,GACN,GAAG,IAAI,WAAW,GAAG;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAExC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,aAAa,CAE9D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,UAAU,CAExD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAElE;AAeD,eAAO,MAAM,aAAa,qBAGzB,CAAA;AAED,wBAAsB,IAAI,kBAoDzB;AASD,wBAAgB,0BAA0B,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,QAUrE;AAED,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACzC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,oBAezC;AAuDD,wBAAsB,YAAY,CAAC,EAClC,OAAO,EACP,OAAO,GACP,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CA6ClD;AAID,wBAAsB,OAAO,CAAC,EAC7B,OAAO,EACP,OAAO,EACP,UAAU,GACV,GAAE,gBAAgB,GAAG;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAoFxE;AAQD;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACrD,iBAAiB,EAAE,MAAM;;;;SA0BzB;AAkND,wBAAsB,gBAAgB,CAAC,EACtC,OAAO,EACP,OAAO,GACP,GAAE,gBAAqB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAkEvD;AA+OD,wBAAsB,WAAW,CAChC,cAAc,EAAE,MAAM,GAAG,MAAM,EAC/B,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAI3C;AAED,wBAAsB,eAAe,CACpC,cAAc,EAAE,MAAM,GAAG,MAAM,EAC/B,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAU3C;AAED,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,EAC5C,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAO3C;AAQD,wBAAsB,cAAc,CACnC,MAAM,EAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,EACD,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAqB3C;AAED,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAI3C;AAED,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,eAAe,EACpB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAS3C;AAED,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,eAAe,EACpB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,gBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAU3C;AACD,wBAAgB,eAAe,CAC9B,GAAG,EAAE,eAAe,EACpB,EACC,QAAQ,EACR,YAAY,GACZ,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,eAAe,CAAA;CAAO,UAgB7D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAGpD;AAED,wBAAsB,aAAa,CAClC,MAAM,EAAE,MAAM,EACd,EAAE,KAAK,EAAE,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,iBAwInC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,2BAgBzC;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,UAmB5D;AAED,wBAAsB,uBAAuB,CAAC,EAC7C,OAAO,GACP,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;;;GAc5B;AAED,wBAAsB,mBAAmB,CAAC,EACzC,OAAO,GACP,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;;;GAkB5B;AAID,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,UAK/C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2BtE"}
|
package/dist/esm/apps.server.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { remember } from '@epic-web/remember';
|
|
4
|
+
import chokidar from 'chokidar';
|
|
4
5
|
/// TODO: figure out why this import is necessary (without it tsc seems to not honor the boolean reset 🤷♂️)
|
|
5
6
|
import '@total-typescript/ts-reset';
|
|
7
|
+
import closeWithGrace from 'close-with-grace';
|
|
6
8
|
import { execa } from 'execa';
|
|
7
9
|
import fsExtra from 'fs-extra';
|
|
8
|
-
import { glob } from 'glob';
|
|
9
10
|
import { globby, isGitIgnored } from 'globby';
|
|
10
11
|
import { z } from 'zod';
|
|
11
12
|
import { appsCache, cachified, exampleAppCache, playgroundAppCache, problemAppCache, solutionAppCache, } from './cache.server.js';
|
|
12
|
-
import { getOptionalWatcher, getWatcher } from './change-tracker.server.js';
|
|
13
13
|
import { compileMdx } from './compile-mdx.server.js';
|
|
14
|
-
import {
|
|
14
|
+
import { getAppConfig, getStackBlitzUrl, getWorkshopConfig, } from './config.server.js';
|
|
15
15
|
import { getEnv, init as initEnv } from './env.server.js';
|
|
16
|
+
import { getDirModifiedTime } from './modified-time.server.js';
|
|
16
17
|
import { closeProcess, isAppRunning, runAppDev, waitOnApp, } from './process-manager.server.js';
|
|
17
|
-
import { getServerTimeHeader } from './timing.server.js';
|
|
18
|
+
import { getServerTimeHeader, time } from './timing.server.js';
|
|
18
19
|
import { getErrorMessage } from './utils.js';
|
|
19
|
-
|
|
20
|
+
global.__epicshop_apps_initialized__ ??= false;
|
|
20
21
|
export const workshopRoot = (process.env.EPICSHOP_CONTEXT_CWD =
|
|
21
22
|
process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd());
|
|
22
23
|
const playgroundAppNameInfoPath = path.join(workshopRoot, 'node_modules', '.cache', 'epicshop', 'playground.json');
|
|
@@ -141,28 +142,54 @@ async function firstToExist(...files) {
|
|
|
141
142
|
return index === -1 ? null : files[index];
|
|
142
143
|
}
|
|
143
144
|
export const modifiedTimes = remember('modified_times', () => new Map());
|
|
144
|
-
export function init() {
|
|
145
|
-
if (
|
|
145
|
+
export async function init() {
|
|
146
|
+
if (global.__epicshop_apps_initialized__)
|
|
146
147
|
return;
|
|
147
|
-
|
|
148
|
+
global.__epicshop_apps_initialized__ = true;
|
|
148
149
|
const config = getWorkshopConfig();
|
|
149
150
|
process.env.EPICSHOP_GITHUB_REPO = config.githubRepo;
|
|
150
151
|
process.env.EPICSHOP_GITHUB_ROOT = config.githubRoot;
|
|
151
152
|
initEnv();
|
|
152
153
|
global.ENV = getEnv();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
if (!ENV.EPICSHOP_DEPLOYED) {
|
|
155
|
+
const isIgnored = await isGitIgnored({ cwd: workshopRoot });
|
|
156
|
+
// watch the README, FINISHED, and package.json for changes that affect the apps
|
|
157
|
+
const filesToWatch = ['README.mdx', 'FINISHED.mdx', 'package.json'];
|
|
158
|
+
const chok = chokidar.watch(['examples', 'playground', 'exercises'], {
|
|
159
|
+
cwd: workshopRoot,
|
|
160
|
+
ignoreInitial: true,
|
|
161
|
+
ignored(filePath, stats) {
|
|
162
|
+
if (isIgnored(filePath))
|
|
163
|
+
return true;
|
|
164
|
+
if (filePath.includes('.git'))
|
|
165
|
+
return true;
|
|
166
|
+
if (stats?.isDirectory()) {
|
|
167
|
+
if (filePath.endsWith('playground'))
|
|
168
|
+
return false;
|
|
169
|
+
const pathParts = filePath.split(path.sep);
|
|
170
|
+
if (pathParts.at(-2) === 'examples')
|
|
171
|
+
return false;
|
|
172
|
+
// steps
|
|
173
|
+
if (pathParts.at(-3) === 'exercises')
|
|
174
|
+
return false;
|
|
175
|
+
// exercises
|
|
176
|
+
if (pathParts.at(-2) === 'exercises')
|
|
177
|
+
return false;
|
|
178
|
+
// the exercise dir itself
|
|
179
|
+
if (pathParts.at(-1) === 'exercises')
|
|
180
|
+
return false;
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
return stats?.isFile()
|
|
184
|
+
? !filesToWatch.some((file) => filePath.endsWith(file))
|
|
185
|
+
: false;
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
chok.on('all', (_event, filePath) => {
|
|
189
|
+
setModifiedTimesForAppDirs(path.join(workshopRoot, filePath));
|
|
190
|
+
});
|
|
191
|
+
closeWithGrace(() => chok.close());
|
|
164
192
|
}
|
|
165
|
-
getWatcher()?.on('all', handleFileChanges);
|
|
166
193
|
}
|
|
167
194
|
function getForceFresh(cacheEntry) {
|
|
168
195
|
if (!cacheEntry)
|
|
@@ -172,8 +199,17 @@ function getForceFresh(cacheEntry) {
|
|
|
172
199
|
return undefined;
|
|
173
200
|
return latestModifiedTime > cacheEntry.metadata.createdTime ? true : undefined;
|
|
174
201
|
}
|
|
175
|
-
export function
|
|
176
|
-
|
|
202
|
+
export function setModifiedTimesForAppDirs(...filePaths) {
|
|
203
|
+
const now = Date.now();
|
|
204
|
+
for (const filePath of filePaths) {
|
|
205
|
+
const appDir = getAppPathFromFilePath(filePath);
|
|
206
|
+
if (appDir) {
|
|
207
|
+
modifiedTimes.set(appDir, now);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.warn(`filePath ${filePath} does not match any app dir`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
177
213
|
}
|
|
178
214
|
export function getForceFreshForDir(cacheEntry, ...dirs) {
|
|
179
215
|
const truthyDirs = dirs.filter(Boolean);
|
|
@@ -275,8 +311,7 @@ export async function getExercises({ timings, request, } = {}) {
|
|
|
275
311
|
}
|
|
276
312
|
let appCallCount = 0;
|
|
277
313
|
export async function getApps({ timings, request, forceFresh, } = {}) {
|
|
278
|
-
|
|
279
|
-
init();
|
|
314
|
+
await init();
|
|
280
315
|
const key = 'apps';
|
|
281
316
|
const apps = await cachified({
|
|
282
317
|
key,
|
|
@@ -289,10 +324,24 @@ export async function getApps({ timings, request, forceFresh, } = {}) {
|
|
|
289
324
|
ttl: 1000 * 60 * 60 * 24,
|
|
290
325
|
forceFresh: forceFresh ?? getForceFresh(appsCache.get(key)),
|
|
291
326
|
getFreshValue: async () => {
|
|
292
|
-
const playgroundApp = await
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
327
|
+
const [playgroundApp, problemApps, solutionApps, exampleApps] = await Promise.all([
|
|
328
|
+
time(() => getPlaygroundApp({ request, timings }), {
|
|
329
|
+
type: 'getPlaygroundApp',
|
|
330
|
+
timings,
|
|
331
|
+
}),
|
|
332
|
+
time(() => getProblemApps({ request, timings }), {
|
|
333
|
+
type: 'getProblemApps',
|
|
334
|
+
timings,
|
|
335
|
+
}),
|
|
336
|
+
time(() => getSolutionApps({ request, timings }), {
|
|
337
|
+
type: 'getSolutionApps',
|
|
338
|
+
timings,
|
|
339
|
+
}),
|
|
340
|
+
time(() => getExampleApps({ request, timings }), {
|
|
341
|
+
type: 'getExampleApps',
|
|
342
|
+
timings,
|
|
343
|
+
}),
|
|
344
|
+
]);
|
|
296
345
|
const sortedApps = [
|
|
297
346
|
playgroundApp,
|
|
298
347
|
...problemApps,
|
|
@@ -389,18 +438,38 @@ export function extractNumbersAndTypeFromAppNameOrPath(fullPathOrAppName) {
|
|
|
389
438
|
}
|
|
390
439
|
async function getProblemDirs() {
|
|
391
440
|
const exercisesDir = path.join(workshopRoot, 'exercises');
|
|
392
|
-
const problemDirs =
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
441
|
+
const problemDirs = [];
|
|
442
|
+
const exerciseSubDirs = await readDir(exercisesDir);
|
|
443
|
+
for (const subDir of exerciseSubDirs) {
|
|
444
|
+
const fullSubDir = path.join(exercisesDir, subDir);
|
|
445
|
+
// catch handles non-directories without us having to bother checking
|
|
446
|
+
// whether it's a directory
|
|
447
|
+
const subDirContents = await readDir(fullSubDir).catch(() => null);
|
|
448
|
+
if (!subDirContents)
|
|
449
|
+
continue;
|
|
450
|
+
const problemSubDirs = subDirContents
|
|
451
|
+
.filter((dir) => dir.includes('.problem'))
|
|
452
|
+
.map((dir) => path.join(fullSubDir, dir));
|
|
453
|
+
problemDirs.push(...problemSubDirs);
|
|
454
|
+
}
|
|
396
455
|
return problemDirs;
|
|
397
456
|
}
|
|
398
457
|
async function getSolutionDirs() {
|
|
399
458
|
const exercisesDir = path.join(workshopRoot, 'exercises');
|
|
400
|
-
const solutionDirs =
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
459
|
+
const solutionDirs = [];
|
|
460
|
+
const exerciseSubDirs = await readDir(exercisesDir);
|
|
461
|
+
for (const subDir of exerciseSubDirs) {
|
|
462
|
+
const fullSubDir = path.join(exercisesDir, subDir);
|
|
463
|
+
// catch handles non-directories without us having to bother checking
|
|
464
|
+
// whether it's a directory
|
|
465
|
+
const subDirContents = await readDir(fullSubDir).catch(() => null);
|
|
466
|
+
if (!subDirContents)
|
|
467
|
+
continue;
|
|
468
|
+
const solutionSubDirs = subDirContents
|
|
469
|
+
.filter((dir) => dir.includes('.solution'))
|
|
470
|
+
.map((dir) => path.join(fullSubDir, dir));
|
|
471
|
+
solutionDirs.push(...solutionSubDirs);
|
|
472
|
+
}
|
|
404
473
|
return solutionDirs;
|
|
405
474
|
}
|
|
406
475
|
/**
|
|
@@ -622,7 +691,7 @@ async function getExampleAppFromPath(fullPath, index, request) {
|
|
|
622
691
|
}
|
|
623
692
|
async function getExampleApps({ timings, request, } = {}) {
|
|
624
693
|
const examplesDir = path.join(workshopRoot, 'examples');
|
|
625
|
-
const exampleDirs = (await
|
|
694
|
+
const exampleDirs = (await readDir(examplesDir)).map((p) => path.join(examplesDir, p));
|
|
626
695
|
const exampleApps = [];
|
|
627
696
|
for (const exampleDir of exampleDirs) {
|
|
628
697
|
const index = exampleDirs.indexOf(exampleDir);
|
|
@@ -635,10 +704,12 @@ async function getExampleApps({ timings, request, } = {}) {
|
|
|
635
704
|
timingKey: exampleDir.replace(`${examplesDir}${path.sep}`, ''),
|
|
636
705
|
request,
|
|
637
706
|
forceFresh: getForceFreshForDir(exampleAppCache.get(key), exampleDir),
|
|
638
|
-
getFreshValue:
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
707
|
+
getFreshValue: async () => {
|
|
708
|
+
return getExampleAppFromPath(exampleDir, index, request).catch((error) => {
|
|
709
|
+
console.error(error);
|
|
710
|
+
return null;
|
|
711
|
+
});
|
|
712
|
+
},
|
|
642
713
|
});
|
|
643
714
|
if (exampleApp)
|
|
644
715
|
exampleApps.push(exampleApp);
|
|
@@ -701,10 +772,12 @@ async function getSolutionApps({ timings, request, } = {}) {
|
|
|
701
772
|
request,
|
|
702
773
|
ttl: 1000 * 60 * 60 * 24,
|
|
703
774
|
forceFresh: getForceFreshForDir(solutionAppCache.get(solutionDir), solutionDir),
|
|
704
|
-
getFreshValue:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
775
|
+
getFreshValue: async () => {
|
|
776
|
+
return getSolutionAppFromPath(solutionDir, request).catch((error) => {
|
|
777
|
+
console.error(error);
|
|
778
|
+
return null;
|
|
779
|
+
});
|
|
780
|
+
},
|
|
708
781
|
});
|
|
709
782
|
if (solutionApp)
|
|
710
783
|
solutionApps.push(solutionApp);
|
|
@@ -768,10 +841,12 @@ async function getProblemApps({ timings, request, } = {}) {
|
|
|
768
841
|
request,
|
|
769
842
|
ttl: 1000 * 60 * 60 * 24,
|
|
770
843
|
forceFresh: getForceFreshForDir(problemAppCache.get(problemDir), problemDir, solutionDir),
|
|
771
|
-
getFreshValue:
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
844
|
+
getFreshValue: async () => {
|
|
845
|
+
return getProblemAppFromPath(problemDir).catch((error) => {
|
|
846
|
+
console.error(error);
|
|
847
|
+
return null;
|
|
848
|
+
});
|
|
849
|
+
},
|
|
775
850
|
});
|
|
776
851
|
if (problemApp)
|
|
777
852
|
problemApps.push(problemApp);
|
|
@@ -867,10 +942,8 @@ export async function getAppFromFile(filePath) {
|
|
|
867
942
|
return apps.find((app) => filePath.startsWith(app.fullPath));
|
|
868
943
|
}
|
|
869
944
|
export async function setPlayground(srcDir, { reset } = {}) {
|
|
870
|
-
const isIgnored = await isGitIgnored({ cwd: srcDir });
|
|
871
945
|
const destDir = path.join(workshopRoot, 'playground');
|
|
872
|
-
const
|
|
873
|
-
getOptionalWatcher()?.unwatch(playgroundFiles);
|
|
946
|
+
const isIgnored = await isGitIgnored({ cwd: srcDir });
|
|
874
947
|
const playgroundApp = await getAppByName('playground');
|
|
875
948
|
const playgroundWasRunning = playgroundApp
|
|
876
949
|
? isAppRunning(playgroundApp)
|
|
@@ -979,12 +1052,12 @@ export async function setPlayground(srcDir, { reset } = {}) {
|
|
|
979
1052
|
},
|
|
980
1053
|
});
|
|
981
1054
|
}
|
|
1055
|
+
// since we are running without the watcher we need to set the modified time
|
|
1056
|
+
modifiedTimes.set(destDir, Date.now());
|
|
982
1057
|
if (playgroundApp && restartPlayground) {
|
|
983
1058
|
await runAppDev(playgroundApp);
|
|
984
1059
|
await waitOnApp(playgroundApp);
|
|
985
1060
|
}
|
|
986
|
-
getOptionalWatcher()?.add(playgroundFiles);
|
|
987
|
-
modifiedTimes.set(destDir, Date.now());
|
|
988
1061
|
}
|
|
989
1062
|
/**
|
|
990
1063
|
* The playground is based on another app. This returns the app the playground
|
|
@@ -1005,31 +1078,6 @@ export async function getPlaygroundAppName() {
|
|
|
1005
1078
|
return null;
|
|
1006
1079
|
}
|
|
1007
1080
|
}
|
|
1008
|
-
async function getDirModifiedTime(dir) {
|
|
1009
|
-
// we can't use modifiedTimes because it only stores the modified times of
|
|
1010
|
-
// things the app started.
|
|
1011
|
-
const isIgnored = await isGitIgnored({ cwd: dir });
|
|
1012
|
-
const files = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
1013
|
-
const modifiedTimes = await Promise.all(files.map(async (file) => {
|
|
1014
|
-
if (isIgnored(file.name))
|
|
1015
|
-
return 0;
|
|
1016
|
-
const filePath = path.join(dir, file.name);
|
|
1017
|
-
if (file.isDirectory()) {
|
|
1018
|
-
return getDirModifiedTime(filePath);
|
|
1019
|
-
}
|
|
1020
|
-
else {
|
|
1021
|
-
try {
|
|
1022
|
-
const { mtimeMs } = await fs.promises.stat(filePath);
|
|
1023
|
-
return mtimeMs;
|
|
1024
|
-
}
|
|
1025
|
-
catch {
|
|
1026
|
-
// Handle errors (e.g., file access permissions, file has been moved or deleted)
|
|
1027
|
-
return 0;
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}));
|
|
1031
|
-
return Math.max(0, ...modifiedTimes); // Ensure there is a default of 0 if all files are ignored
|
|
1032
|
-
}
|
|
1033
1081
|
export function getAppDisplayName(a, allApps) {
|
|
1034
1082
|
let displayName = `${a.title} (${a.type})`;
|
|
1035
1083
|
if (isExerciseStepApp(a)) {
|
|
@@ -1079,4 +1127,30 @@ export function getRelativePath(filePath) {
|
|
|
1079
1127
|
.replace(playgroundPath, `playground${path.sep}`)
|
|
1080
1128
|
.replace(exercisesPath, '');
|
|
1081
1129
|
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Given a file path, this will determine the path to the app that file belongs to.
|
|
1132
|
+
*/
|
|
1133
|
+
export function getAppPathFromFilePath(filePath) {
|
|
1134
|
+
const [, withinWorkshopRootHalf] = filePath.split(workshopRoot);
|
|
1135
|
+
if (!withinWorkshopRootHalf) {
|
|
1136
|
+
return null;
|
|
1137
|
+
}
|
|
1138
|
+
const [part1, part2, part3] = withinWorkshopRootHalf
|
|
1139
|
+
.split(path.sep)
|
|
1140
|
+
.filter(Boolean);
|
|
1141
|
+
// Check if the file is in the playground
|
|
1142
|
+
if (part1 === 'playground') {
|
|
1143
|
+
return path.join(workshopRoot, 'playground');
|
|
1144
|
+
}
|
|
1145
|
+
// Check if the file is in an example
|
|
1146
|
+
if (part1 === 'examples' && part2) {
|
|
1147
|
+
return path.join(workshopRoot, 'examples', part2);
|
|
1148
|
+
}
|
|
1149
|
+
// Check if the file is in an exercise
|
|
1150
|
+
if (part1 === 'exercises' && part2 && part3) {
|
|
1151
|
+
return path.join(workshopRoot, 'exercises', part2, part3);
|
|
1152
|
+
}
|
|
1153
|
+
// If we couldn't determine the app path, return null
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1082
1156
|
//# sourceMappingURL=apps.server.js.map
|