Skip to content

Commit c237d33

Browse files
authored
Transition to new packager (codesandbox#8)
* Transition to new packager * log to raven
1 parent 8360d4c commit c237d33

File tree

7 files changed

+120
-34
lines changed

7 files changed

+120
-34
lines changed

src/app/store/entities/sandboxes/actions.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
// @flow
22
import { push } from 'react-router-redux';
3+
import type { Module, Directory } from 'common/types';
34

45
import { createAPIActions, doRequest } from '../../api/actions';
56
import { normalizeResult } from '../actions';
67
import notificationActions from '../../notifications/actions';
78
import entity from './entity';
8-
import fetchBundle from './bundle-loader';
9-
import type { Module } from './modules/entity';
9+
import fetchBundle from './bundler';
1010
import moduleEntity from './modules/entity';
1111
import moduleActions from './modules/actions';
12-
import type { Directory } from './directories/entity';
1312
import directoryEntity from './directories/entity';
1413
import directoryActions from './directories/actions';
1514
import { singleSandboxSelector } from './selectors';

src/app/store/entities/sandboxes/bundle-loader.js

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default (dependencies: Object) =>
2+
Object.keys(dependencies)
3+
.sort()
4+
.map(name => `${name}@${dependencies[name]}`)
5+
.join('+');
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import dependenciesToQuery from './dependencies-to-query';
2+
3+
it('creates a right query', () => {
4+
const packages = {
5+
react: 'latest',
6+
'react-dom': '15.5.3',
7+
'@angular/core': '14.0.0',
8+
};
9+
10+
expect(dependenciesToQuery(packages)).toEqual(
11+
12+
);
13+
});
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import _debug from 'app/utils/debug';
2+
3+
import callApi from '../../../services/api';
4+
import delay from '../../../services/delay';
5+
6+
import dependenciesToQuery from './dependencies-to-query';
7+
import { singleSandboxSelector } from '../selectors';
8+
import logError from '../../../../utils/error';
9+
10+
const debug = _debug('cs:app:packager');
11+
12+
/**
13+
* Request the packager, if retries > 4 it will throw if something goes wrong
14+
* otherwise it will retry again with an incremented retry
15+
*
16+
* @param {string} query The dependencies to call
17+
*/
18+
async function requestPackager(query: string) {
19+
let retries = 0;
20+
21+
while (true) {
22+
debug(`Trying to call packager for ${retries} time`);
23+
try {
24+
await callApi(
25+
`https://cdn.jsdelivr.net/webpack/v1/${query}/manifest.json`,
26+
);
27+
return;
28+
} catch (e) {
29+
if (retries < 5) {
30+
retries += 1;
31+
} else {
32+
throw e;
33+
}
34+
}
35+
}
36+
}
37+
38+
async function callNewPackager(dependencies: Object) {
39+
// New Packager flow
40+
try {
41+
const dependencyUrl = dependenciesToQuery(dependencies);
42+
43+
await requestPackager(dependencyUrl);
44+
} catch (e) {
45+
logError(e, { level: 'warning', service: 'packager' });
46+
}
47+
}
48+
49+
export default function fetch(actions, id: string) {
50+
return async (dispatch: Function, getState: Function) => {
51+
const sandbox = singleSandboxSelector(getState(), { id });
52+
if (sandbox) {
53+
callNewPackager(sandbox.npmDependencies);
54+
}
55+
56+
dispatch({ type: actions.REQUEST, initial: true, id });
57+
const firstResult = await callApi('/bundler/bundle', null, {
58+
method: 'POST',
59+
body: { id },
60+
});
61+
dispatch({ type: actions.SUCCESS, result: firstResult });
62+
63+
if (firstResult.manifest) {
64+
return firstResult;
65+
}
66+
67+
while (true) {
68+
await delay(1000);
69+
const result = await callApi(`/bundler/bundle/${firstResult.hash}`);
70+
71+
if (result.manifest) {
72+
return result;
73+
}
74+
}
75+
};
76+
}

src/app/store/services/api.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { camelizeKeys, decamelizeKeys } from 'humps';
33
import axios from 'axios';
44

5-
import getJwt from '../user/utils/jwt';
65
import { optionsToParameterizedUrl } from '../../utils/url-generator';
76

87
const API_ROOT = '/api/v1/';
@@ -14,6 +13,14 @@ export type BodyType = {
1413
jwt: ?string,
1514
};
1615

16+
function getUrl(endpoint: string) {
17+
if (endpoint.startsWith('http')) {
18+
return endpoint;
19+
}
20+
21+
return endpoint.split('')[0] === '/' ? endpoint : `${API_ROOT}${endpoint}`;
22+
}
23+
1724
/**
1825
* Sends a request to the API and returns a promise with camelized response
1926
*/
@@ -25,9 +32,7 @@ export default (async function callApi(
2532
if (!endpoint) throw new Error('No endpoint is given');
2633

2734
// If it is an absolute url.
28-
const url = endpoint.split('')[0] === '/'
29-
? endpoint
30-
: `${API_ROOT}${endpoint}`;
35+
const url = getUrl(endpoint);
3136

3237
const options = { url, method };
3338

src/app/utils/debug.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
const getDebugger = () => {
2-
if (process.env.NODE_ENV !== 'development') return () => () => {};
2+
if (process.env.NODE_ENV === 'production') {
3+
// Return a debugger that will log to sentry
4+
return (key: string) => (message: string) => {
5+
if (typeof window.Raven === 'object') {
6+
try {
7+
Raven.captureMessage(message, {
8+
level: 'info',
9+
logger: key,
10+
});
11+
} catch (e) {
12+
console.error(e);
13+
}
14+
}
15+
};
16+
}
317

418
const debug = require('debug'); // eslint-disable-line global-require
519
debug.enable('cs:*');

0 commit comments

Comments
 (0)