@interface-technologies/check-for-js-bundle-update-saga 4.6.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,50 +1,50 @@
1
- import moment from 'moment-timezone';
2
- import { SagaIterator } from 'redux-saga';
3
- /** @internal */
4
- export declare function getIndexHtml(): Promise<string | undefined>;
5
- /** @internal */
6
- export declare function reload(): void;
7
- export interface CheckForJsBundleUpdateSagaOptions {
8
- delayDuration?: moment.Duration;
9
- onError(e: unknown): void;
10
- bundleSrcPattern?: RegExp;
11
- }
12
- /**
13
- * Periodically fetches `/` (`index.html`) to check if a new JavaScript bundle has been
14
- * released.
15
- *
16
- * If the bundle has been updated, the user is prompted to refresh the page.
17
- * After 3 alerts are shown, the page is forcibly refreshed.
18
- *
19
- * Don't enable this in development!
20
- *
21
- * Your `index.html` must contain a script tag like:
22
- *
23
- * ```html
24
- * <script src="app.23e590a23b49.js"></script>
25
- * ```
26
- *
27
- * or
28
- *
29
- * ```html
30
- * <script src="dist/app.js?v=Gq0JHtehvL9fMpV"></script>
31
- * ```
32
- *
33
- * `checkForJsBundleUpdateSaga` will compare the `src` attribute of the script tag.
34
- *
35
- * An example of using `checkForJsBundleUpdateSaga` from your TypeScript code:
36
- *
37
- * ```
38
- * export function* myCheckForJsBundleUpdateSaga(): SagaIterator<void> {
39
- * if (process.env.NODE_ENV === 'development') return
40
- *
41
- * function onError(e: unknown): void {
42
- * console.error(e)
43
- * Bugsnag.notify(e)
44
- * }
45
- *
46
- * yield call(checkForJsBundleUpdateSaga, { onError })
47
- * }
48
- * ```
49
- */
50
- export declare function checkForJsBundleUpdateSaga({ delayDuration, onError, bundleSrcPattern, }: CheckForJsBundleUpdateSagaOptions): SagaIterator<void>;
1
+ import moment from 'moment-timezone';
2
+ import { SagaIterator } from 'redux-saga';
3
+ /** @internal */
4
+ export declare function getIndexHtml(): Promise<string | undefined>;
5
+ /** @internal */
6
+ export declare function reload(): void;
7
+ export interface CheckForJsBundleUpdateSagaOptions {
8
+ delayDuration?: moment.Duration;
9
+ onError(e: unknown): void;
10
+ bundleSrcPattern?: RegExp;
11
+ }
12
+ /**
13
+ * Periodically fetches `/` (`index.html`) to check if a new JavaScript bundle has been
14
+ * released.
15
+ *
16
+ * If the bundle has been updated, the user is prompted to refresh the page.
17
+ * After 3 alerts are shown, the page is forcibly refreshed.
18
+ *
19
+ * Don't enable this in development!
20
+ *
21
+ * Your `index.html` must contain a script tag like:
22
+ *
23
+ * ```html
24
+ * <script src="app.23e590a23b49.js"></script>
25
+ * ```
26
+ *
27
+ * or
28
+ *
29
+ * ```html
30
+ * <script src="dist/app.js?v=Gq0JHtehvL9fMpV"></script>
31
+ * ```
32
+ *
33
+ * `checkForJsBundleUpdateSaga` will compare the `src` attribute of the script tag.
34
+ *
35
+ * An example of using `checkForJsBundleUpdateSaga` from your TypeScript code:
36
+ *
37
+ * ```
38
+ * export function* myCheckForJsBundleUpdateSaga(): SagaIterator<void> {
39
+ * if (process.env.NODE_ENV === 'development') return
40
+ *
41
+ * function onError(e: unknown): void {
42
+ * console.error(e)
43
+ * Bugsnag.notify(e)
44
+ * }
45
+ *
46
+ * yield call(checkForJsBundleUpdateSaga, { onError })
47
+ * }
48
+ * ```
49
+ */
50
+ export declare function checkForJsBundleUpdateSaga({ delayDuration, onError, bundleSrcPattern, }: CheckForJsBundleUpdateSagaOptions): SagaIterator<void>;
@@ -1,117 +1,116 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.checkForJsBundleUpdateSaga = exports.reload = exports.getIndexHtml = void 0;
7
- const jsx_runtime_1 = require("react/jsx-runtime");
8
- const moment_timezone_1 = __importDefault(require("moment-timezone"));
9
- const effects_1 = require("redux-saga/effects");
10
- const iti_react_1 = require("@interface-technologies/iti-react");
11
- const defaultDelayDuration = moment_timezone_1.default.duration(4, 'minutes');
12
- const forceRefreshAfterAlertCount = 3;
13
- /** @internal */
14
- function getIndexHtml() {
15
- return (fetch('/')
16
- .then((response) => {
17
- if (!response.ok)
18
- return undefined;
19
- return response.text();
20
- })
21
- // If fetch throws a TypeError for some weird reason, also return undefined
22
- .catch(() => undefined));
23
- }
24
- exports.getIndexHtml = getIndexHtml;
25
- /** @internal */
26
- function reload() {
27
- window.location.reload();
28
- }
29
- exports.reload = reload;
30
- function getBundleSrcFromDocument(doc, bundleSrcPattern) {
31
- var _a;
32
- const scripts = Array.from(doc.getElementsByTagName('script'));
33
- for (const script of scripts) {
34
- const parts = (_a = script.src) === null || _a === void 0 ? void 0 : _a.split('/');
35
- if (parts.length === 0)
36
- continue;
37
- const src = parts[parts.length - 1];
38
- if (bundleSrcPattern.test(src))
39
- return src;
40
- }
41
- return undefined;
42
- }
43
- /**
44
- * Periodically fetches `/` (`index.html`) to check if a new JavaScript bundle has been
45
- * released.
46
- *
47
- * If the bundle has been updated, the user is prompted to refresh the page.
48
- * After 3 alerts are shown, the page is forcibly refreshed.
49
- *
50
- * Don't enable this in development!
51
- *
52
- * Your `index.html` must contain a script tag like:
53
- *
54
- * ```html
55
- * <script src="app.23e590a23b49.js"></script>
56
- * ```
57
- *
58
- * or
59
- *
60
- * ```html
61
- * <script src="dist/app.js?v=Gq0JHtehvL9fMpV"></script>
62
- * ```
63
- *
64
- * `checkForJsBundleUpdateSaga` will compare the `src` attribute of the script tag.
65
- *
66
- * An example of using `checkForJsBundleUpdateSaga` from your TypeScript code:
67
- *
68
- * ```
69
- * export function* myCheckForJsBundleUpdateSaga(): SagaIterator<void> {
70
- * if (process.env.NODE_ENV === 'development') return
71
- *
72
- * function onError(e: unknown): void {
73
- * console.error(e)
74
- * Bugsnag.notify(e)
75
- * }
76
- *
77
- * yield call(checkForJsBundleUpdateSaga, { onError })
78
- * }
79
- * ```
80
- */
81
- function* checkForJsBundleUpdateSaga({ delayDuration = defaultDelayDuration, onError, bundleSrcPattern = /app\.\S+\.js/, }) {
82
- const bundleSrc = getBundleSrcFromDocument(document, bundleSrcPattern);
83
- if (!bundleSrc) {
84
- onError(new Error('Could not get bundle src from current document.'));
85
- return;
86
- }
87
- yield (0, effects_1.delay)(delayDuration.asMilliseconds());
88
- let alertShownCount = 0;
89
- for (;;) {
90
- try {
91
- const indexHtml = (yield (0, effects_1.call)(getIndexHtml));
92
- if (indexHtml) {
93
- const retrievedDocument = new DOMParser().parseFromString(indexHtml, 'text/html');
94
- const retrievedBundleSrc = getBundleSrcFromDocument(retrievedDocument, bundleSrcPattern);
95
- if (!retrievedBundleSrc) {
96
- onError('Could not get bundle src from retrieved document.');
97
- return;
98
- }
99
- if (bundleSrc !== retrievedBundleSrc) {
100
- const content = ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { children: "Please save your work and refresh the page." }), (0, jsx_runtime_1.jsx)("p", { className: "mb-0", children: "You may encounter errors if you do not refresh the page." })] }));
101
- if (alertShownCount >= forceRefreshAfterAlertCount) {
102
- window.onbeforeunload = null;
103
- yield (0, effects_1.call)(reload);
104
- return;
105
- }
106
- yield (0, effects_1.call)(iti_react_1.alert, content, { title: 'Website Update Available!' });
107
- alertShownCount += 1;
108
- }
109
- }
110
- }
111
- catch (e) {
112
- onError(e);
113
- }
114
- yield (0, effects_1.delay)(delayDuration.asMilliseconds());
115
- }
116
- }
117
- exports.checkForJsBundleUpdateSaga = checkForJsBundleUpdateSaga;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getIndexHtml = getIndexHtml;
7
+ exports.reload = reload;
8
+ exports.checkForJsBundleUpdateSaga = checkForJsBundleUpdateSaga;
9
+ const jsx_runtime_1 = require("react/jsx-runtime");
10
+ const moment_timezone_1 = __importDefault(require("moment-timezone"));
11
+ const effects_1 = require("redux-saga/effects");
12
+ const iti_react_1 = require("@interface-technologies/iti-react");
13
+ const defaultDelayDuration = moment_timezone_1.default.duration(4, 'minutes');
14
+ const forceRefreshAfterAlertCount = 3;
15
+ /** @internal */
16
+ function getIndexHtml() {
17
+ return (fetch('/')
18
+ .then((response) => {
19
+ if (!response.ok)
20
+ return undefined;
21
+ return response.text();
22
+ })
23
+ // If fetch throws a TypeError for some weird reason, also return undefined
24
+ .catch(() => undefined));
25
+ }
26
+ /** @internal */
27
+ function reload() {
28
+ window.location.reload();
29
+ }
30
+ function getBundleSrcFromDocument(doc, bundleSrcPattern) {
31
+ var _a;
32
+ const scripts = Array.from(doc.getElementsByTagName('script'));
33
+ for (const script of scripts) {
34
+ const parts = (_a = script.src) === null || _a === void 0 ? void 0 : _a.split('/');
35
+ if (parts.length === 0)
36
+ continue;
37
+ const src = parts[parts.length - 1];
38
+ if (bundleSrcPattern.test(src))
39
+ return src;
40
+ }
41
+ return undefined;
42
+ }
43
+ /**
44
+ * Periodically fetches `/` (`index.html`) to check if a new JavaScript bundle has been
45
+ * released.
46
+ *
47
+ * If the bundle has been updated, the user is prompted to refresh the page.
48
+ * After 3 alerts are shown, the page is forcibly refreshed.
49
+ *
50
+ * Don't enable this in development!
51
+ *
52
+ * Your `index.html` must contain a script tag like:
53
+ *
54
+ * ```html
55
+ * <script src="app.23e590a23b49.js"></script>
56
+ * ```
57
+ *
58
+ * or
59
+ *
60
+ * ```html
61
+ * <script src="dist/app.js?v=Gq0JHtehvL9fMpV"></script>
62
+ * ```
63
+ *
64
+ * `checkForJsBundleUpdateSaga` will compare the `src` attribute of the script tag.
65
+ *
66
+ * An example of using `checkForJsBundleUpdateSaga` from your TypeScript code:
67
+ *
68
+ * ```
69
+ * export function* myCheckForJsBundleUpdateSaga(): SagaIterator<void> {
70
+ * if (process.env.NODE_ENV === 'development') return
71
+ *
72
+ * function onError(e: unknown): void {
73
+ * console.error(e)
74
+ * Bugsnag.notify(e)
75
+ * }
76
+ *
77
+ * yield call(checkForJsBundleUpdateSaga, { onError })
78
+ * }
79
+ * ```
80
+ */
81
+ function* checkForJsBundleUpdateSaga({ delayDuration = defaultDelayDuration, onError, bundleSrcPattern = /app\.\S+\.js/, }) {
82
+ const bundleSrc = getBundleSrcFromDocument(document, bundleSrcPattern);
83
+ if (!bundleSrc) {
84
+ onError(new Error('Could not get bundle src from current document.'));
85
+ return;
86
+ }
87
+ yield (0, effects_1.delay)(delayDuration.asMilliseconds());
88
+ let alertShownCount = 0;
89
+ for (;;) {
90
+ try {
91
+ const indexHtml = (yield (0, effects_1.call)(getIndexHtml));
92
+ if (indexHtml) {
93
+ const retrievedDocument = new DOMParser().parseFromString(indexHtml, 'text/html');
94
+ const retrievedBundleSrc = getBundleSrcFromDocument(retrievedDocument, bundleSrcPattern);
95
+ if (!retrievedBundleSrc) {
96
+ onError('Could not get bundle src from retrieved document.');
97
+ return;
98
+ }
99
+ if (bundleSrc !== retrievedBundleSrc) {
100
+ const content = ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { children: "Please save your work and refresh the page." }), (0, jsx_runtime_1.jsx)("p", { className: "mb-0", children: "You may encounter errors if you do not refresh the page." })] }));
101
+ if (alertShownCount >= forceRefreshAfterAlertCount) {
102
+ window.onbeforeunload = null;
103
+ yield (0, effects_1.call)(reload);
104
+ return;
105
+ }
106
+ yield (0, effects_1.call)(iti_react_1.alert, content, { title: 'Website Update Available!' });
107
+ alertShownCount += 1;
108
+ }
109
+ }
110
+ }
111
+ catch (e) {
112
+ onError(e);
113
+ }
114
+ yield (0, effects_1.delay)(delayDuration.asMilliseconds());
115
+ }
116
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { checkForJsBundleUpdateSaga } from './checkForJsBundleUpdateSaga';
2
- export type { CheckForJsBundleUpdateSagaOptions } from './checkForJsBundleUpdateSaga';
1
+ export { checkForJsBundleUpdateSaga } from './checkForJsBundleUpdateSaga';
2
+ export type { CheckForJsBundleUpdateSagaOptions } from './checkForJsBundleUpdateSaga';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkForJsBundleUpdateSaga = void 0;
4
- var checkForJsBundleUpdateSaga_1 = require("./checkForJsBundleUpdateSaga");
5
- Object.defineProperty(exports, "checkForJsBundleUpdateSaga", { enumerable: true, get: function () { return checkForJsBundleUpdateSaga_1.checkForJsBundleUpdateSaga; } });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkForJsBundleUpdateSaga = void 0;
4
+ var checkForJsBundleUpdateSaga_1 = require("./checkForJsBundleUpdateSaga");
5
+ Object.defineProperty(exports, "checkForJsBundleUpdateSaga", { enumerable: true, get: function () { return checkForJsBundleUpdateSaga_1.checkForJsBundleUpdateSaga; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interface-technologies/check-for-js-bundle-update-saga",
3
- "version": "4.6.0",
3
+ "version": "5.0.0",
4
4
  "description": "Redux saga for checking if a JavaScript app has been deployed.",
5
5
  "homepage": "https://github.com/srmagura/iti-react",
6
6
  "repository": {
@@ -11,25 +11,23 @@
11
11
  "author": "Interface Technologies, Inc.",
12
12
  "main": "dist/index.js",
13
13
  "types": "dist/index.d.ts",
14
- "typedocMain": "src/index.ts",
15
14
  "files": [
16
15
  "dist"
17
16
  ],
18
17
  "sideEffects": false,
19
18
  "prettier": "@interface-technologies/prettier-config",
20
19
  "dependencies": {
21
- "@types/react": "^17.0.40",
22
- "moment-timezone": "^0.5.34",
23
- "redux-saga": "^1.1.3"
20
+ "@types/react": "^18.3.4",
21
+ "moment-timezone": "^0.5.45",
22
+ "redux-saga": "^1.3.0"
24
23
  },
25
24
  "devDependencies": {
26
- "@interface-technologies/iti-react": "4.6.0",
27
- "@interface-technologies/tsconfig": "4.6.0",
28
- "@redux-saga/is": "^1.1.2",
29
- "@redux-saga/symbols": "^1.1.2",
30
- "@testing-library/react-hooks": "^7.0.2",
31
- "react": "^17.0.2",
32
- "redux-saga-test-plan": "^4.0.4"
25
+ "@interface-technologies/iti-react": "5.0.0",
26
+ "@interface-technologies/tsconfig": "5.0.0",
27
+ "@redux-saga/is": "^1.1.3",
28
+ "@redux-saga/symbols": "^1.1.3",
29
+ "react": "^18.3.1",
30
+ "redux-saga-test-plan": "^4.0.6"
33
31
  },
34
32
  "peerDependencies": {
35
33
  "@interface-technologies/iti-react": "^4.3.8",