Skip to content

Commit a69fea0

Browse files
Alexandre Kirszenbergfacebook-github-bot
authored andcommitted
Add onUpdateStart and onUpdateError
Reviewed By: mjesun Differential Revision: D10527995 fbshipit-source-id: fc0209282e535101eae5257774d33f57de8d71d3
1 parent f388ccd commit a69fea0

File tree

4 files changed

+189
-2
lines changed

4 files changed

+189
-2
lines changed

packages/metro/src/HmrServer/__tests__/HmrServer-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ describe('HmrServer', () => {
210210
},
211211
]);
212212
});
213+
213214
it('should return the correctly formatted HMR message after a file change', async () => {
214215
const sendMessage = jest.fn();
215216

packages/metro/src/lib/bundle-modules/DeltaClient/__tests__/createDeltaClient-test.js

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,89 @@ post(\\"rev0\\");"
347347
});
348348
});
349349

350+
it('sends an update start message to clients', async () => {
351+
const clientMock = {
352+
postMessage: jest.fn(),
353+
};
354+
global.clients = {
355+
get: jest.fn().mockResolvedValue(clientMock),
356+
};
357+
const deltaClient = createDeltaClient();
358+
359+
deltaClient({
360+
clientId: 'client0',
361+
request: new Request('https://localhost/bundles/cool.bundle'),
362+
});
363+
364+
await flushPromises();
365+
366+
emit('open');
367+
emit('update-start');
368+
emit('update', {
369+
revisionId: 'rev0',
370+
modules: [],
371+
deleted: [],
372+
sourceMappingURLs: [],
373+
sourceURLs: [],
374+
});
375+
emit('update-done');
376+
377+
emit('update-start');
378+
379+
expect(global.clients.get).toHaveBeenCalledWith('client0');
380+
381+
await flushPromises();
382+
383+
expect(clientMock.postMessage).toHaveBeenCalledWith({
384+
type: 'METRO_UPDATE_START',
385+
});
386+
});
387+
388+
it('sends an update error message to clients', async () => {
389+
const clientMock = {
390+
postMessage: jest.fn(),
391+
};
392+
global.clients = {
393+
get: jest.fn().mockResolvedValue(clientMock),
394+
};
395+
const deltaClient = createDeltaClient();
396+
397+
deltaClient({
398+
clientId: 'client0',
399+
request: new Request('https://localhost/bundles/cool.bundle'),
400+
});
401+
402+
await flushPromises();
403+
404+
emit('open');
405+
emit('update-start');
406+
emit('update', {
407+
revisionId: 'rev0',
408+
modules: [],
409+
deleted: [],
410+
sourceMappingURLs: [],
411+
sourceURLs: [],
412+
});
413+
emit('update-done');
414+
415+
const error = {
416+
type: 'CompleteFailureError',
417+
message: 'Everything went south',
418+
errors: [],
419+
};
420+
emit('update-start');
421+
emit('error', error);
422+
423+
expect(global.clients.get).toHaveBeenCalledWith('client0');
424+
425+
await flushPromises();
426+
427+
expect(clientMock.postMessage).toHaveBeenCalledWith({
428+
type: 'METRO_UPDATE_ERROR',
429+
error,
430+
});
431+
});
432+
350433
it('patches the cached bundle on later update', async () => {
351434
const deltaClient = createDeltaClient();
352435

@@ -424,6 +507,66 @@ post(\\"rev0\\");"
424507
expect(onUpdate).toHaveBeenCalledWith('client0', update);
425508
});
426509

