@ms-cloudpack/overlay 0.19.55 → 0.19.57
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/NOTICE.txt +27 -0
- package/dist/browser-esm/198.chunk.js +1 -1
- package/dist/browser-esm/282.chunk.js +3 -0
- package/dist/browser-esm/282.chunk.js.LICENSE.txt +9 -0
- package/dist/browser-esm/282.chunk.js.map +1 -0
- package/dist/browser-esm/lib/index.js +1 -1
- package/dist/browser-esm/lib/index.js.map +1 -1
- package/lib/handlePackageUpdate.d.ts +30 -0
- package/lib/handlePackageUpdate.d.ts.map +1 -0
- package/lib/handlePackageUpdate.js +106 -0
- package/lib/handlePackageUpdate.js.map +1 -0
- package/lib/index.js +9 -2
- package/lib/index.js.map +1 -1
- package/lib/registerReactRefresh.d.ts +16 -0
- package/lib/registerReactRefresh.d.ts.map +1 -0
- package/lib/registerReactRefresh.js +79 -0
- package/lib/registerReactRefresh.js.map +1 -0
- package/package.json +8 -6
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles hot module replacement (HMR) updates for packages.
|
|
3
|
+
*
|
|
4
|
+
* This function is called when the development server notifies the client that a package
|
|
5
|
+
* has been updated. It performs the following steps:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Check which modules are loaded**: Uses Performance API to determine which entry points
|
|
8
|
+
* from the package are actually loaded on the current page.
|
|
9
|
+
*
|
|
10
|
+
* 2. **Re-import updated modules**: Dynamically imports the new versions of loaded modules
|
|
11
|
+
* using their updated bundle URLs (with new hash).
|
|
12
|
+
*
|
|
13
|
+
* 3. **Trigger React Refresh**: If React Refresh is available, triggers component updates
|
|
14
|
+
* while preserving component state. Falls back to full page reload otherwise.
|
|
15
|
+
*
|
|
16
|
+
* The process ensures:
|
|
17
|
+
* - Only relevant modules are updated (skip modules not loaded on current page)
|
|
18
|
+
* - React component state is preserved when possible
|
|
19
|
+
* - Graceful fallback to full reload if React Refresh fails
|
|
20
|
+
*
|
|
21
|
+
* @param data - The package update payload containing package name, version, and entry points
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // This is typically called by the WebSocket message handler:
|
|
25
|
+
* socket.on('package-update', (data) => {
|
|
26
|
+
* await handlePackageUpdate(data);
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
export declare const handlePackageUpdate: (data: unknown) => Promise<void>;
|
|
30
|
+
//# sourceMappingURL=handlePackageUpdate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlePackageUpdate.d.ts","sourceRoot":"","sources":["../src/handlePackageUpdate.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,mBAAmB,GAAU,MAAM,OAAO,KAAG,OAAO,CAAC,IAAI,CAmFrE,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { removeHashFromUrl } from '@ms-cloudpack/path-string-parsing';
|
|
2
|
+
/**
|
|
3
|
+
* Handles hot module replacement (HMR) updates for packages.
|
|
4
|
+
*
|
|
5
|
+
* This function is called when the development server notifies the client that a package
|
|
6
|
+
* has been updated. It performs the following steps:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Check which modules are loaded**: Uses Performance API to determine which entry points
|
|
9
|
+
* from the package are actually loaded on the current page.
|
|
10
|
+
*
|
|
11
|
+
* 2. **Re-import updated modules**: Dynamically imports the new versions of loaded modules
|
|
12
|
+
* using their updated bundle URLs (with new hash).
|
|
13
|
+
*
|
|
14
|
+
* 3. **Trigger React Refresh**: If React Refresh is available, triggers component updates
|
|
15
|
+
* while preserving component state. Falls back to full page reload otherwise.
|
|
16
|
+
*
|
|
17
|
+
* The process ensures:
|
|
18
|
+
* - Only relevant modules are updated (skip modules not loaded on current page)
|
|
19
|
+
* - React component state is preserved when possible
|
|
20
|
+
* - Graceful fallback to full reload if React Refresh fails
|
|
21
|
+
*
|
|
22
|
+
* @param data - The package update payload containing package name, version, and entry points
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // This is typically called by the WebSocket message handler:
|
|
26
|
+
* socket.on('package-update', (data) => {
|
|
27
|
+
* await handlePackageUpdate(data);
|
|
28
|
+
* });
|
|
29
|
+
*/
|
|
30
|
+
export const handlePackageUpdate = async (data) => {
|
|
31
|
+
const { packageName, entryPoints, version } = data;
|
|
32
|
+
try {
|
|
33
|
+
console.log(`[Cloudpack HMR] Package updated: ${packageName}@${version}`);
|
|
34
|
+
// Get all loaded resources for checking
|
|
35
|
+
const normalizedResources = performance.getEntriesByType('resource').map((r) => removeHashFromUrl(r.name));
|
|
36
|
+
// Process each entry point
|
|
37
|
+
let loadedCount = 0;
|
|
38
|
+
for (const { importPath, bundleUrl } of entryPoints) {
|
|
39
|
+
// Check if this module was actually loaded using Performance API
|
|
40
|
+
// bundleUrl already has the new hash: http://localhost:5500/pkg@1.0.0/h-abc123-1234567890/v1.2/bundled/lib/file.js
|
|
41
|
+
// We normalize both URLs by removing the hash to compare them
|
|
42
|
+
const normalizedBundleUrl = removeHashFromUrl(bundleUrl);
|
|
43
|
+
const wasLoaded = normalizedResources.some((r) => r === normalizedBundleUrl);
|
|
44
|
+
if (!wasLoaded) {
|
|
45
|
+
console.log(`[Cloudpack HMR] Skipping ${importPath} - not loaded on this page`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
console.log(`[Cloudpack HMR] Loading ${importPath} from ${bundleUrl}`);
|
|
49
|
+
// Dynamic import - use webpackIgnore to bypass bundler's import analysis
|
|
50
|
+
// This ensures we use the browser's native import() for runtime URL
|
|
51
|
+
await import(/* webpackIgnore: true */ bundleUrl);
|
|
52
|
+
loadedCount++;
|
|
53
|
+
}
|
|
54
|
+
if (loadedCount === 0) {
|
|
55
|
+
console.log(`[Cloudpack HMR] No entry points from ${packageName} were loaded on this page`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// ===== Trigger React Refresh =====
|
|
59
|
+
//
|
|
60
|
+
// React Refresh is a hot reloading feature that updates React components without losing state.
|
|
61
|
+
// It allows developers to see component changes instantly while preserving:
|
|
62
|
+
// - Component state (useState, useReducer)
|
|
63
|
+
// - Form inputs
|
|
64
|
+
// - Scroll position
|
|
65
|
+
// - Any other runtime state
|
|
66
|
+
//
|
|
67
|
+
// How it works:
|
|
68
|
+
// 1. When modules are re-imported above, React Refresh automatically detects changed components
|
|
69
|
+
// 2. Components are registered via $RefreshReg$ calls (injected by the bundler during build)
|
|
70
|
+
// 3. Calling performReactRefresh() re-renders the registered components with new code
|
|
71
|
+
// 4. React's reconciliation preserves state by matching component types and positions
|
|
72
|
+
//
|
|
73
|
+
// The $RefreshRuntime$ global is initialized in registerReactRefresh.ts
|
|
74
|
+
if (window.$RefreshRuntime$?.performReactRefresh) {
|
|
75
|
+
// Perform the actual refresh - this will update all components that were re-registered
|
|
76
|
+
// during the dynamic import above, while preserving their state
|
|
77
|
+
const refreshResult = window.$RefreshRuntime$.performReactRefresh();
|
|
78
|
+
if (refreshResult === null) {
|
|
79
|
+
// Refresh returned null - this indicates no components were registered
|
|
80
|
+
// This shouldn't happen if we successfully imported modules, so we fall back to full reload
|
|
81
|
+
console.warn(`[Cloudpack HMR] React Refresh returned null despite registrations, reloading page`);
|
|
82
|
+
window.location.reload();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// React components successfully updated with state preservation
|
|
86
|
+
// refreshResult contains metadata about what was updated
|
|
87
|
+
console.log(`[Cloudpack HMR] ✓ Updated ${packageName}@${version}`, refreshResult);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// React Refresh runtime is not available
|
|
92
|
+
// This happens when:
|
|
93
|
+
// - React Refresh wasn't initialized (registerReactRefresh.ts not called)
|
|
94
|
+
// - The app doesn't use React
|
|
95
|
+
// - React Refresh was disabled
|
|
96
|
+
// Fall back to full page reload to show the changes
|
|
97
|
+
console.warn(`[Cloudpack HMR] React Refresh runtime not found, reloading page`);
|
|
98
|
+
window.location.reload();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(`[Cloudpack HMR] ✗ Failed to update ${packageName}:`, error);
|
|
103
|
+
window.location.reload();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=handlePackageUpdate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlePackageUpdate.js","sourceRoot":"","sources":["../src/handlePackageUpdate.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PackageUpdatePayload } from '@ms-cloudpack/api-server/browser';\nimport { removeHashFromUrl } from '@ms-cloudpack/path-string-parsing';\n\n/**\n * Handles hot module replacement (HMR) updates for packages.\n *\n * This function is called when the development server notifies the client that a package\n * has been updated. It performs the following steps:\n *\n * 1. **Check which modules are loaded**: Uses Performance API to determine which entry points\n * from the package are actually loaded on the current page.\n *\n * 2. **Re-import updated modules**: Dynamically imports the new versions of loaded modules\n * using their updated bundle URLs (with new hash).\n *\n * 3. **Trigger React Refresh**: If React Refresh is available, triggers component updates\n * while preserving component state. Falls back to full page reload otherwise.\n *\n * The process ensures:\n * - Only relevant modules are updated (skip modules not loaded on current page)\n * - React component state is preserved when possible\n * - Graceful fallback to full reload if React Refresh fails\n *\n * @param data - The package update payload containing package name, version, and entry points\n *\n * @example\n * // This is typically called by the WebSocket message handler:\n * socket.on('package-update', (data) => {\n * await handlePackageUpdate(data);\n * });\n */\nexport const handlePackageUpdate = async (data: unknown): Promise<void> => {\n const { packageName, entryPoints, version } = data as PackageUpdatePayload;\n\n try {\n console.log(`[Cloudpack HMR] Package updated: ${packageName}@${version}`);\n\n // Get all loaded resources for checking\n const normalizedResources = (performance.getEntriesByType('resource') as PerformanceResourceTiming[]).map((r) =>\n removeHashFromUrl(r.name),\n );\n\n // Process each entry point\n let loadedCount = 0;\n for (const { importPath, bundleUrl } of entryPoints) {\n // Check if this module was actually loaded using Performance API\n // bundleUrl already has the new hash: http://localhost:5500/pkg@1.0.0/h-abc123-1234567890/v1.2/bundled/lib/file.js\n // We normalize both URLs by removing the hash to compare them\n const normalizedBundleUrl = removeHashFromUrl(bundleUrl);\n const wasLoaded = normalizedResources.some((r) => r === normalizedBundleUrl);\n\n if (!wasLoaded) {\n console.log(`[Cloudpack HMR] Skipping ${importPath} - not loaded on this page`);\n continue;\n }\n\n console.log(`[Cloudpack HMR] Loading ${importPath} from ${bundleUrl}`);\n\n // Dynamic import - use webpackIgnore to bypass bundler's import analysis\n // This ensures we use the browser's native import() for runtime URL\n await import(/* webpackIgnore: true */ bundleUrl);\n loadedCount++;\n }\n\n if (loadedCount === 0) {\n console.log(`[Cloudpack HMR] No entry points from ${packageName} were loaded on this page`);\n return;\n }\n\n // ===== Trigger React Refresh =====\n //\n // React Refresh is a hot reloading feature that updates React components without losing state.\n // It allows developers to see component changes instantly while preserving:\n // - Component state (useState, useReducer)\n // - Form inputs\n // - Scroll position\n // - Any other runtime state\n //\n // How it works:\n // 1. When modules are re-imported above, React Refresh automatically detects changed components\n // 2. Components are registered via $RefreshReg$ calls (injected by the bundler during build)\n // 3. Calling performReactRefresh() re-renders the registered components with new code\n // 4. React's reconciliation preserves state by matching component types and positions\n //\n // The $RefreshRuntime$ global is initialized in registerReactRefresh.ts\n if (window.$RefreshRuntime$?.performReactRefresh) {\n // Perform the actual refresh - this will update all components that were re-registered\n // during the dynamic import above, while preserving their state\n const refreshResult = window.$RefreshRuntime$.performReactRefresh();\n\n if (refreshResult === null) {\n // Refresh returned null - this indicates no components were registered\n // This shouldn't happen if we successfully imported modules, so we fall back to full reload\n console.warn(`[Cloudpack HMR] React Refresh returned null despite registrations, reloading page`);\n window.location.reload();\n } else {\n // React components successfully updated with state preservation\n // refreshResult contains metadata about what was updated\n console.log(`[Cloudpack HMR] ✓ Updated ${packageName}@${version}`, refreshResult);\n }\n } else {\n // React Refresh runtime is not available\n // This happens when:\n // - React Refresh wasn't initialized (registerReactRefresh.ts not called)\n // - The app doesn't use React\n // - React Refresh was disabled\n // Fall back to full page reload to show the changes\n console.warn(`[Cloudpack HMR] React Refresh runtime not found, reloading page`);\n window.location.reload();\n }\n } catch (error) {\n console.error(`[Cloudpack HMR] ✗ Failed to update ${packageName}:`, error);\n window.location.reload();\n }\n};\n"]}
|
package/lib/index.js
CHANGED
|
@@ -4,7 +4,8 @@ import { CloudpackProvider } from './components/CloudpackProvider/CloudpackProvi
|
|
|
4
4
|
import { Overlay } from './components/Overlay/Overlay.js';
|
|
5
5
|
import { ThemeProvider } from './components/ThemeProvider/ThemeProvider.js';
|
|
6
6
|
import { elementIds } from './constants.js';
|
|
7
|
-
import { createCloudpackClient, reloadCountSource } from '@ms-cloudpack/api-server/browser';
|
|
7
|
+
import { createCloudpackClient, reloadCountSource, packageUpdateSource } from '@ms-cloudpack/api-server/browser';
|
|
8
|
+
import { handlePackageUpdate } from './handlePackageUpdate.js';
|
|
8
9
|
async function start() {
|
|
9
10
|
if (!window.__cloudpack) {
|
|
10
11
|
throw new Error('Cloudpack not found on window');
|
|
@@ -13,7 +14,7 @@ async function start() {
|
|
|
13
14
|
if (!pageSessionContext) {
|
|
14
15
|
throw new Error('Session context not found on window.__cloudpack');
|
|
15
16
|
}
|
|
16
|
-
const { apiUrl, currentSequence, sessionId, showOverlay } = pageSessionContext;
|
|
17
|
+
const { apiUrl, currentSequence, sessionId, showOverlay, features } = pageSessionContext;
|
|
17
18
|
// injectScripts shouldn't inject the overlay if it's disabled, but check here too
|
|
18
19
|
if (showOverlay === 'never') {
|
|
19
20
|
return;
|
|
@@ -38,6 +39,12 @@ async function start() {
|
|
|
38
39
|
});
|
|
39
40
|
},
|
|
40
41
|
});
|
|
42
|
+
// Subscribe to HMR package updates
|
|
43
|
+
if (features?.hmr) {
|
|
44
|
+
const { registerReactRefresh } = await import('./registerReactRefresh.js');
|
|
45
|
+
registerReactRefresh();
|
|
46
|
+
client.onDataChanged.subscribe(packageUpdateSource, { onData: (data) => void handlePackageUpdate(data) });
|
|
47
|
+
}
|
|
41
48
|
client.onDataChanged.subscribe(reloadCountSource, {
|
|
42
49
|
onData: (data) => {
|
|
43
50
|
if (Number(data) > currentSequence) {
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qDAAqD,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render } from 'preact';\nimport { CloudpackProvider } from './components/CloudpackProvider/CloudpackProvider.js';\nimport { Overlay } from './components/Overlay/Overlay.js';\nimport { ThemeProvider } from './components/ThemeProvider/ThemeProvider.js';\nimport { elementIds } from './constants.js';\nimport { createCloudpackClient, reloadCountSource, packageUpdateSource } from '@ms-cloudpack/api-server/browser';\nimport { handlePackageUpdate } from './handlePackageUpdate.js';\n\nasync function start(): Promise<void> {\n if (!window.__cloudpack) {\n throw new Error('Cloudpack not found on window');\n }\n\n const { pageSessionContext } = window.__cloudpack;\n\n if (!pageSessionContext) {\n throw new Error('Session context not found on window.__cloudpack');\n }\n\n const { apiUrl, currentSequence, sessionId, showOverlay, features } = pageSessionContext;\n\n // injectScripts shouldn't inject the overlay if it's disabled, but check here too\n if (showOverlay === 'never') {\n return;\n }\n\n const client = await createCloudpackClient({\n url: apiUrl,\n onOpen: () => {\n client.getSessionId\n .query()\n .then((newSessionId) => {\n if (sessionId === newSessionId) {\n console.log('[Cloudpack] socket opened, session Id:', sessionId);\n } else {\n console.warn('[Cloudpack] session ID mismatch, expected:', sessionId, 'but got:', newSessionId);\n // One possible reason for this is that the config has changed and the page needs to be reloaded.\n window.location.reload();\n }\n })\n .catch((err) => {\n console.error('[Cloudpack] Error getting session Id:', err);\n });\n },\n });\n\n // Subscribe to HMR package updates\n if (features?.hmr) {\n const { registerReactRefresh } = await import('./registerReactRefresh.js');\n registerReactRefresh();\n client.onDataChanged.subscribe(packageUpdateSource, { onData: (data) => void handlePackageUpdate(data) });\n }\n client.onDataChanged.subscribe(reloadCountSource, {\n onData: (data) => {\n if (Number(data) > currentSequence) {\n window.location.reload();\n }\n },\n });\n\n const rootDiv = document.createElement('div');\n rootDiv.id = elementIds.root;\n\n render(\n <ThemeProvider>\n <CloudpackProvider client={client}>\n <Overlay />\n </CloudpackProvider>\n </ThemeProvider>,\n rootDiv,\n );\n\n document.body.appendChild(rootDiv);\n}\n\nvoid start();\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initializes the React Refresh runtime for hot module replacement (HMR).
|
|
3
|
+
*
|
|
4
|
+
* React Refresh enables fast refresh of React components without losing their state.
|
|
5
|
+
* This function sets up the necessary global hooks and functions that the bundler-transformed
|
|
6
|
+
* code will use to register components and trigger updates.
|
|
7
|
+
*
|
|
8
|
+
* This should be called once during application initialization, before any React components are loaded.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // In your app entry point:
|
|
12
|
+
* import { registerReactRefresh } from '@ms-cloudpack/overlay';
|
|
13
|
+
* registerReactRefresh();
|
|
14
|
+
*/
|
|
15
|
+
export declare const registerReactRefresh: () => void;
|
|
16
|
+
//# sourceMappingURL=registerReactRefresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerReactRefresh.d.ts","sourceRoot":"","sources":["../src/registerReactRefresh.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,QAAO,IAkEvC,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import RefreshRuntime from 'react-refresh';
|
|
2
|
+
/**
|
|
3
|
+
* Initializes the React Refresh runtime for hot module replacement (HMR).
|
|
4
|
+
*
|
|
5
|
+
* React Refresh enables fast refresh of React components without losing their state.
|
|
6
|
+
* This function sets up the necessary global hooks and functions that the bundler-transformed
|
|
7
|
+
* code will use to register components and trigger updates.
|
|
8
|
+
*
|
|
9
|
+
* This should be called once during application initialization, before any React components are loaded.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // In your app entry point:
|
|
13
|
+
* import { registerReactRefresh } from '@ms-cloudpack/overlay';
|
|
14
|
+
* registerReactRefresh();
|
|
15
|
+
*/
|
|
16
|
+
export const registerReactRefresh = () => {
|
|
17
|
+
// Initialize React Refresh by injecting into React's internals
|
|
18
|
+
// This hooks into React's reconciler to enable hot reloading capabilities
|
|
19
|
+
// It modifies the global React DevTools hook to track component updates
|
|
20
|
+
RefreshRuntime.injectIntoGlobalHook(window);
|
|
21
|
+
// Set up the component registration function
|
|
22
|
+
// This function is called by bundler-injected code for every React component/hook
|
|
23
|
+
//
|
|
24
|
+
// Example of what the bundler transforms:
|
|
25
|
+
// Original code:
|
|
26
|
+
// export const MyComponent = () => <div>Hello</div>
|
|
27
|
+
//
|
|
28
|
+
// Transformed code:
|
|
29
|
+
// export const MyComponent = () => <div>Hello</div>
|
|
30
|
+
// $RefreshReg$(MyComponent, 'MyComponent');
|
|
31
|
+
//
|
|
32
|
+
// The registration allows React Refresh to:
|
|
33
|
+
// - Track which components exist in the module
|
|
34
|
+
// - Match old and new versions of components during updates
|
|
35
|
+
// - Determine if a full reload is needed (e.g., if hooks changed)
|
|
36
|
+
window.$RefreshReg$ = (type, id) => {
|
|
37
|
+
// TODO: Make this fully qualified with id including package name to avoid collisions
|
|
38
|
+
// Currently, if two packages export a component with the same name, they could collide
|
|
39
|
+
// Example collision: '@pkg-a/MyComponent' and '@pkg-b/MyComponent' both register as 'MyComponent'
|
|
40
|
+
RefreshRuntime.register(type, id);
|
|
41
|
+
};
|
|
42
|
+
// Set up the signature function for tracking hook changes
|
|
43
|
+
// This is used to detect when hooks in a component have changed
|
|
44
|
+
//
|
|
45
|
+
// Example of what the bundler transforms:
|
|
46
|
+
// Original code:
|
|
47
|
+
// const MyComponent = () => {
|
|
48
|
+
// const [count, setCount] = useState(0);
|
|
49
|
+
// return <div>{count}</div>
|
|
50
|
+
// }
|
|
51
|
+
//
|
|
52
|
+
// Transformed code:
|
|
53
|
+
// var _s = $RefreshSig$();
|
|
54
|
+
// const MyComponent = () => {
|
|
55
|
+
// _s(); // Signature call to track hooks
|
|
56
|
+
// const [count, setCount] = useState(0);
|
|
57
|
+
// return <div>{count}</div>
|
|
58
|
+
// }
|
|
59
|
+
// _s(MyComponent, "useState{count}");
|
|
60
|
+
//
|
|
61
|
+
// If hook signatures change (e.g., adding/removing useState), React Refresh will:
|
|
62
|
+
// - Detect the change via the signature mismatch
|
|
63
|
+
// - Force a full remount of the component (state will be lost)
|
|
64
|
+
// - Warn the developer about the limitation
|
|
65
|
+
window.$RefreshSig$ = () => {
|
|
66
|
+
return RefreshRuntime.createSignatureFunctionForTransform();
|
|
67
|
+
};
|
|
68
|
+
// Store the runtime globally for manual refresh triggering
|
|
69
|
+
// This is used by handlePackageUpdate.ts to call performReactRefresh()
|
|
70
|
+
// after new modules are imported
|
|
71
|
+
//
|
|
72
|
+
// The runtime provides:
|
|
73
|
+
// - performReactRefresh(): Triggers the actual component updates
|
|
74
|
+
// - register(): Called by $RefreshReg$ to track components
|
|
75
|
+
// - createSignatureFunctionForTransform(): Called by $RefreshSig$ to track hooks
|
|
76
|
+
window.$RefreshRuntime$ = RefreshRuntime;
|
|
77
|
+
console.log('[React Refresh] Runtime initialized');
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=registerReactRefresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerReactRefresh.js","sourceRoot":"","sources":["../src/registerReactRefresh.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,eAAe,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC7C,+DAA+D;IAC/D,0EAA0E;IAC1E,wEAAwE;IACxE,cAAc,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE5C,6CAA6C;IAC7C,kFAAkF;IAClF,EAAE;IACF,0CAA0C;IAC1C,iBAAiB;IACjB,sDAAsD;IACtD,EAAE;IACF,oBAAoB;IACpB,sDAAsD;IACtD,8CAA8C;IAC9C,EAAE;IACF,4CAA4C;IAC5C,+CAA+C;IAC/C,4DAA4D;IAC5D,kEAAkE;IAClE,MAAM,CAAC,YAAY,GAAG,CAAC,IAAa,EAAE,EAAU,EAAE,EAAE;QAClD,qFAAqF;QACrF,uFAAuF;QACvF,kGAAkG;QAClG,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,0DAA0D;IAC1D,gEAAgE;IAChE,EAAE;IACF,0CAA0C;IAC1C,iBAAiB;IACjB,gCAAgC;IAChC,6CAA6C;IAC7C,gCAAgC;IAChC,MAAM;IACN,EAAE;IACF,oBAAoB;IACpB,6BAA6B;IAC7B,gCAAgC;IAChC,8CAA8C;IAC9C,6CAA6C;IAC7C,gCAAgC;IAChC,MAAM;IACN,wCAAwC;IACxC,EAAE;IACF,kFAAkF;IAClF,iDAAiD;IACjD,+DAA+D;IAC/D,4CAA4C;IAC5C,MAAM,CAAC,YAAY,GAAG,GAAG,EAAE;QACzB,OAAO,cAAc,CAAC,mCAAmC,EAAE,CAAC;IAC9D,CAAC,CAAC;IAEF,2DAA2D;IAC3D,uEAAuE;IACvE,iCAAiC;IACjC,EAAE;IACF,wBAAwB;IACxB,iEAAiE;IACjE,2DAA2D;IAC3D,iFAAiF;IACjF,MAAM,CAAC,gBAAgB,GAAG,cAAc,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACrD,CAAC,CAAC","sourcesContent":["import RefreshRuntime from 'react-refresh';\n\n/**\n * Initializes the React Refresh runtime for hot module replacement (HMR).\n *\n * React Refresh enables fast refresh of React components without losing their state.\n * This function sets up the necessary global hooks and functions that the bundler-transformed\n * code will use to register components and trigger updates.\n *\n * This should be called once during application initialization, before any React components are loaded.\n *\n * @example\n * // In your app entry point:\n * import { registerReactRefresh } from '@ms-cloudpack/overlay';\n * registerReactRefresh();\n */\nexport const registerReactRefresh = (): void => {\n // Initialize React Refresh by injecting into React's internals\n // This hooks into React's reconciler to enable hot reloading capabilities\n // It modifies the global React DevTools hook to track component updates\n RefreshRuntime.injectIntoGlobalHook(window);\n\n // Set up the component registration function\n // This function is called by bundler-injected code for every React component/hook\n //\n // Example of what the bundler transforms:\n // Original code:\n // export const MyComponent = () => <div>Hello</div>\n //\n // Transformed code:\n // export const MyComponent = () => <div>Hello</div>\n // $RefreshReg$(MyComponent, 'MyComponent');\n //\n // The registration allows React Refresh to:\n // - Track which components exist in the module\n // - Match old and new versions of components during updates\n // - Determine if a full reload is needed (e.g., if hooks changed)\n window.$RefreshReg$ = (type: unknown, id: string) => {\n // TODO: Make this fully qualified with id including package name to avoid collisions\n // Currently, if two packages export a component with the same name, they could collide\n // Example collision: '@pkg-a/MyComponent' and '@pkg-b/MyComponent' both register as 'MyComponent'\n RefreshRuntime.register(type, id);\n };\n\n // Set up the signature function for tracking hook changes\n // This is used to detect when hooks in a component have changed\n //\n // Example of what the bundler transforms:\n // Original code:\n // const MyComponent = () => {\n // const [count, setCount] = useState(0);\n // return <div>{count}</div>\n // }\n //\n // Transformed code:\n // var _s = $RefreshSig$();\n // const MyComponent = () => {\n // _s(); // Signature call to track hooks\n // const [count, setCount] = useState(0);\n // return <div>{count}</div>\n // }\n // _s(MyComponent, \"useState{count}\");\n //\n // If hook signatures change (e.g., adding/removing useState), React Refresh will:\n // - Detect the change via the signature mismatch\n // - Force a full remount of the component (state will be lost)\n // - Warn the developer about the limitation\n window.$RefreshSig$ = () => {\n return RefreshRuntime.createSignatureFunctionForTransform();\n };\n\n // Store the runtime globally for manual refresh triggering\n // This is used by handlePackageUpdate.ts to call performReactRefresh()\n // after new modules are imported\n //\n // The runtime provides:\n // - performReactRefresh(): Triggers the actual component updates\n // - register(): Called by $RefreshReg$ to track components\n // - createSignatureFunctionForTransform(): Called by $RefreshSig$ to track hooks\n window.$RefreshRuntime$ = RefreshRuntime;\n\n console.log('[React Refresh] Runtime initialized');\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ms-cloudpack/overlay",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.57",
|
|
4
4
|
"description": "The Cloudpack overlay UX",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,16 +29,18 @@
|
|
|
29
29
|
"prepack": "cp .npmignore dist/.npmignore"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@ms-cloudpack/api-server": "^0.
|
|
33
|
-
"@ms-cloudpack/common-types": "^0.33.
|
|
34
|
-
"@ms-cloudpack/common-types-browser": "^0.6.
|
|
32
|
+
"@ms-cloudpack/api-server": "^0.66.0",
|
|
33
|
+
"@ms-cloudpack/common-types": "^0.33.2",
|
|
34
|
+
"@ms-cloudpack/common-types-browser": "^0.6.5",
|
|
35
35
|
"@ms-cloudpack/eslint-plugin-internal": "^0.0.1",
|
|
36
|
-
"@ms-cloudpack/path-string-parsing": "^1.
|
|
36
|
+
"@ms-cloudpack/path-string-parsing": "^1.3.0",
|
|
37
37
|
"@ms-cloudpack/scripts": "^0.0.1",
|
|
38
|
+
"@types/react-refresh": "^0.14.0",
|
|
38
39
|
"classnames": "^2.5.1",
|
|
39
40
|
"preact": "^10.26.8",
|
|
40
41
|
"react": "npm:@preact/compat@^18.0.0",
|
|
41
|
-
"react-focus-on": "^3.10.0"
|
|
42
|
+
"react-focus-on": "^3.10.0",
|
|
43
|
+
"react-refresh": "patch:react-refresh@npm%3A0.18.0#~/.yarn/patches/react-refresh-npm-0.18.0-5576c3f4a3.patch"
|
|
42
44
|
},
|
|
43
45
|
"files": [
|
|
44
46
|
"lib/**/!(*.test.*)",
|