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

fix(hot-reload): fix actions conflicts during hot-reload + change transpilation phase #633

Merged
merged 3 commits into from
Nov 16, 2024
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
12 changes: 0 additions & 12 deletions packages/brisa/src/__fixtures__/actions/a1.tsx

This file was deleted.

10 changes: 0 additions & 10 deletions packages/brisa/src/__fixtures__/actions/a2.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
import type { RequestContext } from '@/types';

export function a1_1(props: any) {
console.log('a1_1', props);
}

export function a1_2(props: any) {
return 'a1_2';
}

export function a1_3(props: any, req: any) {
const [event] = req.store.get('__params:a1_3');
event.target.reset(); // Simulate a form reset
}

export async function a2_1({ onAction }: any) {
return 'a2_1' + ((await onAction?.('foo')) ?? '');
}

export function a2_2({}, req: RequestContext) {
const foo = req.store.get('__params:a2_2')[0];
return '-a2_2-' + foo;
}

export async function a3_1({ onAction2 }: any, req: any) {
const [withAwait] = req.store.get('__params:a3_1');
console.log('a3_1 before calling nested action');
Expand Down
1 change: 1 addition & 0 deletions packages/brisa/src/cli/dev-live-reload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ async function activateHotReload() {
if (!globalThis.brisaServer) return;

await reinitConstants();
Object.keys(require.cache).forEach((key) => delete require.cache[key]);
globalThis.brisaServer.publish('hot-reload', LIVE_RELOAD_COMMAND);

if (waitFilename) {
Expand Down
5 changes: 2 additions & 3 deletions packages/brisa/src/cli/serve/serve-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,8 @@ export async function getServeOptions() {

// Middleware
if (customMiddleware) {
const middlewareResponse = await Promise.resolve().then(() =>
customMiddleware(req),
);
// @ts-ignore TODO: Remove this comment when TypeScript adds Promise.try
const middlewareResponse = await Promise.try(() => customMiddleware(req));

if (middlewareResponse) return middlewareResponse;
}
Expand Down
10 changes: 5 additions & 5 deletions packages/brisa/src/utils/compile-files/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ describe('utils', () => {
).text();

expect(homePageContent).toContain(
`"data-action-onclick":"a1_1","data-action"`,
`"data-action-onclick":"a2n9c_1","data-action"`,
);
expect(homePageContent).toContain(
`"data-action-onclick":"a1_2","data-action"`,
`"data-action-onclick":"a2n9c_2","data-action"`,
);

const pagesClient = fs
Expand Down Expand Up @@ -283,7 +283,7 @@ describe('utils', () => {
${info}Ω /i18n | 162 B |
${info}Ψ /websocket | 207 B |
${info}Θ /web-components/_integrations | 67 B |
${info}λ /pages/index | 821 B | ${greenLog('3 kB')}
${info}λ /pages/index | 827 B | ${greenLog('3 kB')}
${info}λ /pages/page-with-web-component | 761 B | ${greenLog('5 kB')}
${info}λ /pages/somepage | 1 kB | ${greenLog('0 B')}
${info}λ /pages/somepage-with-context | 1 kB | ${greenLog('0 B')}
Expand Down Expand Up @@ -433,7 +433,7 @@ describe('utils', () => {
).text();

expect(layoutContent).toContain(
`"data-action-onclick":"a1_1","data-action"`,
`"data-action-onclick":"a2n9c_1","data-action"`,
);

const pagesClient = fs
Expand Down Expand Up @@ -464,7 +464,7 @@ describe('utils', () => {
${info}Route | JS server | JS client (gz)
${info}----------------------------------------------
${info}λ /pages/index | 444 B | ${greenLog('3 kB')}
${info}Δ /layout | 706 B |
${info}Δ /layout | 709 B |
${info}
${info}λ Server entry-points
${info}Δ Layout
Expand Down
11 changes: 7 additions & 4 deletions packages/brisa/src/utils/compile-files/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { logTable } from '@/utils/log/log-build';
import serverComponentPlugin from '@/utils/server-component-plugin';
import createContextPlugin from '@/utils/create-context/create-context-plugin';
import getI18nClientMessages from '@/utils/get-i18n-client-messages';
import compileActions from '@/utils/compile-actions';
import { transpileActions, buildActions } from '@/utils/transpile-actions';
import generateStaticExport from '@/utils/generate-static-export';
import getWebComponentsPerEntryPoints from '@/utils/get-webcomponents-per-entrypoints';
import { shouldTransferTranslatedPagePaths } from '@/utils/transfer-translated-page-paths';
Expand Down Expand Up @@ -102,7 +102,7 @@ export default async function compileFiles() {
let code = await Bun.file(path).text();

try {
const fileID = `a${actionIdCount}`;
const fileID = `a${Bun.hash(path).toString(36)}`;
const result = serverComponentPlugin(code, {
path,
allWebComponents,
Expand All @@ -117,7 +117,10 @@ export default async function compileFiles() {

actionsEntrypoints.push(actionEntrypoint);
actionIdCount += 1;
await Bun.write(actionEntrypoint, result.code);
await Bun.write(
actionEntrypoint,
transpileActions(result.code),
);
}

code = result.code;
Expand Down Expand Up @@ -145,7 +148,7 @@ export default async function compileFiles() {
if (!success) return { success, logs, pagesSize: {} };

if (actionsEntrypoints.length) {
const actionResult = await compileActions({ actionsEntrypoints, define });
const actionResult = await buildActions({ actionsEntrypoints, define });
if (!actionResult.success) logs.push(...actionResult.logs);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const i18nCode = 2799;
const brisaSize = 5720; // TODO: Reduce this size :/
const webComponents = 1107;
const unsuspenseSize = 213;
const rpcSize = 2509; // TODO: Reduce this size
const rpcSize = 2500; // TODO: Reduce this size
const lazyRPCSize = 4105; // TODO: Reduce this size
// lazyRPC is loaded after user interaction (action, link),
// so it's not included in the initial size
Expand Down
3 changes: 2 additions & 1 deletion packages/brisa/src/utils/import-file-if-exists/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export default async function importFileIfExists(
| 'i18n'
| 'brisa.config'
| '_integrations'
| 'css-files',
| 'css-files'
| 'actions',
dir = path.join(process.cwd(), 'build'),
) {
const importablePath = getImportableFilepath(filename, dir);
Expand Down
8 changes: 1 addition & 7 deletions packages/brisa/src/utils/response-action/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from 'bun:test';
import path from 'node:path';
import extendRequestContext from '@/utils/extend-request-context';
import responseAction, { getActionFile } from '.';
import responseAction from '.';
import { getConstants } from '@/constants';
import { ENCRYPT_NONTEXT_PREFIX, encrypt } from '@/utils/crypto';
import { boldLog } from '@/utils/log/log-color';
Expand Down Expand Up @@ -847,10 +847,4 @@ describe('utils', () => {
expect(await res.text()).toBe(JSON.stringify([['foo', 'bar']]));
});
});

describe('getActionFile', () => {
it('should return the file with the .js extension to work in Node.js and Bun.js', () => {
expect(getActionFile('a1_1')).toBe('a1.js');
});
});
});
28 changes: 6 additions & 22 deletions packages/brisa/src/utils/response-action/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import { join } from 'node:path';
import { getConstants } from '@/constants';
import type { RequestContext } from '@/types';
import { deserialize } from '@/utils/serialization';
import transferStoreService from '@/utils/transfer-store-service';
import { resolveStore } from '@/utils/transfer-store-service';
import { logError } from '@/utils/log/log-build';
import { pathToFileURLWhenNeeded } from '../get-importable-filepath';
import importFileIfExists from '../import-file-if-exists';
import { getConstants } from '@/constants';

const DEPENDENCIES = Symbol.for('DEPENDENCIES');

export default async function responseAction(req: RequestContext) {
const { BUILD_DIR } = getConstants();
const actionModule = await importFileIfExists('actions', BUILD_DIR);

const { transferClientStoreToServer, formData, body } =
await transferStoreService(req);
const { BUILD_DIR } = getConstants();
const url = new URL(req.url);
const action =
req.headers.get('x-action') ?? url.searchParams.get('_aid') ?? '';
const actionsHeaderValue = req.headers.get('x-actions') ?? '[]';
const actionFile = getActionFile(action);
const actionModule = await import(
pathToFileURLWhenNeeded(join(BUILD_DIR, 'actions', actionFile!))
);
let resetForm = false;

const target = {
Expand Down Expand Up @@ -90,19 +88,9 @@ export default async function responseAction(req: RequestContext) {
for (const [eventName, actionId] of actions) {
nextProps[eventName] = async (...params: unknown[]) => {
const { promise, resolve, reject } = Promise.withResolvers();
const actionDependency = actionModule[actionId];

actionCallPromises.push([actionId, promise]);

const file = actionId.split('_').at(0);
const actionDependency =
file === actionFile
? actionModule[actionId]
: (
await import(
pathToFileURLWhenNeeded(join(BUILD_DIR, 'actions', file!))
)
)[actionId];

req.store.set(`__params:${actionId}`, params);

try {
Expand Down Expand Up @@ -211,7 +199,3 @@ export default async function responseAction(req: RequestContext) {

return response;
}

export function getActionFile(action: string) {
return action.split('_').at(0) + '.js';
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { normalizeHTML } from '@/helpers';
import AST from '@/utils/ast';
import { describe, it, expect } from 'bun:test';
import { getPurgedBody } from '.';
import getActionsInfo from '@/utils/compile-actions/get-actions-info';
import getActionsInfo from '@/utils/transpile-actions/get-actions-info';

const { parseCodeToAST, generateCodeFromAST } = AST('tsx');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ESTree } from 'meriyah';
import type { ActionInfo } from '@/utils/compile-actions/get-actions-info';
import type { ActionInfo } from '@/utils/transpile-actions/get-actions-info';
import removeAllReturns from '@/utils/ast/remove-all-returns';
import containsIdentifiers from '@/utils/ast/contains-identifiers';
import getAllIdentifiers from '@/utils/ast/get-all-identifiers';
Expand Down
Loading
Loading