Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging.. #96

Merged
merged 15 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/validate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ jobs:
run: npm run test
build:
name: 🏗️ Build
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
22,253 changes: 10,145 additions & 12,108 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@commitlint/prompt-cli": "^17.7.1",
"@types/semver": "^7.5.2",
"@vitest/coverage-v8": "^0.34.4",
"@types/semver": "^7.5.3",
"@vitest/coverage-v8": "^0.34.5",
"esbuild": "^0.19.3",
"esbuild-node-externals": "^1.9.0",
"glob": "^10.3.10",
"husky": "^8.0.3",
"lint-staged": "^14.0.1",
"npm-run-all": "^4.1.5",
Expand All @@ -41,7 +42,7 @@
"semver": "^7.5.4",
"turbo": "^1.10.14",
"typescript": "^5.2.2",
"vitest": "^0.34.4"
"vitest": "^0.34.5"
},
"engines": {
"node": ">=18.0.0"
Expand Down
10 changes: 6 additions & 4 deletions packages/cache/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
## @remix-pwa/cache 2.0.9 (2023-09-26)
## @remix-pwa/cache 2.0.9-dev.3 (2023-09-27)


### Bug Fixes

* **cache:** fixed LRU cleanup workflow in cache 2dc0449
* **cache:** improved cache catch 4fec009

## @remix-pwa/cache 2.0.9-dev.2 (2023-09-27)

### Performance Improvements

* **cache:** slightly improved lru algo bec7ca3
### Bug Fixes

* **cache:** fixed cache issue during redirects 50007f2

## @remix-pwa/cache 2.0.9-dev.1 (2023-09-26)

Expand Down
2 changes: 1 addition & 1 deletion packages/cache/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-pwa/cache",
"version": "2.0.9",
"version": "2.0.9-dev.3",
"description": "A thin-layered wrapper around the browser's Cache Storage API that supercharges your Remix PWA's caching capabilities.",
"repository": {
"type": "git",
Expand Down
23 changes: 11 additions & 12 deletions packages/cache/src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,12 @@ export class RemixCache implements CustomCache {
return false;
}

private async _values() {
const cache = await this._openCache();
const keys = await cache.keys();
return (await Promise.all(keys.map(key => cache.match(key)))) as Response[];
}

private async _lruCleanup() {
const isOverflowing = (await this.length()) >= this._maxItems;

if (isOverflowing) {
if (process.env.NODE_ENV === 'development')
console.log(`Cache '${this.name}' is overflowing. Running LRU cleanup.`);
// if (process.env.NODE_ENV === 'development')
// console.log(`Cache '${this.name}' is overflowing. Running LRU cleanup.`);

const cache = await this._openCache();
const keys = await cache.keys();
Expand All @@ -166,6 +160,11 @@ export class RemixCache implements CustomCache {
const keyVal = keys.map((key, i) => ({ key, val: values[i] }));

const comparableArrayPromise = keyVal.map(async val => {
if (this.name !== 'assets-cache') {
console.log('inner', val);
console.log('inner-2', (await val.val.clone().text()).slice(0, 20));
}

const { metadata }: ResponseBody = await val.val.clone().json();

return {
Expand All @@ -177,13 +176,13 @@ export class RemixCache implements CustomCache {
const comparableArray = await Promise.all(comparableArrayPromise);

const sortedArr = comparableArray.sort((a, b) => {
return a.metadata.accessedAt - b.metadata.accessedAt;
return Number(a.metadata.accessedAt) - Number(b.metadata.accessedAt);
});

const toBeDeletdItems = sortedArr.slice(0, sortedArr.length - this._maxItems + 1);

if (process.env.NODE_ENV === 'development')
console.log(`Deleting ${toBeDeletdItems.length} items from ${this.name} cache.`);
// if (process.env.NODE_ENV === 'development')
// console.log(`Deleting ${toBeDeletdItems.length} items from ${this.name} cache.`);

for (const deleted of toBeDeletdItems) {
// This runs everytime a new entry is added so that means the array maximum size can never
Expand Down Expand Up @@ -343,7 +342,7 @@ export class RemixCache implements CustomCache {
// If ttl is negative, don't cache
if (this._ttl <= 0 || (ttl && ttl <= 0)) return;

if (response === null || response.clone().body === null) {
if (response === null || response.status === 204 || response.statusText.toLowerCase() === 'no content') {
// If the response/response body is null, delete the entry (if found)
// and don't cache.
await this.delete(request);
Expand Down
7 changes: 7 additions & 0 deletions packages/dev/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## @remix-pwa/dev 2.0.26-dev.1 (2023-09-27)


### Bug Fixes

* **compiler:** handle imports on different OS 76a9d65

## @remix-pwa/dev 2.0.25-dev.1 (2023-09-26)


Expand Down
3 changes: 2 additions & 1 deletion packages/dev/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const TIME_LABEL = '💿 Built in';
function createEsbuildConfig(config: ResolvedWorkerConfig): BuildOptions {
const pluginContext = { config } as unknown as Context;
return {
absWorkingDir: config.rootDirectory,
entryPoints: {
[config.workerName]: config.worker,
},
Expand Down Expand Up @@ -54,7 +55,7 @@ function createEsbuildConfig(config: ResolvedWorkerConfig): BuildOptions {
// we need to generate a list of all the assets generated by the client bundle.
assetsPlugin(config),
// we need to tag the user entry.worker as sideEffect so esbuild will not remove it
sideEffectsPlugin(),
sideEffectsPlugin(config),
],
supported: {
'import-meta': true,
Expand Down
7 changes: 4 additions & 3 deletions packages/dev/compiler/plugins/__test__/assets-module.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ResolvedWorkerConfig } from '@remix-pwa/dev/dist/compiler/utils/config';
import type { OnLoadArgs, PluginBuild } from 'esbuild';
import type { MockedObject } from 'vitest';
import { afterAll, beforeEach, describe, expect, test, vi } from 'vitest';
Expand All @@ -10,7 +11,7 @@ describe('assets-module plugin', () => {
rootDirectory: '/root/',
assetsBuildDirectory: '/path/to/assets',
publicPath: 'public/build',
};
} as ResolvedWorkerConfig;

beforeEach(() => {
mockGlob.mockClear();
Expand All @@ -35,9 +36,9 @@ describe('assets-module plugin', () => {
onLoad: vi.fn(),
} as unknown as PluginBuild;
await plugin.setup(build);
expect(build.onResolve).toHaveBeenCalledWith({ filter: /@remix-sas\/dev\?assets/ }, expect.any(Function));
expect(build.onResolve).toHaveBeenCalledWith({ filter: /@remix-pwa\/dev\?assets/ }, expect.any(Function));
expect(build.onLoad).toHaveBeenCalledWith(
{ filter: /@remix-sas\/dev\?assets/, namespace: 'assets-module' },
{ filter: /@remix-pwa\/dev\?assets/, namespace: 'assets-module' },
expect.any(Function)
);
});
Expand Down
16 changes: 6 additions & 10 deletions packages/dev/compiler/plugins/__test__/entry-module.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ describe('entry-module plugin', () => {
expect(result).toHaveProperty('contents');
expect(result.contents).toMatchInlineSnapshot(`
"
import * as entryWorker from 'entry-worker.js?user';
import * as entryWorker from \\"entry-worker.js\\";

import * as route0 from 'routes/home.js?worker';
import * as route1 from 'routes/about.js?worker';
import * as route0 from \\"routes/home.js?worker\\";
import * as route1 from \\"routes/about.js?worker\\";

export const routes = {
\\"/\\": {
Expand All @@ -71,23 +71,19 @@ describe('entry-module plugin', () => {
path: \\"/\\",
index: undefined,
caseSensitive: undefined,
module: route0,
hasWorkerAction: Boolean(route0.hasWorkerAction),
hasWorkerLoader: Boolean(route0.hasWorkerLoader),
module: route0
},
\\"/about\\": {
id: \\"/about\\",
parentId: undefined,
path: \\"/about\\",
index: undefined,
caseSensitive: undefined,
module: route1,
hasWorkerAction: Boolean(route1.hasWorkerAction),
hasWorkerLoader: Boolean(route1.hasWorkerLoader),
module: route1
}
};

export { assets } from '@remix-sas/dev?assets';
export { assets } from '@remix-pwa/dev?assets';
export const entry = { module: entryWorker };
"
`);
Expand Down
9 changes: 1 addition & 8 deletions packages/dev/compiler/plugins/__test__/routes-module.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,7 @@ describe('routesModulesPlugin', () => {
const onLoadCallback = build.onLoad.mock.calls[0][1];
const result = await onLoadCallback({ path: 'routes/home.js?worker' });

expect(result).toHaveProperty(
'contents',
expect.stringContaining(
'export { workerAction, workerLoader } from "./routes/home.js";\n' +
' export const hasWorkerAction = true;\n' +
' export const hasWorkerLoader = true'
)
);
expect(result.contents).toMatchInlineSnapshot('"export { workerAction, workerLoader } from \\"./routes/home.js\\";"');
expect(result).not.toHaveProperty('contents', expect.stringContaining('otherExport'));
});

Expand Down
12 changes: 8 additions & 4 deletions packages/dev/compiler/plugins/__test__/side-effects.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import type { PluginBuild } from 'esbuild';
import { describe, expect, test, vi } from 'vitest';

import type { ResolvedWorkerConfig } from '../../utils/config.js';
import sideEffectsPlugin from '../side-effects.js';

describe('sideEffectsPlugin', () => {
const config: ResolvedWorkerConfig = {
entryWorkerFile: 'entry-worker.js',
} as unknown as ResolvedWorkerConfig;
test('should return an esbuild plugin object', () => {
const plugin = sideEffectsPlugin();
const plugin = sideEffectsPlugin(config);
expect(plugin).toHaveProperty('name', 'sw-side-effects');
expect(plugin).toHaveProperty('setup');
});

test('should transform modules that match the filter regex', async () => {
const plugin = sideEffectsPlugin();
const plugin = sideEffectsPlugin(config);
const build = {
onResolve: vi.fn(),
onLoad: vi.fn(),
Expand All @@ -22,7 +26,7 @@ describe('sideEffectsPlugin', () => {
});

test('should set sideEffects to true for modules that match the filter regex', async () => {
const plugin = sideEffectsPlugin();
const plugin = sideEffectsPlugin(config);
const build = {
onResolve: vi.fn(),
onLoad: vi.fn(),
Expand All @@ -35,7 +39,7 @@ describe('sideEffectsPlugin', () => {
});

test('should set the loader to "js" for modules that match the filter regex', async () => {
const plugin = sideEffectsPlugin();
const plugin = sideEffectsPlugin(config);
const build = {
onResolve: vi.fn(),
onLoad: vi.fn(),
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/compiler/plugins/assets-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { ResolvedWorkerConfig } from '../utils/config.js';

const { glob } = pkg;

const FILTER_REGEX = /@remix-sas\/dev\?assets/;
const FILTER_REGEX = /@remix-pwa\/dev\?assets/;
const NAMESPACE = 'assets-module';

export default function assetsPlugin(config: ResolvedWorkerConfig): Plugin {
Expand Down
12 changes: 6 additions & 6 deletions packages/dev/compiler/plugins/entry-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const NAMESPACE = 'entry-module';
* Creates a string representation of the routes to be imported
*/
function createRouteImports(routes: ConfigRoute[]): string {
return routes.map((route, index) => `import * as route${index} from '${route.file}?worker';`).join('\n');
return routes
.map((route, index) => `import * as route${index} from ${JSON.stringify(`${route.file}?worker`)};`)
.join('\n');
}

/**
Expand All @@ -26,9 +28,7 @@ function createRouteManifest(routes: RouteManifest): string {
path: ${JSON.stringify(route.path)},
index: ${JSON.stringify(route.index)},
caseSensitive: ${JSON.stringify(route.caseSensitive)},
module: route${index},
hasWorkerAction: Boolean(route${index}.hasWorkerAction),
hasWorkerLoader: Boolean(route${index}.hasWorkerLoader),
module: route${index}
}`
)
.join(',\n');
Expand All @@ -49,15 +49,15 @@ export default function entryModulePlugin(config: ResolvedWorkerConfig): Plugin
const onLoad = () => {
const routes = Object.values(config.routes);
const contents = `
import * as entryWorker from '${config.entryWorkerFile}?user';
import * as entryWorker from ${JSON.stringify(config.entryWorkerFile)};

${createRouteImports(routes)}

export const routes = {
${createRouteManifest(config.routes)}
};

export { assets } from '@remix-sas/dev?assets';
export { assets } from '@remix-pwa/dev?assets';
export const entry = { module: entryWorker };
`;

Expand Down
4 changes: 1 addition & 3 deletions packages/dev/compiler/plugins/routes-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export default function routesModulesPlugin(config: ResolvedWorkerConfig): Plugi
let contents = 'module.exports = {};';
if (theExports.length > 0) {
const spec = `{ ${theExports.join(', ')} }`;
contents = `export ${spec} from ${JSON.stringify(`./${file}`)};
export const hasWorkerAction = ${theExports.includes('workerAction')};
export const hasWorkerLoader = ${theExports.includes('workerLoader')}`;
contents = `export ${spec} from ${JSON.stringify(`./${file}`)};`;
}
return {
contents,
Expand Down
9 changes: 5 additions & 4 deletions packages/dev/compiler/plugins/side-effects.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { OnLoadResult, OnResolveArgs, Plugin, PluginBuild } from 'esbuild';
import type { OnLoadResult, Plugin, PluginBuild } from 'esbuild';

import type { ResolvedWorkerConfig } from '../utils/config.js';
const FILTER_REGEX = /\?user$/;

/**
* The `sw-side-effects` plugin marks the user entry.worker as sideEffect to prevent esbuild from tree shaking it.
*/
export default function sideEffectsPlugin(): Plugin {
export default function sideEffectsPlugin(config: ResolvedWorkerConfig): Plugin {
async function setup(build: PluginBuild) {
const onResolve = ({ path }: OnResolveArgs) => ({
path: path.replace(FILTER_REGEX, ''),
const onResolve = () => ({
path: config.entryWorkerFile,
sideEffects: true,
});

Expand Down
5 changes: 3 additions & 2 deletions packages/dev/compiler/utils/__test__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ vi.doMock('node:module', async () => ({

describe('readConfig', () => {
afterEach(() => {
vi.clearAllMocks();
vi.restoreAllMocks();
});
afterAll(() => {
vi.doUnmock('@remix-run/dev/dist/config');
Expand All @@ -47,8 +47,8 @@ describe('readConfig', () => {
});

test('should return the resolved config object with default worker options', async () => {
mockResolve.mockReturnValue('public').mockReturnValueOnce('entry.worker.ts').mockReturnValueOnce('entry.worker.ts');
mockExists.mockReturnValue(false);
mockResolve.mockReturnValue('/public');

vi.doMock('./remix.config.ts', () => {
return { default: {} };
Expand Down Expand Up @@ -87,6 +87,7 @@ describe('readConfig', () => {
});

test('should return the resolved config object with custom worker options', async () => {
mockResolve.mockReturnValue(undefined);
mockExists.mockReturnValue(false);

vi.doMock('./remix.config.ts', () => {
Expand Down
5 changes: 4 additions & 1 deletion packages/dev/compiler/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,14 @@ async function importWorkerConfig(root: string): Promise<WorkerConfig> {
export default async function readConfig(remixRoot: string, mode: ServerMode): Promise<ResolvedWorkerConfig> {
const remixConfig = await _readConfig(remixRoot, mode);
const workerConfig = await importWorkerConfig(remixRoot);
const entryWorkerFile = findEntry(remixConfig.appDirectory, 'entry.worker');

return {
...remixConfig,
entryWorkerFile:
workerConfig.entryWorkerFile ?? findEntry(remixConfig.appDirectory, 'entry.worker') ?? DEFAULT_ENTRY_WORKER_FILE,
workerConfig.entryWorkerFile ?? entryWorkerFile
? resolve(remixConfig.appDirectory, entryWorkerFile as string)
: DEFAULT_ENTRY_WORKER_FILE,
worker: workerConfig.worker ?? _require.resolve('@remix-pwa/worker-runtime'),
workerBuildDirectory: workerConfig.workerBuildDirectory ?? resolve('./public'),
workerName: workerConfig.workerName ?? 'entry.worker',
Expand Down
Loading
Loading