510+
it('accepts a custom onUpdateStart function', async () => {
511+
const onUpdateStart = jest.fn();
512+
const deltaClient = createDeltaClient({onUpdateStart});
513+
514+
deltaClient({
515+
clientId: 'client0',
516+
request: new Request('https://localhost/bundles/cool.bundle'),
517+
});
518+
519+
await flushPromises();
520+
521+
emit('open');
522+
emit('update-start');
523+
emit('update', {
524+
revisionId: 'rev0',
525+
modules: [],
526+
deleted: [],
527+
sourceMappingURLs: [],
528+
sourceURLs: [],
529+
});
530+
emit('update-done');
531+
532+
emit('update-start');
533+
534+
expect(onUpdateStart).toHaveBeenCalledWith('client0');
535+
});
536+
537+
it('accepts a custom onUpdateError function', async () => {
538+
const onUpdateError = jest.fn();
539+
const deltaClient = createDeltaClient({onUpdateError});
540+
541+
deltaClient({
542+
clientId: 'client0',
543+
request: new Request('https://localhost/bundles/cool.bundle'),
544+
});
545+
546+
await flushPromises();
547+
548+
emit('open');
549+
emit('update-start');
550+
emit('update', {
551+
revisionId: 'rev0',
552+
modules: [],
553+
deleted: [],
554+
sourceMappingURLs: [],
555+
sourceURLs: [],
556+
});
557+
emit('update-done');
558+
559+
const error = {
560+
type: 'CompleteFailureError',
561+
message: 'Everything went south',
562+
errors: [],
563+
};
564+
emit('update-start');
565+
emit('error', error);
566+
567+
expect(onUpdateError).toHaveBeenCalledWith('client0', error);
568+
});
569+
427570
it('only connects once for a given revisionId', async () => {
428571
const onUpdate = jest.fn();
429572
const deltaClient = createDeltaClient({onUpdate});

packages/metro/src/lib/bundle-modules/DeltaClient/createDeltaClient.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ const bundleToString = require('./bundleToString');
1919
const patchBundle = require('./patchBundle');
2020
const stringToBundle = require('./stringToBundle');
2121

22-
import type {Bundle, DeltaBundle, HmrUpdate} from '../types.flow';
22+
import type {
23+
Bundle,
24+
DeltaBundle,
25+
HmrUpdate,
26+
FormattedError,
27+
} from '../types.flow';
2328

2429
declare var __DEV__: boolean;
2530

@@ -36,7 +41,9 @@ export type GetHmrServerUrl = (
3641
export type DeltaClientOptions = {|
3742
+getDeltaBundle?: GetDeltaBundle,
3843
+getHmrServerUrl?: GetHmrServerUrl,
44+
+onUpdateStart?: (clientId: string) => void,
3945
+onUpdate?: (clientId: string, update: HmrUpdate) => void,
46+
+onUpdateError?: (clientId: string, error: FormattedError) => void,
4047
|};
4148

4249
export type DeltaClient = (event: FetchEvent) => Promise<Response>;
@@ -82,10 +89,33 @@ function defaultOnUpdate(clientId: string, update: HmrUpdate) {
8289
});
8390
}
8491

92+
function defaultOnUpdateStart(clientId: string) {
93+
clients.get(clientId).then(client => {
94+
if (client != null) {
95+
client.postMessage({
96+
type: 'METRO_UPDATE_START',
97+
});
98+
}
99+
});
100+
}
101+
102+
function defaultOnUpdateError(clientId: string, error: FormattedError) {
103+
clients.get(clientId).then(client => {
104+
if (client != null) {
105+
client.postMessage({
106+
type: 'METRO_UPDATE_ERROR',
107+
error,
108+
});
109+
}
110+
});
111+
}
112+
85113
function createDeltaClient({
86114
getHmrServerUrl = defaultGetHmrServerUrl,
87115
getDeltaBundle = defaultGetDeltaBundle,
116+
onUpdateStart = defaultOnUpdateStart,
88117
onUpdate = defaultOnUpdate,
118+
onUpdateError = defaultOnUpdateError,
89119
}: DeltaClientOptions = {}): DeltaClient {
90120
const clientsByRevId: Map<string, Set<string>> = new Map();
91121

@@ -140,6 +170,11 @@ function createDeltaClient({
140170
reject(error);
141171
return;
142172
}
173+
clientIds.forEach(clientId => onUpdateError(clientId, error));
174+
});
175+
176+
wsClient.on('update-start', () => {
177+
clientIds.forEach(clientId => onUpdateStart(clientId));
143178
});
144179

145180
wsClient.on('update', update => {

packages/metro/src/lib/bundle-modules/registerServiceWorker.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,17 @@ function registerServiceWorker(swUrl: string) {
3939
sw.addEventListener('message', event => {
4040
const messageEvent: ServiceWorkerMessageEvent = (event: $FlowIssue);
4141
switch (messageEvent.data.type) {
42+
case 'METRO_UPDATE_START': {
43+
console.info('Metro update started.');
44+
break;
45+
}
4246
case 'METRO_UPDATE': {
4347
console.info('Injecting metro update:', messageEvent.data.body);
44-
injectUpdate(messageEvent.data.update);
48+
injectUpdate(messageEvent.data.body);
49+
break;
50+
}
51+
case 'METRO_UPDATE_ERROR': {
52+
console.error('Metro update error: ', messageEvent.data.error);
4553
break;
4654
}
4755
}

0 commit comments

Comments
 (0)