Skip to content

Commit

Permalink
rework result cache and used cache ids
Browse files Browse the repository at this point in the history
  • Loading branch information
Zn4rK committed Nov 24, 2023
1 parent dd728cc commit 634e291
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 30 deletions.
14 changes: 14 additions & 0 deletions .changeset/itchy-ligers-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@navita/webpack-plugin': minor
'@navita/vite-plugin': minor
'@navita/engine': minor
'@navita/core': minor
'@navita/adapter': minor
'@navita/css': minor
'@navita/jest': minor
'@navita/next-plugin': minor
'@navita/swc': minor
'@navita/types': minor
---

better cache handling when navita is used
9 changes: 9 additions & 0 deletions examples/with-next/src/pages/temp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { style } from "@navita/css";

const x = style({
background: "floralwhite",
});

export default function Temp() {
return <div>Temp</div>;
}
2 changes: 1 addition & 1 deletion examples/with-vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { globalStyle } from "@navita/css";
import { useCallback, useState } from "react";
import { Button } from "@/components/button";
import { ComicSansContainer } from "@/components/comicSansContainer.tsx";
import { DynamicStyleExample } from "@/components/dynamicStyleExample.tsx";
import { MergeExample } from "@/components/mergeExample.tsx";
import './App.css';
import { DynamicStyleExample } from "@/components/dynamicStyleExample.tsx";

