Skip to content
Open
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
10 changes: 7 additions & 3 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,18 @@ jobs:
run: yarn flow
- name: Publish Test Report
if: ${{ always() && matrix.node-version == '14' }}
uses: mikepenz/action-junit-report@v2
uses: mikepenz/action-junit-report@127c778ac944abc0f48a5103964304bab7eb208b
with:
check_name: JUnit Annotations for Node ${{ matrix.node-version }}
report_paths: "**/coverage/junit/**/*.xml"
report_paths: '**/coverage/junit/**/*.xml'

publish:
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/alpha' || github.ref == 'refs/heads/beta'
needs: [tests]
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v3
- name: Use Node.js 14
Expand All @@ -55,4 +58,5 @@ jobs:
run: yarn semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "react-relay-network-modern",
"name": "@tensor-hq/react-relay-network-modern",
"version": "0.0.0-semantically-released",
"private": false,
"description": "Network Layer for React Relay and Express (Batch Queries, AuthToken, Logging, Retry)",
"engines": {
"node": ">=14.21.3"
Expand All @@ -11,9 +12,9 @@
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/relay-tools/react-relay-network-modern.git"
"repository": "[email protected]:tensor-hq/react-relay-network-modern.git",
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"keywords": [
"relay",
Expand Down
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export type BatchMiddlewareOpts = {
batchUrl?: string | Promise<string> | ((requestMap: BatchRequestMap) => string | Promise<string>);
batchTimeout?: number;
maxBatchSize?: number;
maxRequestsPerBatch?: number;
allowMutations?: boolean;
method?: 'POST' | 'GET';
headers?: Headers | Promise<Headers> | ((req: RelayRequestBatch) => Headers | Promise<Headers>);
Expand Down
52 changes: 52 additions & 0 deletions src/middlewares/__tests__/batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,56 @@ describe('middlewares/batch', () => {
);
});
});

describe('option `maxRequestsPerBatch`', () => {
beforeEach(() => {
fetchMock.restore();
});

it('should split batch requests based on max requests limit', async () => {
// Set up mocks for single and batch requests
fetchMock.mock({
matcher: '/graphql',
response: {
status: 200,
body: { data: {} },
},
method: 'POST',
});

fetchMock.mock({
matcher: '/graphql/batch',
response: {
status: 200,
body: [{ data: {} }, { data: {} }],
},
method: 'POST',
});

// Create a network layer with maxRequestsPerBatch set to 2
const rnl = new RelayNetworkLayer([batchMiddleware({ maxRequestsPerBatch: 2 })]);

// Create 5 mock requests
const req1 = mockReq(1);
const req2 = mockReq(2);
const req3 = mockReq(3);
const req4 = mockReq(4);
const req5 = mockReq(5);

// Execute all requests simultaneously
await Promise.all([
req1.execute(rnl),
req2.execute(rnl),
req3.execute(rnl),
req4.execute(rnl),
req5.execute(rnl),
]);

// Check if the requests were properly split into batches
const batchReqs = fetchMock.calls('/graphql/batch');
const singleReqs = fetchMock.calls('/graphql');
expect(batchReqs).toHaveLength(2);
expect(singleReqs).toHaveLength(1);
});
});
});
10 changes: 10 additions & 0 deletions src/middlewares/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type BatchMiddlewareOpts = {|
| ((requestList: RequestWrapper[]) => string | Promise<string>),
batchTimeout?: number,
maxBatchSize?: number,
maxRequestsPerBatch?: number,
allowMutations?: boolean,
method?: 'POST' | 'GET',
headers?: Headers | Promise<Headers> | ((req: RelayRequestBatch) => Headers | Promise<Headers>),
Expand Down Expand Up @@ -57,6 +58,7 @@ export default function batchMiddleware(options?: BatchMiddlewareOpts): Middlewa
const allowMutations = opts.allowMutations || false;
const batchUrl = opts.batchUrl || '/graphql/batch';
const maxBatchSize = opts.maxBatchSize || DEFAULT_BATCH_SIZE;
const maxRequestsPerBatch = opts.maxRequestsPerBatch || 0; // 0 is the same as no limit
const singleton = {};

const fetchOpts = {};
Expand Down Expand Up @@ -94,6 +96,7 @@ export default function batchMiddleware(options?: BatchMiddlewareOpts): Middlewa
batchUrl,
singleton,
maxBatchSize,
maxRequestsPerBatch,
fetchOpts,
});
};
Expand All @@ -111,6 +114,13 @@ function passThroughBatch(req: RelayRequest, next, opts) {
singleton.batcher = prepareNewBatcher(next, opts);
}

if (
opts.maxRequestsPerBatch &&
singleton.batcher.requestList.length + 1 > opts.maxRequestsPerBatch
) {
singleton.batcher = prepareNewBatcher(next, opts);
}

if (singleton.batcher.bodySize + bodyLength + 1 > opts.maxBatchSize) {
singleton.batcher = prepareNewBatcher(next, opts);
}
Expand Down