@atlaspack/domain-sharding 2.14.2-typescript-6de04fbae.0 → 2.14.2-typescript-80839fbd5.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.
- package/lib/index.js +22 -39
- package/package.json +5 -8
- package/src/{index.js → index.ts} +22 -45
- package/test/{index.test.js → index.test.ts} +3 -3
- package/tsconfig.json +4 -0
- package/lib/index.d.ts +0 -44
package/lib/index.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.applyShardToDomain = applyShardToDomain;
|
|
7
|
+
exports.domainShardingKey = void 0;
|
|
8
|
+
exports.getDomainShardIndex = getDomainShardIndex;
|
|
9
|
+
exports.shardUrl = shardUrl;
|
|
10
|
+
exports.shardUrlUnchecked = shardUrlUnchecked;
|
|
11
|
+
const globalKeyName = '__ATLASPACK_ENABLE_DOMAIN_SHARDS';
|
|
4
12
|
|
|
5
13
|
/**
|
|
6
14
|
* Extracts the file name from a static asset path.
|
|
7
15
|
* Will throw if the path doesn't have segments or ends in a trailing slash.
|
|
8
|
-
*
|
|
9
|
-
* @param {string} pathname
|
|
10
|
-
* @returns {string}
|
|
11
16
|
*/
|
|
12
17
|
function getFilenameFromUrlPath(pathname) {
|
|
13
|
-
|
|
18
|
+
const lastSlashIdx = pathname.lastIndexOf('/');
|
|
14
19
|
if (lastSlashIdx === -1 || lastSlashIdx === pathname.length - 1) {
|
|
15
20
|
throw new Error(`Expected an absolute URL with a file name, unable to apply sharding.`);
|
|
16
21
|
}
|
|
@@ -21,17 +26,13 @@ function getFilenameFromUrlPath(pathname) {
|
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Generates a bounded numeric hash in [0, maxShards)
|
|
24
|
-
*
|
|
25
|
-
* @param {string} str
|
|
26
|
-
* @param {number} maxShards
|
|
27
|
-
* @returns {number}
|
|
28
29
|
*/
|
|
29
30
|
function getDomainShardIndex(str, maxShards) {
|
|
30
31
|
// As we include the base domain as a shard option then we add 1 to maxShards
|
|
31
32
|
// to account for that.
|
|
32
|
-
|
|
33
|
+
const totalShards = maxShards + 1;
|
|
33
34
|
let shard = str.split('').reduce((a, b) => {
|
|
34
|
-
|
|
35
|
+
const n = (a << totalShards) - a + b.charCodeAt(0);
|
|
35
36
|
|
|
36
37
|
// The value returned by << is 64 bit, the & operator coerces to 32,
|
|
37
38
|
// prevents overflow as we iterate.
|
|
@@ -45,31 +46,28 @@ function getDomainShardIndex(str, maxShards) {
|
|
|
45
46
|
}
|
|
46
47
|
return shard;
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
+
const trailingShardRegex = /-\d+$/;
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
|
-
*
|
|
52
|
+
* Removes trailing shard number from subdomain
|
|
52
53
|
*/
|
|
53
54
|
function removeTrailingShard(subdomain) {
|
|
54
55
|
if (!trailingShardRegex.test(subdomain)) {
|
|
55
56
|
return subdomain;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
+
const shardIdx = subdomain.lastIndexOf('-');
|
|
58
59
|
return subdomain.slice(0, shardIdx);
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/**
|
|
62
63
|
* Given a shard number, inserts that shard in the expected pattern within the
|
|
63
64
|
* domain
|
|
64
|
-
*
|
|
65
|
-
* @param {string} domain
|
|
66
|
-
* @param {number} shard
|
|
67
65
|
*/
|
|
68
66
|
function applyShardToDomain(domain, shard) {
|
|
69
|
-
|
|
67
|
+
const i = domain.indexOf('.');
|
|
70
68
|
// If the shard is 0, then just use the base domain.
|
|
71
69
|
// If the shard is > 0, then remove 1 as the shards domains index from 0
|
|
72
|
-
|
|
70
|
+
const shardSuffix = shard === 0 ? '' : `-${shard - 1}`;
|
|
73
71
|
|
|
74
72
|
// Domains like localhost have no . separators
|
|
75
73
|
if (i === -1) {
|
|
@@ -78,7 +76,7 @@ function applyShardToDomain(domain, shard) {
|
|
|
78
76
|
|
|
79
77
|
// If this domain already has a shard number in it, strip it
|
|
80
78
|
// out before adding the new one
|
|
81
|
-
|
|
79
|
+
const firstSubdomain = removeTrailingShard(domain.slice(0, i));
|
|
82
80
|
return `${firstSubdomain}${shardSuffix}${domain.slice(i)}`;
|
|
83
81
|
}
|
|
84
82
|
|
|
@@ -89,16 +87,11 @@ function applyShardToDomain(domain, shard) {
|
|
|
89
87
|
*
|
|
90
88
|
* Unlike `shardUrl`, this function will always apply sharding, without any
|
|
91
89
|
* conditional logic.
|
|
92
|
-
*
|
|
93
|
-
* @param {string} url
|
|
94
|
-
* @param {number} maxShards
|
|
95
|
-
* @returns {string}
|
|
96
90
|
*/
|
|
97
|
-
|
|
98
91
|
function shardUrlUnchecked(url, maxShards) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
const parsedUrl = new URL(url);
|
|
93
|
+
const fileName = getFilenameFromUrlPath(parsedUrl.pathname);
|
|
94
|
+
const shardNumber = getDomainShardIndex(fileName, maxShards);
|
|
102
95
|
parsedUrl.hostname = applyShardToDomain(parsedUrl.hostname, shardNumber);
|
|
103
96
|
return parsedUrl.toString();
|
|
104
97
|
}
|
|
@@ -110,10 +103,6 @@ function shardUrlUnchecked(url, maxShards) {
|
|
|
110
103
|
*
|
|
111
104
|
* This function only applies the sharding if the
|
|
112
105
|
* __ATLASPACK_ENABLE_DOMAIN_SHARDS global variable has been set to true
|
|
113
|
-
*
|
|
114
|
-
* @param {string} url
|
|
115
|
-
* @param {number} maxShards
|
|
116
|
-
* @returns {string}
|
|
117
106
|
*/
|
|
118
107
|
function shardUrl(url, maxShards) {
|
|
119
108
|
// Global variable is set by SSR servers when HTTP1.1 traffic is detected
|
|
@@ -122,10 +111,4 @@ function shardUrl(url, maxShards) {
|
|
|
122
111
|
}
|
|
123
112
|
return shardUrlUnchecked(url, maxShards);
|
|
124
113
|
}
|
|
125
|
-
|
|
126
|
-
// TODO: convert this file to ESM once HMR issues are resolved
|
|
127
|
-
exports.shardUrl = shardUrl;
|
|
128
|
-
exports.shardUrlUnchecked = shardUrlUnchecked;
|
|
129
|
-
exports.getDomainShardIndex = getDomainShardIndex;
|
|
130
|
-
exports.applyShardToDomain = applyShardToDomain;
|
|
131
|
-
exports.domainShardingKey = globalKeyName;
|
|
114
|
+
const domainShardingKey = exports.domainShardingKey = globalKeyName;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/domain-sharding",
|
|
3
|
-
"version": "2.14.2-typescript-
|
|
3
|
+
"version": "2.14.2-typescript-80839fbd5.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
|
-
"source": "src/index.
|
|
5
|
+
"source": "src/index.ts",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
|
-
"types": "
|
|
7
|
+
"types": "src/index.ts",
|
|
8
8
|
"publishConfig": {
|
|
9
9
|
"access": "public"
|
|
10
10
|
},
|
|
@@ -13,14 +13,11 @@
|
|
|
13
13
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"
|
|
16
|
+
"check-ts": "tsc --noEmit"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">= 16.0.0"
|
|
20
20
|
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"typescript": "^4.4.3"
|
|
23
|
-
},
|
|
24
21
|
"type": "commonjs",
|
|
25
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "80839fbd5c6d6668c2622849856a4b25601354a8"
|
|
26
23
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
const globalKeyName = '__ATLASPACK_ENABLE_DOMAIN_SHARDS';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Extracts the file name from a static asset path.
|
|
5
5
|
* Will throw if the path doesn't have segments or ends in a trailing slash.
|
|
6
|
-
*
|
|
7
|
-
* @param {string} pathname
|
|
8
|
-
* @returns {string}
|
|
9
6
|
*/
|
|
10
|
-
function getFilenameFromUrlPath(pathname) {
|
|
11
|
-
|
|
7
|
+
function getFilenameFromUrlPath(pathname: string): string {
|
|
8
|
+
const lastSlashIdx = pathname.lastIndexOf('/');
|
|
12
9
|
|
|
13
10
|
if (lastSlashIdx === -1 || lastSlashIdx === pathname.length - 1) {
|
|
14
11
|
throw new Error(
|
|
@@ -22,17 +19,13 @@ function getFilenameFromUrlPath(pathname) {
|
|
|
22
19
|
|
|
23
20
|
/**
|
|
24
21
|
* Generates a bounded numeric hash in [0, maxShards)
|
|
25
|
-
*
|
|
26
|
-
* @param {string} str
|
|
27
|
-
* @param {number} maxShards
|
|
28
|
-
* @returns {number}
|
|
29
22
|
*/
|
|
30
|
-
function getDomainShardIndex(str, maxShards) {
|
|
23
|
+
function getDomainShardIndex(str: string, maxShards: number): number {
|
|
31
24
|
// As we include the base domain as a shard option then we add 1 to maxShards
|
|
32
25
|
// to account for that.
|
|
33
|
-
|
|
26
|
+
const totalShards = maxShards + 1;
|
|
34
27
|
let shard = str.split('').reduce((a, b) => {
|
|
35
|
-
|
|
28
|
+
const n = (a << totalShards) - a + b.charCodeAt(0);
|
|
36
29
|
|
|
37
30
|
// The value returned by << is 64 bit, the & operator coerces to 32,
|
|
38
31
|
// prevents overflow as we iterate.
|
|
@@ -49,32 +42,29 @@ function getDomainShardIndex(str, maxShards) {
|
|
|
49
42
|
return shard;
|
|
50
43
|
}
|
|
51
44
|
|
|
52
|
-
|
|
45
|
+
const trailingShardRegex = /-\d+$/;
|
|
53
46
|
|
|
54
47
|
/**
|
|
55
|
-
*
|
|
48
|
+
* Removes trailing shard number from subdomain
|
|
56
49
|
*/
|
|
57
|
-
function removeTrailingShard(subdomain) {
|
|
50
|
+
function removeTrailingShard(subdomain: string): string {
|
|
58
51
|
if (!trailingShardRegex.test(subdomain)) {
|
|
59
52
|
return subdomain;
|
|
60
53
|
}
|
|
61
54
|
|
|
62
|
-
|
|
55
|
+
const shardIdx = subdomain.lastIndexOf('-');
|
|
63
56
|
return subdomain.slice(0, shardIdx);
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
/**
|
|
67
60
|
* Given a shard number, inserts that shard in the expected pattern within the
|
|
68
61
|
* domain
|
|
69
|
-
*
|
|
70
|
-
* @param {string} domain
|
|
71
|
-
* @param {number} shard
|
|
72
62
|
*/
|
|
73
|
-
function applyShardToDomain(domain, shard) {
|
|
74
|
-
|
|
63
|
+
function applyShardToDomain(domain: string, shard: number): string {
|
|
64
|
+
const i = domain.indexOf('.');
|
|
75
65
|
// If the shard is 0, then just use the base domain.
|
|
76
66
|
// If the shard is > 0, then remove 1 as the shards domains index from 0
|
|
77
|
-
|
|
67
|
+
const shardSuffix = shard === 0 ? '' : `-${shard - 1}`;
|
|
78
68
|
|
|
79
69
|
// Domains like localhost have no . separators
|
|
80
70
|
if (i === -1) {
|
|
@@ -83,7 +73,7 @@ function applyShardToDomain(domain, shard) {
|
|
|
83
73
|
|
|
84
74
|
// If this domain already has a shard number in it, strip it
|
|
85
75
|
// out before adding the new one
|
|
86
|
-
|
|
76
|
+
const firstSubdomain = removeTrailingShard(domain.slice(0, i));
|
|
87
77
|
|
|
88
78
|
return `${firstSubdomain}${shardSuffix}${domain.slice(i)}`;
|
|
89
79
|
}
|
|
@@ -95,17 +85,12 @@ function applyShardToDomain(domain, shard) {
|
|
|
95
85
|
*
|
|
96
86
|
* Unlike `shardUrl`, this function will always apply sharding, without any
|
|
97
87
|
* conditional logic.
|
|
98
|
-
*
|
|
99
|
-
* @param {string} url
|
|
100
|
-
* @param {number} maxShards
|
|
101
|
-
* @returns {string}
|
|
102
88
|
*/
|
|
89
|
+
function shardUrlUnchecked(url: string, maxShards: number): string {
|
|
90
|
+
const parsedUrl = new URL(url);
|
|
103
91
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
let fileName = getFilenameFromUrlPath(parsedUrl.pathname);
|
|
108
|
-
let shardNumber = getDomainShardIndex(fileName, maxShards);
|
|
92
|
+
const fileName = getFilenameFromUrlPath(parsedUrl.pathname);
|
|
93
|
+
const shardNumber = getDomainShardIndex(fileName, maxShards);
|
|
109
94
|
|
|
110
95
|
parsedUrl.hostname = applyShardToDomain(parsedUrl.hostname, shardNumber);
|
|
111
96
|
|
|
@@ -119,23 +104,15 @@ function shardUrlUnchecked(url, maxShards) {
|
|
|
119
104
|
*
|
|
120
105
|
* This function only applies the sharding if the
|
|
121
106
|
* __ATLASPACK_ENABLE_DOMAIN_SHARDS global variable has been set to true
|
|
122
|
-
*
|
|
123
|
-
* @param {string} url
|
|
124
|
-
* @param {number} maxShards
|
|
125
|
-
* @returns {string}
|
|
126
107
|
*/
|
|
127
|
-
function shardUrl(url, maxShards) {
|
|
108
|
+
function shardUrl(url: string, maxShards: number): string {
|
|
128
109
|
// Global variable is set by SSR servers when HTTP1.1 traffic is detected
|
|
129
|
-
if (!globalThis[globalKeyName]) {
|
|
110
|
+
if (!(globalThis as any)[globalKeyName]) {
|
|
130
111
|
return url;
|
|
131
112
|
}
|
|
132
113
|
|
|
133
114
|
return shardUrlUnchecked(url, maxShards);
|
|
134
115
|
}
|
|
135
116
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
exports.shardUrlUnchecked = shardUrlUnchecked;
|
|
139
|
-
exports.getDomainShardIndex = getDomainShardIndex;
|
|
140
|
-
exports.applyShardToDomain = applyShardToDomain;
|
|
141
|
-
exports.domainShardingKey = globalKeyName;
|
|
117
|
+
export {shardUrl, shardUrlUnchecked, getDomainShardIndex, applyShardToDomain};
|
|
118
|
+
export const domainShardingKey = globalKeyName;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import assert from 'assert';
|
|
3
2
|
import {
|
|
4
3
|
shardUrlUnchecked,
|
|
5
4
|
shardUrl,
|
|
6
5
|
domainShardingKey,
|
|
7
6
|
applyShardToDomain,
|
|
8
|
-
} from '../src/index.
|
|
7
|
+
} from '../src/index.ts';
|
|
9
8
|
|
|
10
9
|
describe('domain sharding helpers', () => {
|
|
11
10
|
beforeEach(() => {
|
|
12
|
-
//
|
|
11
|
+
// @ts-expect-error - Element implicitly has an 'any' type because expression of type '"__ATLASPACK_ENABLE_DOMAIN_SHARDS"' can't be used to index type 'typeof globalThis'
|
|
13
12
|
delete globalThis[domainShardingKey];
|
|
14
13
|
});
|
|
15
14
|
|
|
@@ -110,6 +109,7 @@ describe('domain sharding helpers', () => {
|
|
|
110
109
|
|
|
111
110
|
describe('shardUrl', () => {
|
|
112
111
|
it('should add a shard if the window property is set', () => {
|
|
112
|
+
// @ts-expect-error - Element implicitly has an 'any' type because expression of type '"__ATLASPACK_ENABLE_DOMAIN_SHARDS"' can't be used to index type 'typeof globalThis'
|
|
113
113
|
globalThis[domainShardingKey] = true;
|
|
114
114
|
const testBundle =
|
|
115
115
|
'https://bundle-shard.assets.example.com/assets/test-bundle.123abc.js';
|
package/tsconfig.json
ADDED
package/lib/index.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Takes an absolute URL and applies a shard to the top level subdomain.
|
|
3
|
-
* The shard number is based on a hash of the file name, which is
|
|
4
|
-
* the content after the last / in the URL.
|
|
5
|
-
*
|
|
6
|
-
* This function only applies the sharding if the
|
|
7
|
-
* __ATLASPACK_ENABLE_DOMAIN_SHARDS global variable has been set to true
|
|
8
|
-
*
|
|
9
|
-
* @param {string} url
|
|
10
|
-
* @param {number} maxShards
|
|
11
|
-
* @returns {string}
|
|
12
|
-
*/
|
|
13
|
-
export function shardUrl(url: string, maxShards: number): string;
|
|
14
|
-
/**
|
|
15
|
-
* Takes an absolute URL and applies a shard to the top level subdomain.
|
|
16
|
-
* The shard number is based on a hash of the file name, which is
|
|
17
|
-
* the content after the last / in the URL.
|
|
18
|
-
*
|
|
19
|
-
* Unlike `shardUrl`, this function will always apply sharding, without any
|
|
20
|
-
* conditional logic.
|
|
21
|
-
*
|
|
22
|
-
* @param {string} url
|
|
23
|
-
* @param {number} maxShards
|
|
24
|
-
* @returns {string}
|
|
25
|
-
*/
|
|
26
|
-
export function shardUrlUnchecked(url: string, maxShards: number): string;
|
|
27
|
-
/**
|
|
28
|
-
* Generates a bounded numeric hash in [0, maxShards)
|
|
29
|
-
*
|
|
30
|
-
* @param {string} str
|
|
31
|
-
* @param {number} maxShards
|
|
32
|
-
* @returns {number}
|
|
33
|
-
*/
|
|
34
|
-
export function getDomainShardIndex(str: string, maxShards: number): number;
|
|
35
|
-
/**
|
|
36
|
-
* Given a shard number, inserts that shard in the expected pattern within the
|
|
37
|
-
* domain
|
|
38
|
-
*
|
|
39
|
-
* @param {string} domain
|
|
40
|
-
* @param {number} shard
|
|
41
|
-
*/
|
|
42
|
-
export function applyShardToDomain(domain: string, shard: number): string;
|
|
43
|
-
declare let globalKeyName: string;
|
|
44
|
-
export { globalKeyName as domainShardingKey };
|