globalStyle(':root', {
background: 'floralwhite',
Expand Down
13 changes: 12 additions & 1 deletion packages/core/src/createRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import path from "path";
import { Engine } from "@navita/engine";
import type { UsedIdCache, Options as EngineOptions } from "@navita/engine";
import type { ImportMap } from "@navita/types";
import MagicString from "magic-string";
import { evaluateAndProcess } from "./evaluateAndProcess";
import type { ResultCache } from "./helpers/setAdapter";

export type { Engine, UsedIdCache, EngineOptions };
export type { ImportMap };
Expand All @@ -16,6 +16,8 @@ export interface Options {
context?: string;
}

const resultCache: ResultCache = {};

export function createRenderer({
resolver,
readFile,
Expand All @@ -28,15 +30,23 @@ export function createRenderer({
...(engineOptions || {}),
});

const clearCache = (filePath: string) => {
engine.clearCache(filePath);
resultCache[filePath] = [];
};

return {
engine,
clearCache,
async transformAndProcess({
content,
filePath,
}: {
content: string;
filePath: string;
}) {
clearCache(filePath);

const { result, dependencies } = await evaluateAndProcess({
type: 'entryPoint',
source: content,
Expand All @@ -45,6 +55,7 @@ export function createRenderer({
readFile,
importMap,
engine,
resultCache
});

const newSource = new MagicString(content, {
Expand Down
12 changes: 7 additions & 5 deletions packages/core/src/evaluateAndProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { ImportMap } from "@navita/types";
import { createCompiledFunction } from "./helpers/createCompiledFunction";
import type { NodeModuleCache, ResolverCache } from "./helpers/createDefineFunction";
import { createDefineFunction } from "./helpers/createDefineFunction";
import type { CollectedResults } from "./helpers/setAdapter";
import type { ResultCache } from "./helpers/setAdapter";
import { setAdapter } from "./helpers/setAdapter";

const rootDir = path.resolve(__dirname, "../../");
Expand All @@ -24,17 +24,18 @@ export interface Caches {
nodeModuleCache?: NodeModuleCache;
resolverCache?: ResolverCache;
moduleCache?: ModuleCache;
resultCache?: ResultCache;
}

const defaultNodeModuleCache: NodeModuleCache = {};
const defaultResolverCache: ResolverCache = {};
const defaultModuleCache: ModuleCache = new Map();
const collectedResults: CollectedResults = {};
const defaultResultCache: ResultCache = {};

type Types = 'entryPoint' | 'dependency';

interface Output<Type extends Types> {
result: Type extends 'entryPoint' ? CollectedResults[number] : Record<string, unknown>;
result: Type extends 'entryPoint' ? ResultCache[number] : Record<string, unknown>;
dependencies: string[];
}

Expand All @@ -49,6 +50,7 @@ export async function evaluateAndProcess<Type extends 'entryPoint' | 'dependency
nodeModuleCache = defaultNodeModuleCache,
resolverCache = defaultResolverCache,
moduleCache = defaultModuleCache,
resultCache = defaultResultCache,
}: {
source: string;
filePath: string;
Expand Down Expand Up @@ -82,7 +84,7 @@ export async function evaluateAndProcess<Type extends 'entryPoint' | 'dependency
nodeModuleCache,
setAdapter: () => setAdapter({
engine,
collectResults: collectedResults,
resultCache: resultCache,
})
}, (dependency) => (
readFile(dependency)
Expand Down Expand Up @@ -118,7 +120,7 @@ export async function evaluateAndProcess<Type extends 'entryPoint' | 'dependency
return compiledFn().then(({ dependencies, exports }) => {
if (type === 'entryPoint') {
return {
result: collectedResults[filePath] || [],
result: resultCache[filePath] || [],
dependencies,
};
}
Expand Down
21 changes: 9 additions & 12 deletions packages/core/src/helpers/setAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import type { GlobalStyleRule, StyleRule } from "@navita/types";

type FilePath = string;

export type CollectedResults = Record<FilePath, {
export type ResultCache = Record<FilePath, {
start: number;
end: number;
value: string;
}[]>;

export function setAdapter({
engine,
collectResults,
resultCache,
}: {
engine: Engine,
collectResults: CollectedResults,
resultCache: ResultCache,
}) {
_setAdapter({
generateIdentifier: (value) => engine.generateIdentifier(value),
Expand All @@ -42,13 +42,6 @@ export function setAdapter({
sourceMap: { line, column },
position,
}) {
if (index === 0) {
if (collectResults) {
collectResults[filePath] = [];
}
engine.clearUsedIds(filePath);
}

engine.setFilePath(filePath);
let result = resultFactory();
engine.setFilePath(undefined);
Expand All @@ -71,9 +64,13 @@ export function setAdapter({
}
}

if (collectResults) {
if (resultCache) {
if (!resultCache[filePath]) {
resultCache[filePath] = [];
}

const [start, end] = position;
collectResults[filePath][index] = {
resultCache[filePath][index] = {
start,
end,
value: result === undefined ? "undefined" : JSON.stringify(result),
Expand Down
11 changes: 9 additions & 2 deletions packages/core/tests/src/evaluateAndProcess.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('evaluateAndProcess', () => {
let moduleCache: Caches['moduleCache'];
let resolverCache: Caches['resolverCache'];
let nodeModuleCache: Caches['nodeModuleCache'];
let resultCache: Caches['resultCache'];

beforeAll(() => {
jest.setTimeout(10000);
Expand All @@ -30,6 +31,7 @@ describe('evaluateAndProcess', () => {
moduleCache = new Map();
resolverCache = {};
nodeModuleCache = {};
resultCache = {};
setAdapter(undefined);
});

Expand Down Expand Up @@ -62,14 +64,20 @@ describe('evaluateAndProcess', () => {
const [filePath] = Object.keys(files || {});
const source = files?.[filePath] || '';

const usedFilePath = path.resolve(basePath, filePath || '');

resultCache[usedFilePath] = [];
engine.clearCache(usedFilePath);

return evaluateAndProcess({
type: 'entryPoint',
filePath: path.resolve(basePath, filePath || ''),
filePath: usedFilePath,
source,
engine,
moduleCache,
resolverCache,
nodeModuleCache,
resultCache,
importMap: [
{
source: '@navita/css',
Expand Down Expand Up @@ -187,7 +195,6 @@ describe('evaluateAndProcess', () => {
});

expect(result).toEqual('something');
expect(engine.clearUsedIds).toHaveBeenCalledWith('cool-filePath');
expect(engine.setFilePath).toHaveBeenNthCalledWith(1, 'cool-filePath');
expect(engine.setFilePath).toHaveBeenNthCalledWith(2, undefined);
expect(engine.setFilePath).toHaveBeenCalledTimes(2);
Expand Down
26 changes: 21 additions & 5 deletions packages/engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import type { SourceMapReference } from "./printers/printSourceMap";
import { printSourceMap } from "./printers/printSourceMap";
import { printStyleBlocks } from "./printers/printStyleBlocks";
import { sortAtRules } from "./printers/sortAtRules";
import { processKeyframes } from "./processKeyframes";
import { processStyles } from "./processStyles";
import type { FontFaceBlock, KeyframesBlock, StyleBlock } from "./types";
import { ClassList } from "./wrappers/classList";
import { Static } from "./wrappers/static";
import { processKeyframes } from "./processKeyframes";

export { ClassList } from "./wrappers/classList";
export { Static } from "./wrappers/static";
Expand Down Expand Up @@ -162,6 +162,16 @@ export class Engine {
return extraClass;
}

private clearSourceMapReferences(filePath: string) {
const newFilePath = path.relative(this.options.context || process.cwd(), filePath);
this.sourceMapReferences[newFilePath] = [];
}

clearCache(filePath: string) {
this.clearUsedIds(filePath);
this.clearSourceMapReferences(filePath);
}

generateIdentifier(value: unknown) {
if (typeof value === 'undefined') {
let identifier = hash((this.identifierCount++).toString(36));
Expand Down Expand Up @@ -222,10 +232,16 @@ export class Engine {
return '';
}

return printSourceMap(
this.sourceMapReferences,
keyFrameCss + fontFaceCss + staticCss + rulesCss + atRulesCss
);
const content = keyFrameCss + fontFaceCss + staticCss + rulesCss + atRulesCss;

if (this.options.enableSourceMaps) {
return printSourceMap(
this.sourceMapReferences,
content,
);
}

return content;
}

serialize() {
Expand Down
1 change: 1 addition & 0 deletions packages/vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export function navita(options?: Options) {
async transform(code, id) {
// Bail as early as we can
if (!importMap.map((x) => x.source).some((value) => code.indexOf(value) !== -1)) {
renderer.clearCache(id);
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/webpack-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export class NavitaPlugin {
compiler.hooks.afterEmit.tapPromise(NavitaPlugin.pluginName, async (compilation) => {
await compilation
.getCache(NavitaPlugin.pluginName)
.storePromise(NavitaPlugin.pluginName, cacheKey, renderer.engine.serialize());
.storePromise(NavitaPlugin.pluginName, cacheKey, Buffer.from(renderer.engine.serialize()));
});
});

Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-plugin/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default async function loader(
sourceMap: LoaderParams[1],
) {
const callback = this.async();
const { resourcePath } = this;
const { importMap, renderer, NavitaDependency, outputCss } = this.getOptions();

// Bail as early as we can.
Expand All @@ -27,12 +28,11 @@ export default async function loader(
!importMap.map((x) => x.source).some(
(value) => content.indexOf(value) !== -1
)) {
renderer.clearCache(resourcePath);
return callback(null, content, sourceMap);
}

try {
const { resourcePath } = this;

const { result, dependencies, usedIds, sourceMap } = await renderer.transformAndProcess({
content,
filePath: resourcePath,
Expand Down
9 changes: 8 additions & 1 deletion packages/webpack-plugin/tests/src/loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import loader from '../../src/loader';

describe('loader.tests.ts', () => {
let callback: jest.Mock;
let clearCacheFn: jest.Mock;

let doneHook: AsyncSeriesHook<void>;
let watchCloseHook: SyncHook<void>;

beforeEach(() => {
callback = jest.fn();
clearCacheFn = jest.fn();
doneHook = new AsyncSeriesHook();
watchCloseHook = new SyncHook();
});
Expand All @@ -21,7 +23,9 @@ describe('loader.tests.ts', () => {
cacheable: () => undefined,
getOptions: () => ({
importMap: [...(options.importMap || [])],
renderer: undefined,
renderer: {
clearCache: clearCacheFn,
},
}),
resourcePath: options.fileName || undefined,
_module: {
Expand Down Expand Up @@ -53,6 +57,7 @@ describe('loader.tests.ts', () => {

await loader.call(context, input, sourceMap);
expect(callback).toHaveBeenCalledWith(null, input, sourceMap);
expect(clearCacheFn).toHaveBeenCalledWith(undefined);
});

it('should bail if no callExpressions', async () => {
Expand All @@ -61,6 +66,7 @@ describe('loader.tests.ts', () => {

await loader.call(createLoaderContext(), input, sourceMap);
expect(callback).toHaveBeenCalledWith(null, input, sourceMap);
expect(clearCacheFn).toHaveBeenCalledWith(undefined);
});

it('should bail if no import found', async () => {
Expand All @@ -72,6 +78,7 @@ describe('loader.tests.ts', () => {

await loader.call(createLoaderContext(), input, sourceMap);
expect(callback).toHaveBeenCalledWith(null, input, sourceMap);
expect(clearCacheFn).toHaveBeenCalledWith(undefined);
});

it('should callback with errors on errors', async () => {
Expand Down

0 comments on commit 634e291

Please sign in to comment.