vite-plugin-cross-origin-storage 1.3.18 → 1.3.20
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/dist/index.js +4 -2
- package/dist/loader.js +45 -82
- package/loader.js +45 -82
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1691,7 +1691,7 @@ function cosPlugin(options = {}) {
|
|
|
1691
1691
|
/[.*+?^${}()|[\]\\]/g,
|
|
1692
1692
|
"\\$&"
|
|
1693
1693
|
);
|
|
1694
|
-
const bareSpecifier =
|
|
1694
|
+
const bareSpecifier = `./${depFileName}`;
|
|
1695
1695
|
const staticPattern = `(import|export)\\b\\s*((?:(?!\\bimport\\b|\\bexport\\b)[\\s\\S])*?\\bfrom\\b\\s*)?['"]${escapedRelPath}['"]\\s*;?`;
|
|
1696
1696
|
const staticRegex = new RegExp(staticPattern, "g");
|
|
1697
1697
|
targetChunk.code = targetChunk.code.replace(
|
|
@@ -1722,8 +1722,10 @@ function cosPlugin(options = {}) {
|
|
|
1722
1722
|
hasDefault
|
|
1723
1723
|
};
|
|
1724
1724
|
}
|
|
1725
|
+
const entryFileName = mainChunk.fileName;
|
|
1725
1726
|
manifest["index"] = {
|
|
1726
|
-
|
|
1727
|
+
fileName: entryFileName,
|
|
1728
|
+
file: `${base}${entryFileName}`
|
|
1727
1729
|
};
|
|
1728
1730
|
if (htmlAsset) {
|
|
1729
1731
|
try {
|
package/dist/loader.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
(async function () {
|
|
2
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3
|
-
|
|
4
2
|
const isCOSAvailable = 'crossOriginStorage' in navigator;
|
|
5
3
|
console.log('COS Loader: isCOSAvailable =', isCOSAvailable);
|
|
6
4
|
|
|
@@ -44,100 +42,65 @@
|
|
|
44
42
|
const writable = await handles[0].createWritable();
|
|
45
43
|
await writable.write(blob);
|
|
46
44
|
await writable.close();
|
|
47
|
-
console.log('COS Loader: Stored
|
|
45
|
+
console.log('COS Loader: Stored chunk in COS', hash);
|
|
48
46
|
}
|
|
49
47
|
} catch (err) {
|
|
50
48
|
console.error('COS Loader: Failed to store in COS', err);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
0,
|
|
68
|
-
firstChunk.file.lastIndexOf('/') + 1
|
|
69
|
-
);
|
|
70
|
-
if (assetsDir && assetsUrl) {
|
|
71
|
-
importMap.imports[assetsDir] = assetsUrl;
|
|
52
|
+
async function getChunkDataUrl(chunk) {
|
|
53
|
+
let blob = await getBlobFromCOS(chunk.hash);
|
|
54
|
+
if (!blob) {
|
|
55
|
+
console.log(`COS Loader: ${chunk.file} not in COS, fetching...`);
|
|
56
|
+
try {
|
|
57
|
+
const resp = await fetch(chunk.file);
|
|
58
|
+
if (!resp.ok) throw new Error(`Status ${resp.status}`);
|
|
59
|
+
blob = await resp.blob();
|
|
60
|
+
await storeBlobInCOS(blob, chunk.hash);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(`COS Loader: Failed to fetch ${chunk.file}`, e);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
72
65
|
}
|
|
73
66
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
// Convert blob to Data URL
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
const reader = new FileReader();
|
|
70
|
+
reader.onloadend = () => resolve(reader.result);
|
|
71
|
+
reader.readAsDataURL(blob);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Initialize
|
|
76
|
+
try {
|
|
77
|
+
console.log('COS Loader: Starting app...');
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const response = await fetch(chunk.file);
|
|
88
|
-
if (response.ok) {
|
|
89
|
-
const blob = await response.blob();
|
|
90
|
-
url = URL.createObjectURL(
|
|
91
|
-
new Blob([blob], { type: 'text/javascript' })
|
|
92
|
-
);
|
|
93
|
-
// Store in COS for next time
|
|
94
|
-
storeBlobInCOS(blob, chunk.hash);
|
|
95
|
-
} else {
|
|
96
|
-
console.error(
|
|
97
|
-
`COS Loader: Fetch failed with status ${response.status}`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
} catch (e) {
|
|
101
|
-
console.error(
|
|
102
|
-
`COS Loader: Network fetch failed for ${chunk.file}`,
|
|
103
|
-
e
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
79
|
+
// Resolve all chunks to Data URLs
|
|
80
|
+
const importMap = { imports: {} };
|
|
81
|
+
const loadPromises = chunksToLoad.map(async (chunk) => {
|
|
82
|
+
const dataUrl = await getChunkDataUrl(chunk);
|
|
83
|
+
if (dataUrl) {
|
|
84
|
+
// Map the relative path (as used in the plugin's bare specifier rewrite) to the data URL
|
|
85
|
+
importMap.imports[`./${chunk.fileName}`] = dataUrl;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
107
88
|
|
|
108
|
-
|
|
109
|
-
// Use a Data URL shim to decouple the import graph.
|
|
110
|
-
// This ensures that the circular dependency between React and React-DOM
|
|
111
|
-
// doesn't cause a lockout/deadlock during the module graph instantiation.
|
|
112
|
-
const shim = `export * from "${url}";${chunk.hasDefault ? `export { default } from "${url}";` : ''}`;
|
|
113
|
-
const shimUrl = `data:text/javascript;base64,${btoa(shim)}`;
|
|
89
|
+
await Promise.all(loadPromises);
|
|
114
90
|
|
|
115
|
-
|
|
116
|
-
|
|
91
|
+
// Inject Import Map
|
|
92
|
+
const script = document.createElement('script');
|
|
93
|
+
script.type = 'importmap';
|
|
94
|
+
script.textContent = JSON.stringify(importMap);
|
|
95
|
+
document.head.appendChild(script);
|
|
117
96
|
|
|
118
|
-
|
|
119
|
-
if (chunk.globalVar) {
|
|
120
|
-
window[chunk.globalVar] = url;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
);
|
|
97
|
+
console.log('COS Loader: Import Map injected');
|
|
125
98
|
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
imScript.textContent = JSON.stringify(importMap);
|
|
131
|
-
document.head.appendChild(imScript);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
99
|
+
// Import the main entry.
|
|
100
|
+
// The main entry itself is also managed and rewritten to use bare specifiers.
|
|
101
|
+
const entryFileName = mainEntry.fileName;
|
|
102
|
+
await import(`./${entryFileName}`);
|
|
134
103
|
|
|
135
|
-
// Start App
|
|
136
|
-
try {
|
|
137
|
-
console.log('COS Loader: Starting app...');
|
|
138
|
-
// Ensure the importmap is registered before importing
|
|
139
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
140
|
-
await import(mainEntry.file);
|
|
141
104
|
} catch (err) {
|
|
142
105
|
console.error('COS Loader: Failed to start app', err);
|
|
143
106
|
}
|
package/loader.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
(async function () {
|
|
2
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3
|
-
|
|
4
2
|
const isCOSAvailable = 'crossOriginStorage' in navigator;
|
|
5
3
|
console.log('COS Loader: isCOSAvailable =', isCOSAvailable);
|
|
6
4
|
|
|
@@ -44,100 +42,65 @@
|
|
|
44
42
|
const writable = await handles[0].createWritable();
|
|
45
43
|
await writable.write(blob);
|
|
46
44
|
await writable.close();
|
|
47
|
-
console.log('COS Loader: Stored
|
|
45
|
+
console.log('COS Loader: Stored chunk in COS', hash);
|
|
48
46
|
}
|
|
49
47
|
} catch (err) {
|
|
50
48
|
console.error('COS Loader: Failed to store in COS', err);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
0,
|
|
68
|
-
firstChunk.file.lastIndexOf('/') + 1
|
|
69
|
-
);
|
|
70
|
-
if (assetsDir && assetsUrl) {
|
|
71
|
-
importMap.imports[assetsDir] = assetsUrl;
|
|
52
|
+
async function getChunkDataUrl(chunk) {
|
|
53
|
+
let blob = await getBlobFromCOS(chunk.hash);
|
|
54
|
+
if (!blob) {
|
|
55
|
+
console.log(`COS Loader: ${chunk.file} not in COS, fetching...`);
|
|
56
|
+
try {
|
|
57
|
+
const resp = await fetch(chunk.file);
|
|
58
|
+
if (!resp.ok) throw new Error(`Status ${resp.status}`);
|
|
59
|
+
blob = await resp.blob();
|
|
60
|
+
await storeBlobInCOS(blob, chunk.hash);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(`COS Loader: Failed to fetch ${chunk.file}`, e);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
72
65
|
}
|
|
73
66
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
// Convert blob to Data URL
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
const reader = new FileReader();
|
|
70
|
+
reader.onloadend = () => resolve(reader.result);
|
|
71
|
+
reader.readAsDataURL(blob);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Initialize
|
|
76
|
+
try {
|
|
77
|
+
console.log('COS Loader: Starting app...');
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const response = await fetch(chunk.file);
|
|
88
|
-
if (response.ok) {
|
|
89
|
-
const blob = await response.blob();
|
|
90
|
-
url = URL.createObjectURL(
|
|
91
|
-
new Blob([blob], { type: 'text/javascript' })
|
|
92
|
-
);
|
|
93
|
-
// Store in COS for next time
|
|
94
|
-
storeBlobInCOS(blob, chunk.hash);
|
|
95
|
-
} else {
|
|
96
|
-
console.error(
|
|
97
|
-
`COS Loader: Fetch failed with status ${response.status}`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
} catch (e) {
|
|
101
|
-
console.error(
|
|
102
|
-
`COS Loader: Network fetch failed for ${chunk.file}`,
|
|
103
|
-
e
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
79
|
+
// Resolve all chunks to Data URLs
|
|
80
|
+
const importMap = { imports: {} };
|
|
81
|
+
const loadPromises = chunksToLoad.map(async (chunk) => {
|
|
82
|
+
const dataUrl = await getChunkDataUrl(chunk);
|
|
83
|
+
if (dataUrl) {
|
|
84
|
+
// Map the relative path (as used in the plugin's bare specifier rewrite) to the data URL
|
|
85
|
+
importMap.imports[`./${chunk.fileName}`] = dataUrl;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
107
88
|
|
|
108
|
-
|
|
109
|
-
// Use a Data URL shim to decouple the import graph.
|
|
110
|
-
// This ensures that the circular dependency between React and React-DOM
|
|
111
|
-
// doesn't cause a lockout/deadlock during the module graph instantiation.
|
|
112
|
-
const shim = `export * from "${url}";${chunk.hasDefault ? `export { default } from "${url}";` : ''}`;
|
|
113
|
-
const shimUrl = `data:text/javascript;base64,${btoa(shim)}`;
|
|
89
|
+
await Promise.all(loadPromises);
|
|
114
90
|
|
|
115
|
-
|
|
116
|
-
|
|
91
|
+
// Inject Import Map
|
|
92
|
+
const script = document.createElement('script');
|
|
93
|
+
script.type = 'importmap';
|
|
94
|
+
script.textContent = JSON.stringify(importMap);
|
|
95
|
+
document.head.appendChild(script);
|
|
117
96
|
|
|
118
|
-
|
|
119
|
-
if (chunk.globalVar) {
|
|
120
|
-
window[chunk.globalVar] = url;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
);
|
|
97
|
+
console.log('COS Loader: Import Map injected');
|
|
125
98
|
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
imScript.textContent = JSON.stringify(importMap);
|
|
131
|
-
document.head.appendChild(imScript);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
99
|
+
// Import the main entry.
|
|
100
|
+
// The main entry itself is also managed and rewritten to use bare specifiers.
|
|
101
|
+
const entryFileName = mainEntry.fileName;
|
|
102
|
+
await import(`./${entryFileName}`);
|
|
134
103
|
|
|
135
|
-
// Start App
|
|
136
|
-
try {
|
|
137
|
-
console.log('COS Loader: Starting app...');
|
|
138
|
-
// Ensure the importmap is registered before importing
|
|
139
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
140
|
-
await import(mainEntry.file);
|
|
141
104
|
} catch (err) {
|
|
142
105
|
console.error('COS Loader: Failed to start app', err);
|
|
143
106
|
}
|