Skip to content

Commit b97f05b

Browse files
Refactor imports to use local utils module
- Updated import paths in multiple files to reference the new local utils.ts module instead of the previous utils from 'react-on-rails'. - Introduced utils.ts with utility functions including fetch, createRSCPayloadKey, wrapInNewPromise, and extractErrorMessage. These changes enhance modularity and maintainability of the codebase.
1 parent 1e05f49 commit b97f05b

File tree

9 files changed

+139
-11
lines changed

9 files changed

+139
-11
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// eslint-disable-next-line import/no-relative-packages
2+
import rootConfig from '../../jest.config.base.js';
3+
4+
const nodeVersion = parseInt(process.version.slice(1), 10);
5+
6+
// Package-specific Jest configuration
7+
// Inherits from root jest.config.mjs and adds package-specific settings
8+
export default {
9+
// Inherit all settings from root
10+
...rootConfig,
11+
12+
// Override: Package-specific test directory
13+
testMatch: ['<rootDir>/tests/**/?(*.)+(spec|test).[jt]s?(x)'],
14+
15+
// Package-specific: Jest setup files
16+
setupFiles: ['<rootDir>/tests/jest.setup.js'],
17+
18+
// Package-specific: Module name mapping for React Server Components
19+
// Only mock modules on Node versions < 18 where RSC features aren't available
20+
moduleNameMapper:
21+
nodeVersion < 18
22+
? {
23+
'react-on-rails-rsc/client': '<rootDir>/tests/emptyForTesting.js',
24+
'^@testing-library/dom$': '<rootDir>/tests/emptyForTesting.js',
25+
'^@testing-library/react$': '<rootDir>/tests/emptyForTesting.js',
26+
}
27+
: {},
28+
29+
// Set root directory to current package
30+
rootDir: '.',
31+
};

packages/react-on-rails-pro/src/RSCProvider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import * as React from 'react';
1616
import type { ClientGetReactServerComponentProps } from './getReactServerComponent.client.ts';
17-
import { createRSCPayloadKey } from 'react-on-rails/utils';
17+
import { createRSCPayloadKey } from './utils.ts';
1818

