@wyw-in-js/transform 1.0.7 → 1.1.0
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/esm/cache.js +60 -5
- package/esm/cache.js.map +1 -1
- package/esm/index.js +2 -1
- package/esm/index.js.map +1 -1
- package/esm/module.js +8 -3
- package/esm/module.js.map +1 -1
- package/esm/transform/Entrypoint.js +8 -3
- package/esm/transform/Entrypoint.js.map +1 -1
- package/esm/transform/actions/BaseAction.js +2 -1
- package/esm/transform/actions/BaseAction.js.map +1 -1
- package/esm/transform/actions/actionRunner.js +2 -2
- package/esm/transform/actions/actionRunner.js.map +1 -1
- package/esm/transform/actions/types.js.map +1 -1
- package/esm/transform/generators/processEntrypoint.js +5 -1
- package/esm/transform/generators/processEntrypoint.js.map +1 -1
- package/esm/transform/generators/workflow.js +11 -0
- package/esm/transform/generators/workflow.js.map +1 -1
- package/esm/transform/helpers/loadWywOptions.js +1 -0
- package/esm/transform/helpers/loadWywOptions.js.map +1 -1
- package/esm/transform/types.js.map +1 -1
- package/esm/transform.js +45 -23
- package/esm/transform.js.map +1 -1
- package/esm/types.js.map +1 -1
- package/esm/utils/TransformDiagnostics.js +10 -0
- package/esm/utils/TransformDiagnostics.js.map +1 -0
- package/esm/utils/TransformMetadata.js +20 -0
- package/esm/utils/TransformMetadata.js.map +1 -1
- package/esm/utils/collectTemplateDependencies.js +9 -0
- package/esm/utils/collectTemplateDependencies.js.map +1 -1
- package/lib/cache.js +60 -5
- package/lib/cache.js.map +1 -1
- package/lib/index.js +29 -0
- package/lib/index.js.map +1 -1
- package/lib/module.js +10 -5
- package/lib/module.js.map +1 -1
- package/lib/transform/Entrypoint.js +8 -3
- package/lib/transform/Entrypoint.js.map +1 -1
- package/lib/transform/actions/BaseAction.js +2 -1
- package/lib/transform/actions/BaseAction.js.map +1 -1
- package/lib/transform/actions/actionRunner.js +2 -2
- package/lib/transform/actions/actionRunner.js.map +1 -1
- package/lib/transform/actions/types.js.map +1 -1
- package/lib/transform/generators/processEntrypoint.js +5 -1
- package/lib/transform/generators/processEntrypoint.js.map +1 -1
- package/lib/transform/generators/workflow.js +10 -0
- package/lib/transform/generators/workflow.js.map +1 -1
- package/lib/transform/helpers/loadWywOptions.js +1 -0
- package/lib/transform/helpers/loadWywOptions.js.map +1 -1
- package/lib/transform/types.js.map +1 -1
- package/lib/transform.js +45 -23
- package/lib/transform.js.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/utils/TransformDiagnostics.js +20 -0
- package/lib/utils/TransformDiagnostics.js.map +1 -0
- package/lib/utils/TransformMetadata.js +27 -1
- package/lib/utils/TransformMetadata.js.map +1 -1
- package/lib/utils/collectTemplateDependencies.js +9 -0
- package/lib/utils/collectTemplateDependencies.js.map +1 -1
- package/package.json +3 -3
- package/types/cache.d.ts +7 -0
- package/types/cache.js +59 -3
- package/types/index.d.ts +4 -2
- package/types/index.js +6 -1
- package/types/module.js +8 -3
- package/types/plugins/collector.d.ts +4 -1
- package/types/transform/Entrypoint.d.ts +1 -1
- package/types/transform/Entrypoint.js +8 -3
- package/types/transform/actions/BaseAction.d.ts +2 -1
- package/types/transform/actions/BaseAction.js +3 -1
- package/types/transform/actions/actionRunner.js +2 -2
- package/types/transform/actions/types.d.ts +4 -0
- package/types/transform/generators/processEntrypoint.js +4 -1
- package/types/transform/generators/workflow.js +8 -0
- package/types/transform/helpers/loadWywOptions.js +1 -0
- package/types/transform/types.d.ts +1 -0
- package/types/transform.js +47 -23
- package/types/types.d.ts +4 -1
- package/types/utils/TransformDiagnostics.d.ts +9 -0
- package/types/utils/TransformDiagnostics.js +15 -0
- package/types/utils/TransformMetadata.d.ts +22 -4
- package/types/utils/TransformMetadata.js +24 -1
- package/types/utils/collectTemplateDependencies.js +9 -0
package/types/cache.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare class TransformCacheCollection<TEntrypoint extends IBaseCachedEnt
|
|
|
25
25
|
readonly exports: Map<string, string[]>;
|
|
26
26
|
private readonly barrelManifestDependencies;
|
|
27
27
|
private contentHashes;
|
|
28
|
+
private fileMtimes;
|
|
28
29
|
private readonly exportDependencies;
|
|
29
30
|
constructor(caches?: Partial<ICaches<TEntrypoint>>);
|
|
30
31
|
add<TCache extends CacheNames, TValue extends MapValue<ICaches<TEntrypoint>[TCache]>>(cacheName: TCache, key: string, value: TValue): void;
|
|
@@ -40,6 +41,12 @@ export declare class TransformCacheCollection<TEntrypoint extends IBaseCachedEnt
|
|
|
40
41
|
private getCachedDependencies;
|
|
41
42
|
private getDependencyCache;
|
|
42
43
|
private hasCachedDependencies;
|
|
44
|
+
/**
|
|
45
|
+
* Fast check if a file changed on disk since last seen.
|
|
46
|
+
* Uses mtime as a fast path — only reads the file if mtime differs.
|
|
47
|
+
* Returns true if the file changed (cache was invalidated).
|
|
48
|
+
*/
|
|
49
|
+
checkFreshness(filename: string, strippedFilename: string): boolean;
|
|
43
50
|
private setContentHash;
|
|
44
51
|
}
|
|
45
52
|
export {};
|
package/types/cache.js
CHANGED
|
@@ -12,6 +12,13 @@ const parseRequest_1 = require("./utils/parseRequest");
|
|
|
12
12
|
function hashContent(content) {
|
|
13
13
|
return (0, crypto_1.createHash)('sha256').update(content).digest('hex');
|
|
14
14
|
}
|
|
15
|
+
function isMissingFileError(error) {
|
|
16
|
+
if (!error || typeof error !== 'object') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const { code } = error;
|
|
20
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
21
|
+
}
|
|
15
22
|
const cacheLogger = shared_1.logger.extend('cache');
|
|
16
23
|
const cacheNames = ['barrelManifests', 'entrypoints', 'exports'];
|
|
17
24
|
const loggers = cacheNames.reduce((acc, key) => ({
|
|
@@ -24,6 +31,7 @@ class TransformCacheCollection {
|
|
|
24
31
|
exports;
|
|
25
32
|
barrelManifestDependencies = new Map();
|
|
26
33
|
contentHashes = new Map();
|
|
34
|
+
fileMtimes = new Map();
|
|
27
35
|
exportDependencies = new Map();
|
|
28
36
|
constructor(caches = {}) {
|
|
29
37
|
this.barrelManifests = caches.barrelManifests || new Map();
|
|
@@ -157,7 +165,19 @@ class TransformCacheCollection {
|
|
|
157
165
|
for (const [, dependency] of dependenciesToCheck) {
|
|
158
166
|
const dependencyFilename = dependency.resolved;
|
|
159
167
|
if (dependencyFilename) {
|
|
160
|
-
|
|
168
|
+
let dependencyContent;
|
|
169
|
+
try {
|
|
170
|
+
dependencyContent = node_fs_1.default.readFileSync((0, parseRequest_1.stripQueryAndHash)(dependencyFilename), 'utf8');
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (!isMissingFileError(error)) {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
this.invalidateForFile(dependencyFilename);
|
|
177
|
+
anyDepChanged = true;
|
|
178
|
+
// eslint-disable-next-line no-continue
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
161
181
|
const dependencyChanged = this.invalidateIfChanged(dependencyFilename, dependencyContent, visitedFiles, 'fs', changedFiles);
|
|
162
182
|
if (dependencyChanged &&
|
|
163
183
|
invalidateOnDependencyChange?.has(dependencyFilename)) {
|
|
@@ -249,13 +269,49 @@ class TransformCacheCollection {
|
|
|
249
269
|
hasCachedDependencies(filename) {
|
|
250
270
|
return this.getCachedDependencies(filename).size > 0;
|
|
251
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Fast check if a file changed on disk since last seen.
|
|
274
|
+
* Uses mtime as a fast path — only reads the file if mtime differs.
|
|
275
|
+
* Returns true if the file changed (cache was invalidated).
|
|
276
|
+
*/
|
|
277
|
+
checkFreshness(filename, strippedFilename) {
|
|
278
|
+
try {
|
|
279
|
+
const currentMtime = node_fs_1.default.statSync(strippedFilename).mtimeMs;
|
|
280
|
+
const cachedMtime = this.fileMtimes.get(filename);
|
|
281
|
+
if (cachedMtime !== undefined && currentMtime === cachedMtime) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
const content = node_fs_1.default.readFileSync(strippedFilename, 'utf-8');
|
|
285
|
+
this.fileMtimes.set(filename, currentMtime);
|
|
286
|
+
if (this.invalidateIfChanged(filename, content, undefined, 'fs')) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
if (!isMissingFileError(error)) {
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
this.invalidateForFile(filename);
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
252
299
|
setContentHash(filename, source, hash) {
|
|
253
300
|
const current = this.contentHashes.get(filename);
|
|
254
301
|
if (current) {
|
|
255
302
|
current[source] = hash;
|
|
256
|
-
return;
|
|
257
303
|
}
|
|
258
|
-
|
|
304
|
+
else {
|
|
305
|
+
this.contentHashes.set(filename, { [source]: hash });
|
|
306
|
+
}
|
|
307
|
+
if (source === 'fs') {
|
|
308
|
+
try {
|
|
309
|
+
this.fileMtimes.set(filename, node_fs_1.default.statSync((0, parseRequest_1.stripQueryAndHash)(filename)).mtimeMs);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// ignore
|
|
313
|
+
}
|
|
314
|
+
}
|
|
259
315
|
}
|
|
260
316
|
}
|
|
261
317
|
exports.TransformCacheCollection = TransformCacheCollection;
|
package/types/index.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ export { createFileReporter } from './debug/fileReporter';
|
|
|
3
3
|
export type { IFileReporterOptions } from './debug/fileReporter';
|
|
4
4
|
export { default as babelTransformPlugin } from './plugins/babel-transform';
|
|
5
5
|
export { default as preeval } from './plugins/preeval';
|
|
6
|
-
export { getTransformMetadata, withTransformMetadata, } from './utils/TransformMetadata';
|
|
7
|
-
export type { WYWTransformMetadata } from './utils/TransformMetadata';
|
|
6
|
+
export { createTransformManifest, getTransformMetadata, stringifyTransformManifest, toTransformResultMetadata, withTransformMetadata, } from './utils/TransformMetadata';
|
|
7
|
+
export type { WYWTransformManifest, WYWTransformMetadata, WYWTransformProcessorMetadata, WYWTransformResultMetadata, } from './utils/TransformMetadata';
|
|
8
|
+
export { collectTransformDiagnostics } from './utils/TransformDiagnostics';
|
|
9
|
+
export type { WYWTransformDiagnostic } from './utils/TransformDiagnostics';
|
|
8
10
|
export { Module, DefaultModuleImplementation } from './module';
|
|
9
11
|
export { default as shaker } from './shaker';
|
|
10
12
|
export { transform } from './transform';
|
package/types/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.findIdentifiers = exports.TransformCacheCollection = exports.peek = exports.getVisitorKeys = exports.applyProcessors = exports.getFileIdx = exports.isNode = exports.EventEmitter = exports.withDefaultServices = exports.loadWywOptions = exports.syncResolveImports = exports.asyncResolveImports = exports.transformUrl = exports.Entrypoint = exports.prepareCode = exports.baseHandlers = exports.parseFile = exports.EvaluatedEntrypoint = exports.UnprocessedEntrypointError = exports.isUnprocessedEntrypointError = exports.transform = exports.shaker = exports.DefaultModuleImplementation = exports.Module = exports.withTransformMetadata = exports.getTransformMetadata = exports.preeval = exports.babelTransformPlugin = exports.createFileReporter = exports.slugify = void 0;
|
|
20
|
+
exports.findIdentifiers = exports.TransformCacheCollection = exports.peek = exports.getVisitorKeys = exports.applyProcessors = exports.getFileIdx = exports.isNode = exports.EventEmitter = exports.withDefaultServices = exports.loadWywOptions = exports.syncResolveImports = exports.asyncResolveImports = exports.transformUrl = exports.Entrypoint = exports.prepareCode = exports.baseHandlers = exports.parseFile = exports.EvaluatedEntrypoint = exports.UnprocessedEntrypointError = exports.isUnprocessedEntrypointError = exports.transform = exports.shaker = exports.DefaultModuleImplementation = exports.Module = exports.collectTransformDiagnostics = exports.withTransformMetadata = exports.toTransformResultMetadata = exports.stringifyTransformManifest = exports.getTransformMetadata = exports.createTransformManifest = exports.preeval = exports.babelTransformPlugin = exports.createFileReporter = exports.slugify = void 0;
|
|
21
21
|
var shared_1 = require("@wyw-in-js/shared");
|
|
22
22
|
Object.defineProperty(exports, "slugify", { enumerable: true, get: function () { return shared_1.slugify; } });
|
|
23
23
|
var fileReporter_1 = require("./debug/fileReporter");
|
|
@@ -27,8 +27,13 @@ Object.defineProperty(exports, "babelTransformPlugin", { enumerable: true, get:
|
|
|
27
27
|
var preeval_1 = require("./plugins/preeval");
|
|
28
28
|
Object.defineProperty(exports, "preeval", { enumerable: true, get: function () { return __importDefault(preeval_1).default; } });
|
|
29
29
|
var TransformMetadata_1 = require("./utils/TransformMetadata");
|
|
30
|
+
Object.defineProperty(exports, "createTransformManifest", { enumerable: true, get: function () { return TransformMetadata_1.createTransformManifest; } });
|
|
30
31
|
Object.defineProperty(exports, "getTransformMetadata", { enumerable: true, get: function () { return TransformMetadata_1.getTransformMetadata; } });
|
|
32
|
+
Object.defineProperty(exports, "stringifyTransformManifest", { enumerable: true, get: function () { return TransformMetadata_1.stringifyTransformManifest; } });
|
|
33
|
+
Object.defineProperty(exports, "toTransformResultMetadata", { enumerable: true, get: function () { return TransformMetadata_1.toTransformResultMetadata; } });
|
|
31
34
|
Object.defineProperty(exports, "withTransformMetadata", { enumerable: true, get: function () { return TransformMetadata_1.withTransformMetadata; } });
|
|
35
|
+
var TransformDiagnostics_1 = require("./utils/TransformDiagnostics");
|
|
36
|
+
Object.defineProperty(exports, "collectTransformDiagnostics", { enumerable: true, get: function () { return TransformDiagnostics_1.collectTransformDiagnostics; } });
|
|
32
37
|
var module_1 = require("./module");
|
|
33
38
|
Object.defineProperty(exports, "Module", { enumerable: true, get: function () { return module_1.Module; } });
|
|
34
39
|
Object.defineProperty(exports, "DefaultModuleImplementation", { enumerable: true, get: function () { return module_1.DefaultModuleImplementation; } });
|
package/types/module.js
CHANGED
|
@@ -326,10 +326,15 @@ class Module {
|
|
|
326
326
|
if (extension !== '.json' && !this.extensions.includes(extension)) {
|
|
327
327
|
return null;
|
|
328
328
|
}
|
|
329
|
-
|
|
329
|
+
let entrypoint = this.cache.get('entrypoints', filename);
|
|
330
330
|
if (entrypoint && (0, Entrypoint_helpers_1.isSuperSet)(entrypoint.evaluatedOnly ?? [], only)) {
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
if (this.cache.checkFreshness(filename, strippedFilename)) {
|
|
332
|
+
entrypoint = undefined;
|
|
333
|
+
}
|
|
334
|
+
if (entrypoint) {
|
|
335
|
+
log('✅ file has been already evaluated');
|
|
336
|
+
return entrypoint;
|
|
337
|
+
}
|
|
333
338
|
}
|
|
334
339
|
if (entrypoint?.ignored) {
|
|
335
340
|
log('✅ file has been ignored during prepare stage. Original code will be used');
|
|
@@ -12,7 +12,10 @@ export declare const filename: string;
|
|
|
12
12
|
export declare function collector(file: BabelFile, options: Pick<StrictOptions, 'classNameSlug' | 'displayName' | 'extensions' | 'evaluate' | 'tagResolver'> & {
|
|
13
13
|
eventEmitter?: EventEmitter;
|
|
14
14
|
}, values: ValueCache): {
|
|
15
|
-
artifacts: import("@wyw-in-js/shared").Artifact[];
|
|
15
|
+
readonly artifacts: import("@wyw-in-js/shared").Artifact[];
|
|
16
|
+
readonly className: string;
|
|
17
|
+
readonly displayName: string;
|
|
18
|
+
readonly location: import("@babel/types").SourceLocation | null;
|
|
16
19
|
}[];
|
|
17
20
|
export default function collectorPlugin(babel: Core, options: StrictOptions & {
|
|
18
21
|
eventEmitter?: EventEmitter;
|
|
@@ -43,7 +43,7 @@ export declare class Entrypoint extends BaseEntrypoint {
|
|
|
43
43
|
assertNotSuperseded(): void;
|
|
44
44
|
assertTransformed(): void;
|
|
45
45
|
beginProcessing(): void;
|
|
46
|
-
createAction<TType extends ActionTypes, TAction extends ActionByType<TType>>(actionType: TType, data: TAction['data'], abortSignal?: AbortSignal | null): BaseAction<TAction>;
|
|
46
|
+
createAction<TType extends ActionTypes, TAction extends ActionByType<TType>>(actionType: TType, data: TAction['data'], abortSignal?: AbortSignal | null, actionContext?: unknown): BaseAction<TAction>;
|
|
47
47
|
createChild(name: string, only: string[], loadedCode?: string): Entrypoint | 'loop';
|
|
48
48
|
createEvaluated(): EvaluatedEntrypoint;
|
|
49
49
|
endProcessing(): void;
|
|
@@ -14,6 +14,7 @@ const BaseAction_1 = require("./actions/BaseAction");
|
|
|
14
14
|
const UnprocessedEntrypointError_1 = require("./actions/UnprocessedEntrypointError");
|
|
15
15
|
const parseRequest_1 = require("../utils/parseRequest");
|
|
16
16
|
const EMPTY_FILE = '=== empty file ===';
|
|
17
|
+
const DEFAULT_ACTION_CONTEXT = Symbol('defaultActionContext');
|
|
17
18
|
function hasLoop(name, parent, processed = []) {
|
|
18
19
|
if (parent.name === name || processed.includes(parent.name)) {
|
|
19
20
|
return true;
|
|
@@ -201,16 +202,20 @@ class Entrypoint extends BaseEntrypoint_1.BaseEntrypoint {
|
|
|
201
202
|
beginProcessing() {
|
|
202
203
|
this.#isProcessing = true;
|
|
203
204
|
}
|
|
204
|
-
createAction(actionType, data, abortSignal = null) {
|
|
205
|
+
createAction(actionType, data, abortSignal = null, actionContext = DEFAULT_ACTION_CONTEXT) {
|
|
205
206
|
if (!this.actionsCache.has(actionType)) {
|
|
206
207
|
this.actionsCache.set(actionType, new Map());
|
|
207
208
|
}
|
|
208
|
-
const
|
|
209
|
+
const contexts = this.actionsCache.get(actionType);
|
|
210
|
+
if (!contexts.has(actionContext)) {
|
|
211
|
+
contexts.set(actionContext, new Map());
|
|
212
|
+
}
|
|
213
|
+
const cache = contexts.get(actionContext);
|
|
209
214
|
const cached = cache.get(data);
|
|
210
215
|
if (cached && !cached.abortSignal?.aborted) {
|
|
211
216
|
return cached;
|
|
212
217
|
}
|
|
213
|
-
const newAction = new BaseAction_1.BaseAction(actionType, this.services, this, data, abortSignal);
|
|
218
|
+
const newAction = new BaseAction_1.BaseAction(actionType, this.services, this, data, abortSignal, actionContext);
|
|
214
219
|
cache.set(data, newAction);
|
|
215
220
|
this.services.eventEmitter.entrypointEvent(this.seqId, {
|
|
216
221
|
type: 'actionCreated',
|
|
@@ -13,13 +13,14 @@ export declare class BaseAction<TAction extends ActionQueueItem> implements GetB
|
|
|
13
13
|
readonly entrypoint: Entrypoint;
|
|
14
14
|
readonly data: TAction['data'];
|
|
15
15
|
readonly abortSignal: AbortSignal | null;
|
|
16
|
+
readonly actionContext: unknown;
|
|
16
17
|
readonly idx: string;
|
|
17
18
|
result: TypeOfResult<TAction> | typeof Pending;
|
|
18
19
|
private activeScenario;
|
|
19
20
|
private activeScenarioError?;
|
|
20
21
|
private activeScenarioNextResults;
|
|
21
22
|
private handler;
|
|
22
|
-
constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null);
|
|
23
|
+
constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null, actionContext: unknown);
|
|
23
24
|
get log(): Debugger;
|
|
24
25
|
get ref(): string;
|
|
25
26
|
createAbortSignal(): AbortSignal & Disposable;
|
|
@@ -11,18 +11,20 @@ class BaseAction {
|
|
|
11
11
|
entrypoint;
|
|
12
12
|
data;
|
|
13
13
|
abortSignal;
|
|
14
|
+
actionContext;
|
|
14
15
|
idx;
|
|
15
16
|
result = types_1.Pending;
|
|
16
17
|
activeScenario = null;
|
|
17
18
|
activeScenarioError;
|
|
18
19
|
activeScenarioNextResults = [];
|
|
19
20
|
handler = null;
|
|
20
|
-
constructor(type, services, entrypoint, data, abortSignal) {
|
|
21
|
+
constructor(type, services, entrypoint, data, abortSignal, actionContext) {
|
|
21
22
|
this.type = type;
|
|
22
23
|
this.services = services;
|
|
23
24
|
this.entrypoint = entrypoint;
|
|
24
25
|
this.data = data;
|
|
25
26
|
this.abortSignal = abortSignal;
|
|
27
|
+
this.actionContext = actionContext;
|
|
26
28
|
actionIdx += 1;
|
|
27
29
|
this.idx = actionIdx.toString(16).padStart(6, '0');
|
|
28
30
|
}
|
|
@@ -36,7 +36,7 @@ async function asyncActionRunner(action, actionHandlers, stack = [getActionRef(a
|
|
|
36
36
|
return result.value;
|
|
37
37
|
}
|
|
38
38
|
const [type, entrypoint, data, abortSignal] = result.value;
|
|
39
|
-
const nextAction = entrypoint.createAction(type, data, abortSignal);
|
|
39
|
+
const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
|
|
40
40
|
try {
|
|
41
41
|
actionResult = await asyncActionRunner(nextAction, actionHandlers, [
|
|
42
42
|
...stack,
|
|
@@ -70,7 +70,7 @@ function syncActionRunner(action, actionHandlers, stack = [getActionRef(action.t
|
|
|
70
70
|
return result.value;
|
|
71
71
|
}
|
|
72
72
|
const [type, entrypoint, data, abortSignal] = result.value;
|
|
73
|
-
const nextAction = entrypoint.createAction(type, data, abortSignal);
|
|
73
|
+
const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
|
|
74
74
|
try {
|
|
75
75
|
actionResult = syncActionRunner(nextAction, actionHandlers, [
|
|
76
76
|
...stack,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { BabelFileResult } from '@babel/core';
|
|
2
2
|
import type { Replacements, Rules } from '@wyw-in-js/shared';
|
|
3
|
+
import type { WYWTransformDiagnostic } from '../../utils/TransformDiagnostics';
|
|
4
|
+
import type { WYWTransformResultMetadata } from '../../utils/TransformMetadata';
|
|
3
5
|
export interface IExtracted {
|
|
4
6
|
cssSourceMapText: string;
|
|
5
7
|
cssText: string;
|
|
@@ -12,4 +14,6 @@ export interface IWorkflowActionNonLinariaResult {
|
|
|
12
14
|
}
|
|
13
15
|
export interface IWorkflowActionLinariaResult extends IExtracted, IWorkflowActionNonLinariaResult {
|
|
14
16
|
dependencies: string[];
|
|
17
|
+
diagnostics?: WYWTransformDiagnostic[];
|
|
18
|
+
metadata?: WYWTransformResultMetadata;
|
|
15
19
|
}
|
|
@@ -57,7 +57,10 @@ const shaker_1 = require("../../shaker");
|
|
|
57
57
|
const AbortError_1 = require("../actions/AbortError");
|
|
58
58
|
const barrelManifest_1 = require("../barrelManifest");
|
|
59
59
|
const shouldSkipExplodeReexports = (action) => {
|
|
60
|
-
const { loadedAndParsed } = action.entrypoint;
|
|
60
|
+
const { loadedAndParsed, only } = action.entrypoint;
|
|
61
|
+
if (only.length === 1 && only[0] === '__wywPreval') {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
61
64
|
if (loadedAndParsed.evaluator !== shaker_1.shaker || !loadedAndParsed.ast) {
|
|
62
65
|
return false;
|
|
63
66
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.workflow = workflow;
|
|
4
4
|
const AbortError_1 = require("../actions/AbortError");
|
|
5
|
+
const TransformDiagnostics_1 = require("../../utils/TransformDiagnostics");
|
|
6
|
+
const TransformMetadata_1 = require("../../utils/TransformMetadata");
|
|
5
7
|
/**
|
|
6
8
|
* The entry point for file processing. Sequentially calls `processEntrypoint`,
|
|
7
9
|
* `evalFile`, `collect`, and `extract`. Returns the result of transforming
|
|
@@ -59,6 +61,10 @@ function* workflow() {
|
|
|
59
61
|
sourceMap: collectStageResult.map,
|
|
60
62
|
};
|
|
61
63
|
}
|
|
64
|
+
const metadata = options.pluginOptions.outputMetadata
|
|
65
|
+
? (0, TransformMetadata_1.toTransformResultMetadata)(collectStageResult.metadata, dependencies)
|
|
66
|
+
: null;
|
|
67
|
+
const diagnostics = (0, TransformDiagnostics_1.collectTransformDiagnostics)(entrypoint.name, collectStageResult.metadata.processors);
|
|
62
68
|
// *** 4th stage
|
|
63
69
|
const extractStageResult = yield* this.getNext('extract', entrypoint, {
|
|
64
70
|
processors: collectStageResult.metadata.processors,
|
|
@@ -67,6 +73,8 @@ function* workflow() {
|
|
|
67
73
|
...extractStageResult,
|
|
68
74
|
code: collectStageResult.code ?? '',
|
|
69
75
|
dependencies,
|
|
76
|
+
...(diagnostics.length > 0 ? { diagnostics } : {}),
|
|
77
|
+
...(metadata ? { metadata } : {}),
|
|
70
78
|
replacements: [
|
|
71
79
|
...extractStageResult.replacements,
|
|
72
80
|
...collectStageResult.metadata.replacements,
|
|
@@ -34,6 +34,7 @@ export type AnyIteratorResult<TMode extends 'async' | 'sync', TResult> = {
|
|
|
34
34
|
sync: IteratorResult<YieldArg, TResult>;
|
|
35
35
|
}[TMode];
|
|
36
36
|
export interface IBaseAction<TAction extends ActionQueueItem, TResult, TData> extends IBaseNode {
|
|
37
|
+
actionContext: unknown;
|
|
37
38
|
abortSignal: AbortSignal | null;
|
|
38
39
|
createAbortSignal: () => AbortSignal & Disposable;
|
|
39
40
|
data: TData;
|
package/types/transform.js
CHANGED
|
@@ -21,6 +21,24 @@ const resolveImports_1 = require("./transform/generators/resolveImports");
|
|
|
21
21
|
const withDefaultServices_1 = require("./transform/helpers/withDefaultServices");
|
|
22
22
|
const memoizedSyncResolve = new WeakMap();
|
|
23
23
|
const memoizedAsyncResolve = new WeakMap();
|
|
24
|
+
const EMPTY_CUSTOM_HANDLERS = {};
|
|
25
|
+
const memoizedActionContexts = new WeakMap();
|
|
26
|
+
const getActionContext = (resolveImportsHandler, customHandlers) => {
|
|
27
|
+
const customHandlersKey = Object.keys(customHandlers).length === 0
|
|
28
|
+
? EMPTY_CUSTOM_HANDLERS
|
|
29
|
+
: customHandlers;
|
|
30
|
+
let actionContextsByHandlers = memoizedActionContexts.get(resolveImportsHandler);
|
|
31
|
+
if (!actionContextsByHandlers) {
|
|
32
|
+
actionContextsByHandlers = new WeakMap();
|
|
33
|
+
memoizedActionContexts.set(resolveImportsHandler, actionContextsByHandlers);
|
|
34
|
+
}
|
|
35
|
+
let actionContext = actionContextsByHandlers.get(customHandlersKey);
|
|
36
|
+
if (!actionContext) {
|
|
37
|
+
actionContext = {};
|
|
38
|
+
actionContextsByHandlers.set(customHandlersKey, actionContext);
|
|
39
|
+
}
|
|
40
|
+
return actionContext;
|
|
41
|
+
};
|
|
24
42
|
function transformSync(partialServices, originalCode, syncResolve, customHandlers = {}) {
|
|
25
43
|
const { options } = partialServices;
|
|
26
44
|
const pluginOptions = (0, loadWywOptions_1.loadWywOptions)(options.pluginOptions);
|
|
@@ -35,6 +53,18 @@ function transformSync(partialServices, originalCode, syncResolve, customHandler
|
|
|
35
53
|
// If global cache is disabled, we need to create a new cache for each file
|
|
36
54
|
services.cache = new cache_1.TransformCacheCollection();
|
|
37
55
|
}
|
|
56
|
+
if (!memoizedSyncResolve.has(syncResolve)) {
|
|
57
|
+
memoizedSyncResolve.set(syncResolve, function resolveImports() {
|
|
58
|
+
return resolveImports_1.syncResolveImports.call(this, syncResolve);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const resolveImportsHandler = memoizedSyncResolve.get(syncResolve);
|
|
62
|
+
const actionHandlers = {
|
|
63
|
+
...generators_1.baseHandlers,
|
|
64
|
+
...customHandlers,
|
|
65
|
+
resolveImports: resolveImportsHandler,
|
|
66
|
+
};
|
|
67
|
+
const actionContext = getActionContext(resolveImportsHandler, customHandlers);
|
|
38
68
|
const entrypoint = Entrypoint_1.Entrypoint.createRoot(services, options.filename, ['__wywPreval'], originalCode);
|
|
39
69
|
if (entrypoint.ignored) {
|
|
40
70
|
return {
|
|
@@ -42,18 +72,9 @@ function transformSync(partialServices, originalCode, syncResolve, customHandler
|
|
|
42
72
|
sourceMap: options.inputSourceMap,
|
|
43
73
|
};
|
|
44
74
|
}
|
|
45
|
-
const workflowAction = entrypoint.createAction('workflow', undefined);
|
|
46
|
-
if (!memoizedSyncResolve.has(syncResolve)) {
|
|
47
|
-
memoizedSyncResolve.set(syncResolve, function resolveImports() {
|
|
48
|
-
return resolveImports_1.syncResolveImports.call(this, syncResolve);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
75
|
+
const workflowAction = entrypoint.createAction('workflow', undefined, null, actionContext);
|
|
51
76
|
try {
|
|
52
|
-
const result = (0, actionRunner_1.syncActionRunner)(workflowAction,
|
|
53
|
-
...generators_1.baseHandlers,
|
|
54
|
-
...customHandlers,
|
|
55
|
-
resolveImports: memoizedSyncResolve.get(syncResolve),
|
|
56
|
-
});
|
|
77
|
+
const result = (0, actionRunner_1.syncActionRunner)(workflowAction, actionHandlers);
|
|
57
78
|
entrypoint.log('%s is ready', entrypoint.name);
|
|
58
79
|
return result;
|
|
59
80
|
}
|
|
@@ -92,6 +113,19 @@ async function transform(partialServices, originalCode, asyncResolve, customHand
|
|
|
92
113
|
* but the "only" option has changed, the file will be re-processed using
|
|
93
114
|
* the combined "only" option.
|
|
94
115
|
*/
|
|
116
|
+
if (!memoizedAsyncResolve.has(asyncResolve)) {
|
|
117
|
+
const resolveImports = function resolveImports() {
|
|
118
|
+
return resolveImports_1.asyncResolveImports.call(this, asyncResolve);
|
|
119
|
+
};
|
|
120
|
+
memoizedAsyncResolve.set(asyncResolve, resolveImports);
|
|
121
|
+
}
|
|
122
|
+
const resolveImportsHandler = memoizedAsyncResolve.get(asyncResolve);
|
|
123
|
+
const actionHandlers = {
|
|
124
|
+
...generators_1.baseHandlers,
|
|
125
|
+
...customHandlers,
|
|
126
|
+
resolveImports: resolveImportsHandler,
|
|
127
|
+
};
|
|
128
|
+
const actionContext = getActionContext(resolveImportsHandler, customHandlers);
|
|
95
129
|
const entrypoint = Entrypoint_1.Entrypoint.createRoot(services, options.filename, ['__wywPreval'], originalCode);
|
|
96
130
|
if (entrypoint.ignored) {
|
|
97
131
|
return {
|
|
@@ -99,19 +133,9 @@ async function transform(partialServices, originalCode, asyncResolve, customHand
|
|
|
99
133
|
sourceMap: options.inputSourceMap,
|
|
100
134
|
};
|
|
101
135
|
}
|
|
102
|
-
const workflowAction = entrypoint.createAction('workflow', undefined);
|
|
103
|
-
if (!memoizedAsyncResolve.has(asyncResolve)) {
|
|
104
|
-
const resolveImports = function resolveImports() {
|
|
105
|
-
return resolveImports_1.asyncResolveImports.call(this, asyncResolve);
|
|
106
|
-
};
|
|
107
|
-
memoizedAsyncResolve.set(asyncResolve, resolveImports);
|
|
108
|
-
}
|
|
136
|
+
const workflowAction = entrypoint.createAction('workflow', undefined, null, actionContext);
|
|
109
137
|
try {
|
|
110
|
-
const result = await (0, actionRunner_1.asyncActionRunner)(workflowAction,
|
|
111
|
-
...generators_1.baseHandlers,
|
|
112
|
-
...customHandlers,
|
|
113
|
-
resolveImports: memoizedAsyncResolve.get(asyncResolve),
|
|
114
|
-
});
|
|
138
|
+
const result = await (0, actionRunner_1.asyncActionRunner)(workflowAction, actionHandlers);
|
|
115
139
|
entrypoint.log('%s is ready', entrypoint.name);
|
|
116
140
|
return result;
|
|
117
141
|
}
|
package/types/types.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import type { File, Program } from '@babel/types';
|
|
|
4
4
|
import type { RawSourceMap } from 'source-map';
|
|
5
5
|
import type { BaseProcessor } from '@wyw-in-js/processor-utils';
|
|
6
6
|
import type { Debugger, Replacement, Rules, StrictOptions } from '@wyw-in-js/shared';
|
|
7
|
-
import type { WYWTransformMetadata } from './utils/TransformMetadata';
|
|
7
|
+
import type { WYWTransformMetadata, WYWTransformResultMetadata } from './utils/TransformMetadata';
|
|
8
|
+
import type { WYWTransformDiagnostic } from './utils/TransformDiagnostics';
|
|
8
9
|
export type PluginOptions = StrictOptions & {
|
|
9
10
|
configFile?: string | false;
|
|
10
11
|
stage?: Stage;
|
|
@@ -36,6 +37,8 @@ export type Result = {
|
|
|
36
37
|
cssSourceMapText?: string;
|
|
37
38
|
cssText?: string;
|
|
38
39
|
dependencies?: string[];
|
|
40
|
+
diagnostics?: WYWTransformDiagnostic[];
|
|
41
|
+
metadata?: WYWTransformResultMetadata;
|
|
39
42
|
replacements?: Replacement[];
|
|
40
43
|
rules?: Rules;
|
|
41
44
|
sourceMap?: RawSourceMap | null;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BaseProcessor, ProcessorDiagnostic } from '@wyw-in-js/processor-utils';
|
|
2
|
+
type DiagnosticProcessor = Pick<BaseProcessor, 'artifacts' | 'className' | 'displayName'>;
|
|
3
|
+
export type WYWTransformDiagnostic = ProcessorDiagnostic & {
|
|
4
|
+
className: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const collectTransformDiagnostics: (filename: string, processors: DiagnosticProcessor[]) => WYWTransformDiagnostic[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectTransformDiagnostics = void 0;
|
|
4
|
+
const processor_utils_1 = require("@wyw-in-js/processor-utils");
|
|
5
|
+
const collectTransformDiagnostics = (filename, processors) => processors.flatMap((processor) => processor.artifacts
|
|
6
|
+
.filter(processor_utils_1.isProcessorDiagnosticArtifact)
|
|
7
|
+
.map(([, diagnostic]) => ({
|
|
8
|
+
...diagnostic,
|
|
9
|
+
className: processor.className,
|
|
10
|
+
displayName: processor.displayName,
|
|
11
|
+
end: diagnostic.end ?? null,
|
|
12
|
+
filename,
|
|
13
|
+
start: diagnostic.start ?? null,
|
|
14
|
+
})));
|
|
15
|
+
exports.collectTransformDiagnostics = collectTransformDiagnostics;
|
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BaseProcessor } from '@wyw-in-js/processor-utils';
|
|
2
|
+
import type { Artifact, Location, Replacement, Rules } from '@wyw-in-js/shared';
|
|
3
|
+
type TransformMetadataProcessor = Pick<BaseProcessor, 'artifacts' | 'className' | 'displayName' | 'location'>;
|
|
2
4
|
export type WYWTransformMetadata = {
|
|
3
5
|
dependencies: string[];
|
|
4
|
-
processors:
|
|
5
|
-
artifacts: Artifact[];
|
|
6
|
-
}[];
|
|
6
|
+
processors: TransformMetadataProcessor[];
|
|
7
7
|
replacements: Replacement[];
|
|
8
8
|
rules: Rules;
|
|
9
9
|
};
|
|
10
|
+
export type WYWTransformProcessorMetadata = {
|
|
11
|
+
artifacts: Artifact[];
|
|
12
|
+
className: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
start: Location | null | undefined;
|
|
15
|
+
};
|
|
16
|
+
export type WYWTransformResultMetadata = Omit<WYWTransformMetadata, 'processors'> & {
|
|
17
|
+
processors: WYWTransformProcessorMetadata[];
|
|
18
|
+
};
|
|
19
|
+
export type WYWTransformManifest = WYWTransformResultMetadata & {
|
|
20
|
+
cssFile?: string;
|
|
21
|
+
source: string;
|
|
22
|
+
version: 1;
|
|
23
|
+
};
|
|
10
24
|
export declare const withTransformMetadata: (value: unknown) => value is {
|
|
11
25
|
wywInJS: WYWTransformMetadata;
|
|
12
26
|
};
|
|
13
27
|
export declare const getTransformMetadata: (value: unknown) => WYWTransformMetadata | undefined;
|
|
28
|
+
export declare const toTransformResultMetadata: (metadata: WYWTransformMetadata, dependencies: string[]) => WYWTransformResultMetadata;
|
|
29
|
+
export declare const createTransformManifest: (metadata: WYWTransformResultMetadata, context: Pick<WYWTransformManifest, "cssFile" | "source">) => WYWTransformManifest;
|
|
30
|
+
export declare const stringifyTransformManifest: (manifest: WYWTransformManifest) => string;
|
|
31
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTransformMetadata = exports.withTransformMetadata = void 0;
|
|
3
|
+
exports.stringifyTransformManifest = exports.createTransformManifest = exports.toTransformResultMetadata = exports.getTransformMetadata = exports.withTransformMetadata = void 0;
|
|
4
|
+
const processor_utils_1 = require("@wyw-in-js/processor-utils");
|
|
4
5
|
const withTransformMetadata = (value) => typeof value === 'object' &&
|
|
5
6
|
value !== null &&
|
|
6
7
|
typeof value.wywInJS === 'object';
|
|
@@ -15,3 +16,25 @@ const getTransformMetadata = (value) => {
|
|
|
15
16
|
return undefined;
|
|
16
17
|
};
|
|
17
18
|
exports.getTransformMetadata = getTransformMetadata;
|
|
19
|
+
const toTransformResultMetadata = (metadata, dependencies) => ({
|
|
20
|
+
dependencies,
|
|
21
|
+
processors: metadata.processors.map((processor) => ({
|
|
22
|
+
artifacts: processor.artifacts
|
|
23
|
+
.filter((artifact) => !(0, processor_utils_1.isProcessorDiagnosticArtifact)(artifact))
|
|
24
|
+
.map(([type, data]) => [type, data]),
|
|
25
|
+
className: processor.className,
|
|
26
|
+
displayName: processor.displayName,
|
|
27
|
+
start: processor.location?.start ?? null,
|
|
28
|
+
})),
|
|
29
|
+
replacements: [...metadata.replacements],
|
|
30
|
+
rules: { ...metadata.rules },
|
|
31
|
+
});
|
|
32
|
+
exports.toTransformResultMetadata = toTransformResultMetadata;
|
|
33
|
+
const createTransformManifest = (metadata, context) => ({
|
|
34
|
+
...metadata,
|
|
35
|
+
...context,
|
|
36
|
+
version: 1,
|
|
37
|
+
});
|
|
38
|
+
exports.createTransformManifest = createTransformManifest;
|
|
39
|
+
const stringifyTransformManifest = (manifest) => `${JSON.stringify(manifest, null, 2)}\n`;
|
|
40
|
+
exports.stringifyTransformManifest = stringifyTransformManifest;
|
|
@@ -18,6 +18,15 @@ const valueToLiteral_1 = require("./valueToLiteral");
|
|
|
18
18
|
function staticEval(ex, evaluate = false) {
|
|
19
19
|
if (!evaluate)
|
|
20
20
|
return undefined;
|
|
21
|
+
if (ex.isIdentifier()) {
|
|
22
|
+
const binding = ex.scope.getBinding(ex.node.name);
|
|
23
|
+
// Babel may "evaluate" a destructured binding to its source container
|
|
24
|
+
// object/array instead of the bound value, which changes template semantics.
|
|
25
|
+
if (binding?.path.isVariableDeclarator() &&
|
|
26
|
+
!binding.path.get('id').isIdentifier()) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
21
30
|
const result = ex.evaluate();
|
|
22
31
|
if (result.confident && !(0, shared_1.hasEvalMeta)(result.value)) {
|
|
23
32
|
return [result.value];
|