1919
type RSCContextType = {
2020
getComponent: (componentName: string, componentProps: unknown) => Promise<React.ReactNode>;

packages/react-on-rails-pro/src/RSCRequestTracker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414

1515
import { PassThrough, Readable } from 'stream';
16-
import { extractErrorMessage } from 'react-on-rails/utils';
16+
import { extractErrorMessage } from './utils.ts';
1717
import {
1818
RSCPayloadStreamInfo,
1919
RSCPayloadCallback,

packages/react-on-rails-pro/src/getReactServerComponent.client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import * as React from 'react';
1616
import { createFromReadableStream } from 'react-on-rails-rsc/client.browser';
17-
import { createRSCPayloadKey, fetch, wrapInNewPromise, extractErrorMessage } from 'react-on-rails/utils';
17+
import { createRSCPayloadKey, fetch, wrapInNewPromise, extractErrorMessage } from './utils.ts';
1818
import transformRSCStreamAndReplayConsoleLogs from './transformRSCStreamAndReplayConsoleLogs.ts';
1919
import { RailsContext } from 'react-on-rails/types';
2020

packages/react-on-rails-pro/src/injectRSCPayload.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import { PassThrough } from 'stream';
1616
import { finished } from 'stream/promises';
17-
import { createRSCPayloadKey } from 'react-on-rails/utils';
17+
import { createRSCPayloadKey } from './utils.ts';
1818
import { PipeableOrReadableStream } from 'react-on-rails/types';
1919
import RSCRequestTracker from './RSCRequestTracker.ts';
2020

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const customFetch = (...args: Parameters<typeof fetch>) => {
2+
const res = fetch(...args);
3+
return res;
4+
};
5+
6+
export { customFetch as fetch };
7+
8+
export const createRSCPayloadKey = (componentName: string, componentProps: unknown, domNodeId?: string) => {
9+
return `${componentName}-${JSON.stringify(componentProps)}${domNodeId ? `-${domNodeId}` : ''}`;
10+
};
11+
12+
export const wrapInNewPromise = <T>(promise: Promise<T>) => {
13+
return new Promise<T>((resolve, reject) => {
14+
void promise.then(resolve);
15+
void promise.catch(reject);
16+
});
17+
};
18+
19+
export const extractErrorMessage = (error: unknown): string => {
20+
return error instanceof Error ? error.message : String(error);
21+
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// If jsdom environment is set and TextEncoder is not defined, then define TextEncoder and TextDecoder
2+
// The current version of jsdom does not support TextEncoder and TextDecoder
3+
// The following code will tell us when jsdom supports TextEncoder and TextDecoder
4+
if (typeof window !== 'undefined' && typeof window.TextEncoder !== 'undefined') {
5+
throw new Error('TextEncoder is already defined, remove the polyfill');
6+
}
7+
8+
// Similarly for MessageChannel
9+
if (typeof window !== 'undefined' && typeof window.MessageChannel !== 'undefined') {
10+
throw new Error('MessageChannel is already defined, remove the polyfill');
11+
}
12+
13+
if (typeof window !== 'undefined') {
14+
// eslint-disable-next-line global-require
15+
const { TextEncoder, TextDecoder } = require('util');
16+
// eslint-disable-next-line global-require
17+
const { Readable } = require('stream');
18+
// eslint-disable-next-line global-require
19+
const { ReadableStream, ReadableStreamDefaultReader } = require('stream/web');
20+
21+
// Mock the fetch function to return a ReadableStream instead of Node's Readable stream
22+
// This matches browser behavior where fetch responses have ReadableStream bodies
23+
// Node's fetch and polyfills like jest-fetch-mock return Node's Readable stream,
24+
// so we convert it to a web-standard ReadableStream for consistency
25+
// Note: Node's Readable stream exists in node 'stream' built-in module, can be imported as `import { Readable } from 'stream'`
26+
jest.mock('../src/utils', () => ({
27+
...jest.requireActual('../src/utils'),
28+
fetch: (...args) =>
29+
jest
30+
.requireActual('../src/utils')
31+
.fetch(...args)
32+
.then((res) => {
33+
const originalBody = res.body;
34+
if (originalBody instanceof Readable) {
35+
Object.defineProperty(res, 'body', {
36+
value: Readable.toWeb(originalBody),
37+
});
38+
}
39+
return res;
40+
}),
41+
}));
42+
43+
global.TextEncoder = TextEncoder;
44+
global.TextDecoder = TextDecoder;
45+
46+
// https://github.com/jsdom/jsdom/issues/2448#issuecomment-1703763542
47+
global.MessageChannel = jest.fn().mockImplementation(() => {
48+
let onmessage;
49+
return {
50+
port1: {
51+
set onmessage(cb) {
52+
onmessage = cb;
53+
},
54+
},
55+
port2: {
56+
postMessage: (data) => {
57+
onmessage?.({ data });
58+
},
59+
},
60+
};
61+
});
62+
global.ReadableStream = ReadableStream;
63+
global.ReadableStreamDefaultReader = ReadableStreamDefaultReader;
64+
}
65+
66+
if (!['yes', 'true', 'y', 't'].includes(process.env.ENABLE_JEST_CONSOLE || ''.toLowerCase())) {
67+
global.console.log('All calls to console have been disabled in jest.setup.js');
68+
69+
global.console = {
70+
log: jest.fn(),
71+
error: jest.fn(),
72+
warn: jest.fn(),
73+
info: jest.fn(),
74+
debug: jest.fn(),
75+
};
76+
}

packages/react-on-rails-pro/tests/registerServerComponent.client.test.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { screen, act } from '@testing-library/react';
99
import '@testing-library/jest-dom';
1010
import * as path from 'path';
1111
import * as fs from 'fs';
12-
import { createNodeReadableStream, getNodeVersion } from './testUtils.js';
13-
import ReactOnRails from '../src/ReactOnRails.client.ts';
14-
import registerServerComponent from '../src/pro/registerServerComponent/client.tsx';
15-
import { clear as clearComponentRegistry } from '../src/pro/ComponentRegistry.ts';
12+
import { createNodeReadableStream, getNodeVersion } from '../../react-on-rails/tests/testUtils.js';
13+
import ReactOnRails from '../src/index.ts';
14+
import registerServerComponent from '../src/registerServerComponent/client.tsx';
15+
import { clear as clearComponentRegistry } from '../src/ComponentRegistry.ts';
1616

1717
enableFetchMocks();
1818

packages/react-on-rails-pro/tests/streamServerRenderedReactComponent.test.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import * as React from 'react';
66
import * as PropTypes from 'prop-types';
7-
import streamServerRenderedReactComponent from '../src/pro/streamServerRenderedReactComponent.ts';
8-
import * as ComponentRegistry from '../src/pro/ComponentRegistry.ts';
9-
import ReactOnRails from '../src/ReactOnRails.node.ts';
7+
import streamServerRenderedReactComponent from '../src/streamServerRenderedReactComponent.ts';
8+
import * as ComponentRegistry from '../src/ComponentRegistry.ts';
9+
import ReactOnRails from '../src/index.ts';
1010

1111
const AsyncContent = async ({ throwAsyncError }) => {
1212
await new Promise((resolve) => {

0 commit comments

Comments
 (0)