catalyst-core 0.2.0-beta.2 → 0.3.0-beta.1

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.
Files changed (184) hide show
  1. package/babel.native.config.cjs +8 -0
  2. package/bin/catalyst.js +49 -105
  3. package/changelog.md +8 -0
  4. package/dist/caching.js +1 -1
  5. package/dist/index.jsx +8 -0
  6. package/dist/logger.js +74 -3
  7. package/dist/native/androidProject/app/build.gradle.kts +1 -0
  8. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +143 -4
  9. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +26 -6
  10. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MetricsMonitor.kt +143 -17
  11. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +6 -0
  12. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/WebCacheManager.kt +26 -0
  13. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +56 -1
  14. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/KeyboardUtil.kt +48 -8
  15. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/PerfDeliveryState.kt +36 -0
  16. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/PerfEventBuffer.kt +289 -0
  17. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/ProfilerNavigationState.kt +13 -0
  18. package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/ProfilerLifecycleTest.kt +51 -0
  19. package/dist/native/androidSetup.js +300 -8
  20. package/dist/native/bridge/WebBridge.js +481 -59
  21. package/dist/native/bridge/constants/NativeInterfaces.js +290 -44
  22. package/dist/native/bridge/errors.js +250 -26
  23. package/dist/native/bridge/hooks/index.js +125 -1
  24. package/dist/native/bridge/hooks/useCamera.js +347 -9
  25. package/dist/native/bridge/hooks/useDataProtection.js +200 -2
  26. package/dist/native/bridge/hooks/useDeviceInfo.js +71 -2
  27. package/dist/native/bridge/hooks/useFilePicker.js +429 -2
  28. package/dist/native/bridge/hooks/useGoogleSignIn.js +81 -1
  29. package/dist/native/bridge/hooks/useHapticFeedback.js +196 -1
  30. package/dist/native/bridge/hooks/useIntent.js +95 -1
  31. package/dist/native/bridge/hooks/useNativeTransition.js +202 -27
  32. package/dist/native/bridge/hooks/useNetworkStatus.js +84 -3
  33. package/dist/native/bridge/hooks/useNotification.js +318 -2
  34. package/dist/native/bridge/hooks/useSafeArea.js +84 -2
  35. package/dist/native/bridge/hooks/useVideoStream.js +434 -6
  36. package/dist/native/bridge/hooks/utils.js +27 -1
  37. package/dist/native/bridge/hooks.js +16 -1
  38. package/dist/native/bridge/perf/collectors/ApiCollector.js +85 -0
  39. package/dist/native/bridge/perf/collectors/CacheCollector.js +215 -0
  40. package/dist/native/bridge/perf/collectors/HookCollector.js +165 -0
  41. package/dist/native/bridge/perf/collectors/InsightsCollector.js +505 -0
  42. package/dist/native/bridge/perf/collectors/InteractionCollector.js +273 -0
  43. package/dist/native/bridge/perf/collectors/KeyboardCollector.js +124 -0
  44. package/dist/native/bridge/perf/collectors/NavigationCollector.js +294 -0
  45. package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +183 -0
  46. package/dist/native/bridge/perf/collectors/RenderCollector.js +284 -0
  47. package/dist/native/bridge/perf/collectors/ScrollCollector.js +111 -0
  48. package/dist/native/bridge/perf/collectors/ThreadCollector.js +111 -0
  49. package/dist/native/bridge/perf/core/constants.js +126 -0
  50. package/dist/native/bridge/perf/core/measure.js +189 -0
  51. package/dist/native/bridge/perf/core/session.js +100 -0
  52. package/dist/native/bridge/perf/core/store.js +554 -0
  53. package/dist/native/bridge/perf/core/summary.js +174 -0
  54. package/dist/native/bridge/perf/core/traceExport.js +240 -0
  55. package/dist/native/bridge/perf/core/waterfalls.js +146 -0
  56. package/dist/native/bridge/perf/index.js +402 -0
  57. package/dist/native/bridge/safeArea.js +53 -5
  58. package/dist/native/bridge/standardizedHooks.js +595 -82
  59. package/dist/native/bridge/useBaseHook.js +274 -38
  60. package/dist/native/bridge/utils/CameraUtils.js +201 -56
  61. package/dist/native/bridge/utils/FileObjectConverter.js +129 -18
  62. package/dist/native/bridge/utils/NativeBridge.js +425 -141
  63. package/dist/native/buildAndroid/assets.js +510 -13
  64. package/dist/native/buildAndroid/build.js +296 -19
  65. package/dist/native/buildAndroid/config.js +87 -1
  66. package/dist/native/buildAndroid/index.js +374 -1
  67. package/dist/native/buildAppAndroid.js +34 -2
  68. package/dist/native/buildAppIos.js +62 -2
  69. package/dist/native/buildIos/assets.js +609 -8
  70. package/dist/native/buildIos/build.js +639 -20
  71. package/dist/native/buildIos/config.js +294 -12
  72. package/dist/native/buildIos/index.js +343 -6
  73. package/dist/native/buildIos/plugins.js +343 -16
  74. package/dist/native/internal-plugins/device-info-plugin/android/DeviceInfoPlugin.kt +43 -0
  75. package/dist/native/internal-plugins/device-info-plugin/ios/DeviceInfoPlugin.swift +28 -0
  76. package/dist/native/internal-plugins/device-info-plugin/manifest.json +19 -0
  77. package/dist/native/internalPluginUtils.js +232 -7
  78. package/dist/native/iosnativeWebView/Sources/Core/Constants/CatalystConstants.swift +19 -0
  79. package/dist/native/iosnativeWebView/Sources/Core/Constants/ConfigConstants.swift +4 -0
  80. package/dist/native/iosnativeWebView/Sources/Core/Utils/BootTimingUtility.swift +5 -1
  81. package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +10 -0
  82. package/dist/native/iosnativeWebView/Sources/Core/Utils/DisplayLinkPerfMonitor.swift +89 -0
  83. package/dist/native/iosnativeWebView/Sources/Core/Utils/PerfEventBuffer.swift +373 -0
  84. package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeFileHandler.swift +35 -1
  85. package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeMessageValidator.swift +24 -11
  86. package/dist/native/iosnativeWebView/Sources/Core/WebView/NativeBridge.swift +9 -0
  87. package/dist/native/iosnativeWebView/Sources/Core/WebView/WebView.swift +126 -0
  88. package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +75 -1
  89. package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeMessageValidatorTests.swift +13 -0
  90. package/dist/native/package.json +3 -0
  91. package/dist/native/plugin-bridge/PluginBridge.js +227 -1
  92. package/dist/native/pluginComposerAndroid.js +407 -23
  93. package/dist/native/pluginComposerIos.js +435 -11
  94. package/dist/native/renameAndroidProject.js +1094 -88
  95. package/dist/native/setupEmulatorIos.js +289 -22
  96. package/dist/native/setupServer.js +160 -19
  97. package/dist/native/terminalProgress.js +199 -11
  98. package/dist/native/utils.js +193 -15
  99. package/dist/offline/catalyst-sw.js +145 -1
  100. package/dist/offline/registerServiceWorker.js +33 -1
  101. package/dist/otel.js +375 -46
  102. package/dist/router/ClientRouter.js +14 -2
  103. package/dist/router/ServerRouter.js +9 -1
  104. package/dist/router.js +1 -1
  105. package/dist/scripts/build.js +112 -3
  106. package/dist/scripts/checkVersion.js +3 -1
  107. package/dist/scripts/cleanCache.js +30 -1
  108. package/dist/scripts/generateOfflineManifest.js +116 -1
  109. package/dist/scripts/loadEnvironmentVariables.js +32 -6
  110. package/dist/scripts/plugins.js +309 -1
  111. package/dist/scripts/preServerInit.js +13 -0
  112. package/dist/scripts/scriptUtils.js +54 -3
  113. package/dist/scripts/serve.js +51 -4
  114. package/dist/scripts/start.js +47 -10
  115. package/dist/scripts/validator.js +149 -1
  116. package/dist/sentry.cjs +127 -0
  117. package/dist/sentry.js +125 -5
  118. package/dist/server/expressServer.js +250 -5
  119. package/dist/server/manifestCache.js +36 -0
  120. package/dist/server/renderer/ChunkExtractor.js +144 -0
  121. package/dist/server/renderer/document/Body.jsx +59 -0
  122. package/dist/server/renderer/document/FastRefresh.jsx +20 -0
  123. package/dist/server/renderer/document/Head.jsx +60 -0
  124. package/dist/server/renderer/document/index.jsx +2 -0
  125. package/dist/server/renderer/extract.js +149 -31
  126. package/dist/server/renderer/handler.jsx +433 -0
  127. package/dist/server/renderer/index.js +8 -1
  128. package/dist/server/renderer/render.js +47 -0
  129. package/dist/server/utils/botDetectionMiddleware.js +29 -0
  130. package/dist/server/utils/cjsRequire.js +10 -0
  131. package/dist/server/utils/userAgentUtil.js +87 -9
  132. package/dist/server/utils/validator.js +164 -1
  133. package/dist/vite/FastRefresh.jsx +20 -0
  134. package/dist/vite/inject-cache-key-plugin.js +276 -0
  135. package/dist/vite/loadCustomViteConfig.js +22 -0
  136. package/dist/vite/manifest-categorization-plugin.js +455 -0
  137. package/dist/vite/node-loader.mjs +458 -0
  138. package/dist/vite/scssParams.js +21 -0
  139. package/dist/vite/vite.config.client.js +130 -0
  140. package/dist/vite/vite.config.js +422 -0
  141. package/dist/vite/vite.config.server.js +84 -0
  142. package/dist/web-router/components/MetaTag.jsx +34 -0
  143. package/dist/web-router/components/RouterDataProvider.jsx +332 -0
  144. package/dist/web-router/components/Split.jsx +200 -0
  145. package/dist/web-router/components/SplitInview.jsx +106 -0
  146. package/dist/web-router/components/SsrRequestContext.jsx +14 -0
  147. package/dist/web-router/context.jsx +12 -0
  148. package/dist/web-router/hooks.jsx +72 -0
  149. package/dist/web-router/types/components/MetaTag.d.ts +2 -0
  150. package/dist/web-router/types/components/RouterDataProvider.d.ts +95 -0
  151. package/dist/web-router/types/context.d.ts +14 -0
  152. package/dist/web-router/types/hooks.d.ts +1 -0
  153. package/dist/web-router/types/index.d.ts +3 -0
  154. package/dist/web-router/types/utils/metaDataUtils.d.ts +24 -0
  155. package/dist/web-router/utils/metaDataUtils.jsx +119 -0
  156. package/mcp_v2/conversion-tasks.json +35 -17
  157. package/mcp_v2/knowledge-base.json +124 -13
  158. package/mcp_v2/lib/helpers.js +10 -0
  159. package/mcp_v2/mcp.js +4 -4
  160. package/mcp_v2/package.json +1 -0
  161. package/mcp_v2/tools/build.js +116 -20
  162. package/mcp_v2/tools/conversion.js +106 -5
  163. package/mcp_v2/tools/tasks.js +18 -14
  164. package/package.json +35 -68
  165. package/babel.config.js +0 -32
  166. package/dist/index.js +0 -1
  167. package/dist/scripts/devBuild.js +0 -3
  168. package/dist/scripts/devServe.js +0 -3
  169. package/dist/scripts/loadScriptsBeforeServerStarts.js +0 -4
  170. package/dist/scripts/registerAliases.js +0 -6
  171. package/dist/server/renderer/document/Body.js +0 -11
  172. package/dist/server/renderer/document/Head.js +0 -9
  173. package/dist/server/renderer/document/index.js +0 -1
  174. package/dist/server/renderer/handler.js +0 -47
  175. package/dist/server/startServer.js +0 -57
  176. package/dist/webpack/babel-plugins/remove-client.plugin.js +0 -5
  177. package/dist/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
  178. package/dist/webpack/babel.config.client.js +0 -1
  179. package/dist/webpack/babel.config.ssr.js +0 -1
  180. package/dist/webpack/base.babel.js +0 -7
  181. package/dist/webpack/development.client.babel.js +0 -10
  182. package/dist/webpack/production.client.babel.js +0 -4
  183. package/dist/webpack/production.ssr.babel.js +0 -8
  184. package/dist/webpack/scssParams.js +0 -9
@@ -1,11 +1,199 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var pc=_interopRequireWildcard(require("picocolors"));function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(i.get||i.set)?o(f,t,i):f[t]=e[t]);return f;})(e,t);}class TerminalProgress{constructor(steps,title="Setup Progress",options={}){this.steps=new Map(Object.entries(steps).map(([id,description])=>[id,{id,description,status:"pending",error:null}]));this.title=title;this.currentStep=null;this.isPaused=false;this.lineCount=0;this.lastRender="";// Default styling options
2
- this.options={titlePaddingTop:options.titlePaddingTop??1,titlePaddingBottom:options.titlePaddingBottom??1,stepPaddingLeft:options.stepPaddingLeft??2,stepSpacing:options.stepSpacing??0,errorPaddingLeft:options.errorPaddingLeft??4,bottomMargin:options.bottomMargin??1};}static icons={completed:"✓",running:"◆",pending:"○",error:"✗",info:"ℹ",warning:"⚠",prompt:"?"};printTreeContent(title,content){// Add top padding
3
- console.log("\n".repeat(this.options.titlePaddingTop));// Print the title
4
- console.log(`${pc.cyan(pc.bold(title))}`);// Process and print each line of content
5
- for(const line of content){if(typeof line==="string"){console.log(`${" ".repeat(this.options.stepPaddingLeft)}${line}`);}else if(typeof line==="object"){const{text,indent=0,prefix="",color="white"}=line;const indentation=" ".repeat(this.options.stepPaddingLeft+indent*3);const coloredText=pc[color]?pc[color](text):text;console.log(`${indentation}${prefix}${coloredText}`);}}}start(id){const step=this.steps.get(id);if(!step)throw new Error(`Step ${id} not found`);this.currentStep=step;step.status="running";this.render();}complete(id){const step=this.steps.get(id);if(!step)throw new Error(`Step ${id} not found`);step.status="completed";if(this.currentStep===step){this.currentStep=null;}this.render();}fail(id,error){const step=this.steps.get(id);if(!step)throw new Error(`Step ${id} not found`);step.status="error";step.error=error;if(this.currentStep===step){this.currentStep=null;}this.render();}pause(){this.isPaused=true;this.render();console.log("");}resume(){this.isPaused=false;console.log("");this.render();}getStepIcon(step){const icon=TerminalProgress.icons[step.status]||TerminalProgress.icons.pending;switch(step.status){case"completed":return pc.green(icon);case"error":return pc.red(icon);case"running":return pc.blue(icon);default:return pc.gray(icon);}}clearLines(){if(this.lineCount>0&&process.stdout.isTTY&&process.stdout.moveCursor){process.stdout.moveCursor(0,-this.lineCount);process.stdout.cursorTo(0);process.stdout.clearScreenDown();}}log(message,type="info"){this.pause();let icon;let color;switch(type){case"success":icon=TerminalProgress.icons.completed;color=pc.green;break;case"error":icon=TerminalProgress.icons.error;color=pc.red;break;case"warning":icon=TerminalProgress.icons.warning;color=pc.yellow;break;case"prompt":icon=TerminalProgress.icons.prompt;color=pc.yellow;break;default:icon=TerminalProgress.icons.info;color=pc.blue;}console.log(`${" ".repeat(this.options.stepPaddingLeft)}${color(icon)} ${message}`);this.resume();}render(){if(this.isPaused)return;this.clearLines();let output="";let currentLineCount=0;// Add top padding
6
- output+="\n".repeat(this.options.titlePaddingTop);currentLineCount+=this.options.titlePaddingTop;// Render title
7
- output+=`${pc.bold(pc.cyan(this.title))}\n`;output+=`${pc.gray("─".repeat(this.title.length))}\n`;currentLineCount+=2;// Add padding after title
8
- output+="\n".repeat(this.options.titlePaddingBottom);currentLineCount+=this.options.titlePaddingBottom;// Render steps
9
- for(const step of this.steps.values()){const icon=this.getStepIcon(step);const description=step.status==="error"?pc.red(step.description):step.status==="completed"?pc.green(step.description):step.status==="running"?pc.blue(step.description):pc.gray(step.description);const stepPadding=" ".repeat(this.options.stepPaddingLeft);output+=`${stepPadding}${icon} ${description}\n`;currentLineCount++;if(step.status==="error"&&step.error){const errorPadding=" ".repeat(this.options.errorPaddingLeft);output+=`${errorPadding}${pc.red("↳")} ${pc.red(step.error)}\n`;currentLineCount++;}// Add spacing between steps
10
- if(this.options.stepSpacing>0){output+="\n".repeat(this.options.stepSpacing);currentLineCount+=this.options.stepSpacing;}}// Add bottom margin
11
- output+="\n".repeat(this.options.bottomMargin);currentLineCount+=this.options.bottomMargin;if(output!==this.lastRender){process.stdout.write(output);this.lastRender=output;this.lineCount=currentLineCount;}}}var _default=exports.default=TerminalProgress;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var pc = _interopRequireWildcard(require("picocolors"));
8
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
9
+ class TerminalProgress {
10
+ constructor(steps, title = "Setup Progress", options = {}) {
11
+ this.steps = new Map(Object.entries(steps).map(([id, description]) => [id, {
12
+ id,
13
+ description,
14
+ status: "pending",
15
+ error: null
16
+ }]));
17
+ this.title = title;
18
+ this.currentStep = null;
19
+ this.isPaused = false;
20
+ this.lineCount = 0;
21
+ this.lastRender = "";
22
+
23
+ // Default styling options
24
+ this.options = {
25
+ titlePaddingTop: options.titlePaddingTop ?? 1,
26
+ titlePaddingBottom: options.titlePaddingBottom ?? 1,
27
+ stepPaddingLeft: options.stepPaddingLeft ?? 2,
28
+ stepSpacing: options.stepSpacing ?? 0,
29
+ errorPaddingLeft: options.errorPaddingLeft ?? 4,
30
+ bottomMargin: options.bottomMargin ?? 1
31
+ };
32
+ }
33
+ static icons = {
34
+ completed: "✓",
35
+ running: "◆",
36
+ pending: "○",
37
+ error: "✗",
38
+ info: "ℹ",
39
+ warning: "⚠",
40
+ prompt: "?"
41
+ };
42
+ printTreeContent(title, content) {
43
+ // Add top padding
44
+ console.log("\n".repeat(this.options.titlePaddingTop));
45
+
46
+ // Print the title
47
+ console.log(`${pc.cyan(pc.bold(title))}`);
48
+
49
+ // Process and print each line of content
50
+ for (const line of content) {
51
+ if (typeof line === "string") {
52
+ console.log(`${" ".repeat(this.options.stepPaddingLeft)}${line}`);
53
+ } else if (typeof line === "object") {
54
+ const {
55
+ text,
56
+ indent = 0,
57
+ prefix = "",
58
+ color = "white"
59
+ } = line;
60
+ const indentation = " ".repeat(this.options.stepPaddingLeft + indent * 3);
61
+ const coloredText = pc[color] ? pc[color](text) : text;
62
+ console.log(`${indentation}${prefix}${coloredText}`);
63
+ }
64
+ }
65
+ }
66
+ start(id) {
67
+ const step = this.steps.get(id);
68
+ if (!step) throw new Error(`Step ${id} not found`);
69
+ this.currentStep = step;
70
+ step.status = "running";
71
+ this.render();
72
+ }
73
+ complete(id) {
74
+ const step = this.steps.get(id);
75
+ if (!step) throw new Error(`Step ${id} not found`);
76
+ step.status = "completed";
77
+ if (this.currentStep === step) {
78
+ this.currentStep = null;
79
+ }
80
+ this.render();
81
+ }
82
+ fail(id, error) {
83
+ const step = this.steps.get(id);
84
+ if (!step) throw new Error(`Step ${id} not found`);
85
+ step.status = "error";
86
+ step.error = error;
87
+ if (this.currentStep === step) {
88
+ this.currentStep = null;
89
+ }
90
+ this.render();
91
+ }
92
+ pause() {
93
+ this.isPaused = true;
94
+ this.render();
95
+ console.log("");
96
+ }
97
+ resume() {
98
+ this.isPaused = false;
99
+ console.log("");
100
+ this.render();
101
+ }
102
+ getStepIcon(step) {
103
+ const icon = TerminalProgress.icons[step.status] || TerminalProgress.icons.pending;
104
+ switch (step.status) {
105
+ case "completed":
106
+ return pc.green(icon);
107
+ case "error":
108
+ return pc.red(icon);
109
+ case "running":
110
+ return pc.blue(icon);
111
+ default:
112
+ return pc.gray(icon);
113
+ }
114
+ }
115
+ clearLines() {
116
+ if (this.lineCount > 0 && process.stdout.isTTY && process.stdout.moveCursor) {
117
+ process.stdout.moveCursor(0, -this.lineCount);
118
+ process.stdout.cursorTo(0);
119
+ process.stdout.clearScreenDown();
120
+ }
121
+ }
122
+ log(message, type = "info") {
123
+ this.pause();
124
+ let icon;
125
+ let color;
126
+ switch (type) {
127
+ case "success":
128
+ icon = TerminalProgress.icons.completed;
129
+ color = pc.green;
130
+ break;
131
+ case "error":
132
+ icon = TerminalProgress.icons.error;
133
+ color = pc.red;
134
+ break;
135
+ case "warning":
136
+ icon = TerminalProgress.icons.warning;
137
+ color = pc.yellow;
138
+ break;
139
+ case "prompt":
140
+ icon = TerminalProgress.icons.prompt;
141
+ color = pc.yellow;
142
+ break;
143
+ default:
144
+ icon = TerminalProgress.icons.info;
145
+ color = pc.blue;
146
+ }
147
+ console.log(`${" ".repeat(this.options.stepPaddingLeft)}${color(icon)} ${message}`);
148
+ this.resume();
149
+ }
150
+ render() {
151
+ if (this.isPaused) return;
152
+ this.clearLines();
153
+ let output = "";
154
+ let currentLineCount = 0;
155
+
156
+ // Add top padding
157
+ output += "\n".repeat(this.options.titlePaddingTop);
158
+ currentLineCount += this.options.titlePaddingTop;
159
+
160
+ // Render title
161
+ output += `${pc.bold(pc.cyan(this.title))}\n`;
162
+ output += `${pc.gray("─".repeat(this.title.length))}\n`;
163
+ currentLineCount += 2;
164
+
165
+ // Add padding after title
166
+ output += "\n".repeat(this.options.titlePaddingBottom);
167
+ currentLineCount += this.options.titlePaddingBottom;
168
+
169
+ // Render steps
170
+ for (const step of this.steps.values()) {
171
+ const icon = this.getStepIcon(step);
172
+ const description = step.status === "error" ? pc.red(step.description) : step.status === "completed" ? pc.green(step.description) : step.status === "running" ? pc.blue(step.description) : pc.gray(step.description);
173
+ const stepPadding = " ".repeat(this.options.stepPaddingLeft);
174
+ output += `${stepPadding}${icon} ${description}\n`;
175
+ currentLineCount++;
176
+ if (step.status === "error" && step.error) {
177
+ const errorPadding = " ".repeat(this.options.errorPaddingLeft);
178
+ output += `${errorPadding}${pc.red("↳")} ${pc.red(step.error)}\n`;
179
+ currentLineCount++;
180
+ }
181
+
182
+ // Add spacing between steps
183
+ if (this.options.stepSpacing > 0) {
184
+ output += "\n".repeat(this.options.stepSpacing);
185
+ currentLineCount += this.options.stepSpacing;
186
+ }
187
+ }
188
+
189
+ // Add bottom margin
190
+ output += "\n".repeat(this.options.bottomMargin);
191
+ currentLineCount += this.options.bottomMargin;
192
+ if (output !== this.lastRender) {
193
+ process.stdout.write(output);
194
+ this.lastRender = output;
195
+ this.lineCount = currentLineCount;
196
+ }
197
+ }
198
+ }
199
+ var _default = exports.default = TerminalProgress;
@@ -1,15 +1,193 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.commandExists=commandExists;exports.promptUser=promptUser;exports.runCommand=runCommand;exports.runInteractiveCommand=runInteractiveCommand;exports.runSdkManagerCommand=runSdkManagerCommand;exports.validateAndCompleteConfig=validateAndCompleteConfig;var _child_process=require("child_process");var _readline=_interopRequireDefault(require("readline"));var _fs=_interopRequireDefault(require("fs"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}const rl=_readline.default.createInterface({input:process.stdin,output:process.stdout});function runCommand(command){try{// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Native setup/build uses fixed internal command strings; preserve existing shell behavior.
2
- return(0,_child_process.execSync)(command,{encoding:"utf8"});}catch(error){console.error(`Error executing command: ${command}`);console.error(`Error message: ${error.message}`);throw error;}}function commandExists(command){try{// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Utility checks known local tool names during native setup.
3
- (0,_child_process.execSync)(`which ${command}`,{stdio:"ignore"});return true;}catch(error){return false;}}async function promptUser(question){return new Promise(resolve=>{rl.question(question,answer=>{resolve(answer.trim());});});}async function runInteractiveCommand(command,args,promptResponses={}){return new Promise((resolve,reject)=>{// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Native build commands are fixed internal commands passed with argv arrays.
4
- const process=(0,_child_process.spawn)(command,args,{stdio:["pipe","pipe","pipe"]});let buffer="";let outputBuffer="";process.stdout.on("data",data=>{buffer+=data.toString();outputBuffer+=data.toString();console.log(data.toString());handlePrompts(process,buffer,promptResponses);});process.stderr.on("data",data=>{buffer+=data.toString();outputBuffer+=data.toString();console.error(data.toString());handlePrompts(process,buffer,promptResponses);});process.on("close",code=>{if(code===0){resolve(outputBuffer);}else{reject(new Error(`Command failed with exit code ${code}`));}});});}function handlePrompts(process,buffer,promptResponses){for(const[prompt,response]of Object.entries(promptResponses)){if(buffer.includes(prompt)){process.stdin.write(response+"\n");return;}}}async function runSdkManagerCommand(sdkManagerPath,args){const promptResponses={"(y/N)":"y","Accept? (y/N):":"y"};return runInteractiveCommand(sdkManagerPath,args,promptResponses);}async function validateAndCompleteConfig(platform,configPath){// Read existing config
5
- let config;try{const configContent=_fs.default.readFileSync(configPath,"utf8");config=JSON.parse(configContent);}catch(error){console.error(`Error reading config file: ${error.message}`);config={};}// Initialize WEBVIEW_CONFIG if it doesn't exist
6
- if(!config.WEBVIEW_CONFIG){config.WEBVIEW_CONFIG={};}// Check if WEBVIEW_CONFIG already has all required fields
7
- const webviewConfig=config.WEBVIEW_CONFIG;const commonFields={port:"Enter port number (e.g., 3005): "};const platformConfigs={android:{buildType:"Enter Android build type (debug/release): ",sdkPath:"Enter Android SDK path: ",emulatorName:"Enter Android emulator name (e.g., Small_Phone_API_35): ",cachePattern:"Enter Cache pattern (e.g., *.css): "},ios:{buildType:"Enter iOS build type (debug/release): ",appBundleId:"Enter iOS bundle ID (e.g., com.test.test): ",simulatorName:"Enter iOS simulator name (e.g., iPhone 16 Pro): ",cachePattern:"Enter Cache pattern (e.g., *.css): "}};if(!platformConfigs[platform]){throw new Error('Invalid platform. Must be either "android" or "ios"');}// Check if all required fields are present
8
- let hasAllFields=true;// Check common fields
9
- for(const key of Object.keys(commonFields)){if(!webviewConfig[key]){hasAllFields=false;break;}}// Check platform-specific fields
10
- if(!webviewConfig[platform]){webviewConfig[platform]={};hasAllFields=false;}else{for(const key of Object.keys(platformConfigs[platform])){if(!webviewConfig[platform][key]){hasAllFields=false;break;}}}// If all fields are present, return the platform-specific config
11
- if(hasAllFields){return{port:webviewConfig.port,[platform]:webviewConfig[platform]};}// Handle common fields
12
- for(const[key,prompt]of Object.entries(commonFields)){if(!webviewConfig[key]){webviewConfig[key]=await promptUser(prompt);}}// Handle platform-specific fields
13
- for(const[key,prompt]of Object.entries(platformConfigs[platform])){if(!webviewConfig[platform][key]){webviewConfig[platform][key]=await promptUser(prompt);}}// Save updated config back to file
14
- try{_fs.default.writeFileSync(configPath,JSON.stringify(config,null,2));console.log("Configuration updated successfully.");}catch(error){console.error(`Error saving config file: ${error.message}`);throw error;}// Return only the platform-specific config
15
- return{port:webviewConfig.port,[platform]:webviewConfig[platform]};}
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.commandExists = commandExists;
7
+ exports.promptUser = promptUser;
8
+ exports.runCommand = runCommand;
9
+ exports.runInteractiveCommand = runInteractiveCommand;
10
+ exports.runSdkManagerCommand = runSdkManagerCommand;
11
+ exports.validateAndCompleteConfig = validateAndCompleteConfig;
12
+ var _child_process = require("child_process");
13
+ var _readline = _interopRequireDefault(require("readline"));
14
+ var _fs = _interopRequireDefault(require("fs"));
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ const rl = _readline.default.createInterface({
17
+ input: process.stdin,
18
+ output: process.stdout
19
+ });
20
+ function runCommand(command) {
21
+ try {
22
+ // nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Native setup/build uses fixed internal command strings; preserve existing shell behavior.
23
+ return (0, _child_process.execSync)(command, {
24
+ encoding: "utf8"
25
+ });
26
+ } catch (error) {
27
+ console.error(`Error executing command: ${command}`);
28
+ console.error(`Error message: ${error.message}`);
29
+ throw error;
30
+ }
31
+ }
32
+ function commandExists(command) {
33
+ try {
34
+ // nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Utility checks known local tool names during native setup.
35
+ (0, _child_process.execSync)(`which ${command}`, {
36
+ stdio: "ignore"
37
+ });
38
+ return true;
39
+ } catch (error) {
40
+ return false;
41
+ }
42
+ }
43
+ async function promptUser(question) {
44
+ return new Promise(resolve => {
45
+ rl.question(question, answer => {
46
+ resolve(answer.trim());
47
+ });
48
+ });
49
+ }
50
+ async function runInteractiveCommand(command, args, promptResponses = {}) {
51
+ return new Promise((resolve, reject) => {
52
+ // nosemgrep: javascript.lang.security.detect-child-process.detect-child-process - Native build commands are fixed internal commands passed with argv arrays.
53
+ const process = (0, _child_process.spawn)(command, args, {
54
+ stdio: ["pipe", "pipe", "pipe"]
55
+ });
56
+ let buffer = "";
57
+ let outputBuffer = "";
58
+ process.stdout.on("data", data => {
59
+ buffer += data.toString();
60
+ outputBuffer += data.toString();
61
+ console.log(data.toString());
62
+ handlePrompts(process, buffer, promptResponses);
63
+ });
64
+ process.stderr.on("data", data => {
65
+ buffer += data.toString();
66
+ outputBuffer += data.toString();
67
+ console.error(data.toString());
68
+ handlePrompts(process, buffer, promptResponses);
69
+ });
70
+ process.on("close", code => {
71
+ if (code === 0) {
72
+ resolve(outputBuffer);
73
+ } else {
74
+ reject(new Error(`Command failed with exit code ${code}`));
75
+ }
76
+ });
77
+ });
78
+ }
79
+ function handlePrompts(process, buffer, promptResponses) {
80
+ for (const [prompt, response] of Object.entries(promptResponses)) {
81
+ if (buffer.includes(prompt)) {
82
+ process.stdin.write(response + "\n");
83
+ return;
84
+ }
85
+ }
86
+ }
87
+ async function runSdkManagerCommand(sdkManagerPath, args) {
88
+ const promptResponses = {
89
+ "(y/N)": "y",
90
+ "Accept? (y/N):": "y"
91
+ };
92
+ return runInteractiveCommand(sdkManagerPath, args, promptResponses);
93
+ }
94
+ async function validateAndCompleteConfig(platform, configPath) {
95
+ // Read existing config
96
+ let config;
97
+ try {
98
+ const configContent = _fs.default.readFileSync(configPath, "utf8");
99
+ config = JSON.parse(configContent);
100
+ } catch (error) {
101
+ console.error(`Error reading config file: ${error.message}`);
102
+ config = {};
103
+ }
104
+
105
+ // Initialize WEBVIEW_CONFIG if it doesn't exist
106
+ if (!config.WEBVIEW_CONFIG) {
107
+ config.WEBVIEW_CONFIG = {};
108
+ }
109
+
110
+ // Check if WEBVIEW_CONFIG already has all required fields
111
+ const webviewConfig = config.WEBVIEW_CONFIG;
112
+ const commonFields = {
113
+ port: "Enter port number (e.g., 3005): "
114
+ };
115
+ const platformConfigs = {
116
+ android: {
117
+ buildType: "Enter Android build type (debug/release): ",
118
+ sdkPath: "Enter Android SDK path: ",
119
+ emulatorName: "Enter Android emulator name (e.g., Small_Phone_API_35): ",
120
+ cachePattern: "Enter Cache pattern (e.g., *.css): "
121
+ },
122
+ ios: {
123
+ buildType: "Enter iOS build type (debug/release): ",
124
+ appBundleId: "Enter iOS bundle ID (e.g., com.test.test): ",
125
+ simulatorName: "Enter iOS simulator name (e.g., iPhone 16 Pro): ",
126
+ cachePattern: "Enter Cache pattern (e.g., *.css): "
127
+ }
128
+ };
129
+ if (!platformConfigs[platform]) {
130
+ throw new Error('Invalid platform. Must be either "android" or "ios"');
131
+ }
132
+
133
+ // Check if all required fields are present
134
+ let hasAllFields = true;
135
+
136
+ // Check common fields
137
+ for (const key of Object.keys(commonFields)) {
138
+ if (!webviewConfig[key]) {
139
+ hasAllFields = false;
140
+ break;
141
+ }
142
+ }
143
+
144
+ // Check platform-specific fields
145
+ if (!webviewConfig[platform]) {
146
+ webviewConfig[platform] = {};
147
+ hasAllFields = false;
148
+ } else {
149
+ for (const key of Object.keys(platformConfigs[platform])) {
150
+ if (!webviewConfig[platform][key]) {
151
+ hasAllFields = false;
152
+ break;
153
+ }
154
+ }
155
+ }
156
+
157
+ // If all fields are present, return the platform-specific config
158
+ if (hasAllFields) {
159
+ return {
160
+ port: webviewConfig.port,
161
+ [platform]: webviewConfig[platform]
162
+ };
163
+ }
164
+
165
+ // Handle common fields
166
+ for (const [key, prompt] of Object.entries(commonFields)) {
167
+ if (!webviewConfig[key]) {
168
+ webviewConfig[key] = await promptUser(prompt);
169
+ }
170
+ }
171
+
172
+ // Handle platform-specific fields
173
+ for (const [key, prompt] of Object.entries(platformConfigs[platform])) {
174
+ if (!webviewConfig[platform][key]) {
175
+ webviewConfig[platform][key] = await promptUser(prompt);
176
+ }
177
+ }
178
+
179
+ // Save updated config back to file
180
+ try {
181
+ _fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
182
+ console.log("Configuration updated successfully.");
183
+ } catch (error) {
184
+ console.error(`Error saving config file: ${error.message}`);
185
+ throw error;
186
+ }
187
+
188
+ // Return only the platform-specific config
189
+ return {
190
+ port: webviewConfig.port,
191
+ [platform]: webviewConfig[platform]
192
+ };
193
+ }
@@ -1 +1,145 @@
1
- "use strict";/* eslint-disable no-restricted-globals */const MANIFEST_URL="/catalyst-offline-manifest.json";const OFFLINE_URL="/offline.html";const CACHE_PREFIX="catalyst-offline";const MANIFEST_CACHE=`${CACHE_PREFIX}-manifest`;self.addEventListener("install",event=>{event.waitUntil((async()=>{await loadManifest(true);await cacheOfflineFallback();await self.skipWaiting();})());});self.addEventListener("activate",event=>{event.waitUntil((async()=>{await cleanupOldCaches();await self.clients.claim();})());});self.addEventListener("fetch",event=>{const{request}=event;if(request.method!=="GET")return;if(request.mode==="navigate"||request.destination==="document"){event.respondWith(handleNavigation(request));return;}if(["script","style","font","image"].includes(request.destination)){event.respondWith(handleAsset(request));}});async function loadManifest(preferNetwork){const cache=await caches.open(MANIFEST_CACHE);if(preferNetwork){try{const response=await fetch(MANIFEST_URL,{cache:"no-store"});if(response.ok){await cache.put(MANIFEST_URL,response.clone());const manifest=await response.json();cleanupOldCaches(manifest);return manifest;}}catch(_){}}const cached=await cache.match(MANIFEST_URL);if(cached)return cached.json();return{buildId:"unknown",routes:[]};}async function cacheOfflineFallback(){try{const cache=await caches.open(`${CACHE_PREFIX}-fallback`);const response=await fetch(OFFLINE_URL,{cache:"no-store"});if(response.ok)await cache.put(OFFLINE_URL,response);}catch(_){}}function routeCacheName(manifest){return`${CACHE_PREFIX}-routes-${manifest.buildId}`;}function assetCacheName(manifest){return`${CACHE_PREFIX}-assets-${manifest.buildId}`;}async function cleanupOldCaches(manifest){manifest=manifest||(await loadManifest(false));if(!manifest.buildId||manifest.buildId==="unknown")return;const keep=new Set([MANIFEST_CACHE,`${CACHE_PREFIX}-fallback`,routeCacheName(manifest),assetCacheName(manifest)]);const cacheNames=await caches.keys();await Promise.all(cacheNames.filter(name=>name.startsWith(CACHE_PREFIX)&&!keep.has(name)).map(name=>caches.delete(name)));}function isOfflineRoute(url,manifest){const{pathname}=new URL(url);return(manifest.routes||[]).some(route=>{try{return new RegExp(route.regex).test(pathname);}catch(_){return false;}});}function canStore(response){return!!(response&&(response.ok||response.type==="opaque"));}async function handleNavigation(request){const manifest=await loadManifest(true);if(!isOfflineRoute(request.url,manifest))return fetch(request);const cache=await caches.open(routeCacheName(manifest));try{const response=await fetch(request);const contentType=response.headers.get("content-type")||"";if(canStore(response)&&contentType.includes("text/html")){await cache.put(request.url,response.clone());}return response;}catch(_){const cached=await cache.match(request.url);if(cached)return cached;const offlineResponse=await caches.match(OFFLINE_URL);if(offlineResponse)return offlineResponse;return fetch(OFFLINE_URL);}}async function handleAsset(request){const manifest=await loadManifest(false);const cache=await caches.open(assetCacheName(manifest));const cached=await cache.match(request);if(cached)return cached;const response=await fetch(request);if(canStore(response))await cache.put(request,response.clone());return response;}
1
+ /* eslint-disable no-restricted-globals */
2
+ const MANIFEST_URL = "/catalyst-offline-manifest.json"
3
+ const OFFLINE_URL = "/offline.html"
4
+ const CACHE_PREFIX = "catalyst-offline"
5
+ const MANIFEST_CACHE = `${CACHE_PREFIX}-manifest`
6
+
7
+ self.addEventListener("install", (event) => {
8
+ event.waitUntil(
9
+ (async () => {
10
+ await loadManifest(true)
11
+ await cacheOfflineFallback()
12
+ await self.skipWaiting()
13
+ })()
14
+ )
15
+ })
16
+
17
+ self.addEventListener("activate", (event) => {
18
+ event.waitUntil(
19
+ (async () => {
20
+ await cleanupOldCaches()
21
+ await self.clients.claim()
22
+ })()
23
+ )
24
+ })
25
+
26
+ self.addEventListener("fetch", (event) => {
27
+ const { request } = event
28
+ if (request.method !== "GET") return
29
+
30
+ if (request.mode === "navigate" || request.destination === "document") {
31
+ event.respondWith(handleNavigation(request))
32
+ return
33
+ }
34
+
35
+ if (["script", "style", "font", "image"].includes(request.destination)) {
36
+ event.respondWith(handleAsset(request))
37
+ }
38
+ })
39
+
40
+ async function loadManifest(preferNetwork) {
41
+ const cache = await caches.open(MANIFEST_CACHE)
42
+
43
+ if (preferNetwork) {
44
+ try {
45
+ const response = await fetch(MANIFEST_URL, { cache: "no-store" })
46
+ if (response.ok) {
47
+ await cache.put(MANIFEST_URL, response.clone())
48
+ const manifest = await response.json()
49
+ cleanupOldCaches(manifest)
50
+ return manifest
51
+ }
52
+ } catch (_) {
53
+ // Fall back to the cached manifest below.
54
+ }
55
+ }
56
+
57
+ const cached = await cache.match(MANIFEST_URL)
58
+ if (cached) return cached.json()
59
+ return { buildId: "unknown", routes: [] }
60
+ }
61
+
62
+ async function cacheOfflineFallback() {
63
+ try {
64
+ const cache = await caches.open(`${CACHE_PREFIX}-fallback`)
65
+ const response = await fetch(OFFLINE_URL, { cache: "no-store" })
66
+ if (response.ok) await cache.put(OFFLINE_URL, response)
67
+ } catch (_) {
68
+ // The offline fallback remains unavailable until a later successful install.
69
+ }
70
+ }
71
+
72
+ function routeCacheName(manifest) {
73
+ return `${CACHE_PREFIX}-routes-${manifest.buildId}`
74
+ }
75
+
76
+ function assetCacheName(manifest) {
77
+ return `${CACHE_PREFIX}-assets-${manifest.buildId}`
78
+ }
79
+
80
+ async function cleanupOldCaches(manifest) {
81
+ manifest = manifest || (await loadManifest(false))
82
+ if (!manifest.buildId || manifest.buildId === "unknown") return
83
+
84
+ const keep = new Set([
85
+ MANIFEST_CACHE,
86
+ `${CACHE_PREFIX}-fallback`,
87
+ routeCacheName(manifest),
88
+ assetCacheName(manifest),
89
+ ])
90
+ const cacheNames = await caches.keys()
91
+ await Promise.all(
92
+ cacheNames
93
+ .filter((name) => name.startsWith(CACHE_PREFIX) && !keep.has(name))
94
+ .map((name) => caches.delete(name))
95
+ )
96
+ }
97
+
98
+ function isOfflineRoute(url, manifest) {
99
+ const { pathname } = new URL(url)
100
+ return (manifest.routes || []).some((route) => {
101
+ try {
102
+ return new RegExp(route.regex).test(pathname)
103
+ } catch (_) {
104
+ return false
105
+ }
106
+ })
107
+ }
108
+
109
+ function canStore(response) {
110
+ return !!(response && (response.ok || response.type === "opaque"))
111
+ }
112
+
113
+ async function handleNavigation(request) {
114
+ const manifest = await loadManifest(true)
115
+ if (!isOfflineRoute(request.url, manifest)) return fetch(request)
116
+
117
+ const cache = await caches.open(routeCacheName(manifest))
118
+ try {
119
+ const response = await fetch(request)
120
+ const contentType = response.headers.get("content-type") || ""
121
+ if (canStore(response) && contentType.includes("text/html")) {
122
+ await cache.put(request.url, response.clone())
123
+ }
124
+ return response
125
+ } catch (_) {
126
+ const cached = await cache.match(request.url)
127
+ if (cached) return cached
128
+
129
+ const offlineResponse = await caches.match(OFFLINE_URL)
130
+ if (offlineResponse) return offlineResponse
131
+
132
+ return fetch(OFFLINE_URL)
133
+ }
134
+ }
135
+
136
+ async function handleAsset(request) {
137
+ const manifest = await loadManifest(false)
138
+ const cache = await caches.open(assetCacheName(manifest))
139
+ const cached = await cache.match(request)
140
+ if (cached) return cached
141
+
142
+ const response = await fetch(request)
143
+ if (canStore(response)) await cache.put(request, response.clone())
144
+ return response
145
+ }
@@ -1 +1,33 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.registerCatalystServiceWorker=registerCatalystServiceWorker;let registered=false;function isNativeWebView(){if(typeof window==="undefined")return false;return!!(window.NativeBridge||window.webkit?.messageHandlers?.NativeBridge);}function registerCatalystServiceWorker(){if(registered)return;if(typeof window==="undefined"||typeof navigator==="undefined")return;if(process.env.NODE_ENV!=="production")return;if(isNativeWebView())return;if(!("serviceWorker"in navigator))return;registered=true;const register=()=>{navigator.serviceWorker.register("/catalyst-sw.js",{scope:"/",updateViaCache:"none"}).catch(()=>{registered=false;});};if(document.readyState==="complete"){register();}else{window.addEventListener("load",register,{once:true});}}
1
+ let registered = false
2
+
3
+ function isNativeWebView() {
4
+ if (typeof window === "undefined") return false
5
+ return !!(window.NativeBridge || window.webkit?.messageHandlers?.NativeBridge)
6
+ }
7
+
8
+ export function registerCatalystServiceWorker() {
9
+ if (registered) return
10
+ if (typeof window === "undefined" || typeof navigator === "undefined") return
11
+ if (process.env.NODE_ENV !== "production") return
12
+ if (isNativeWebView()) return
13
+ if (!("serviceWorker" in navigator)) return
14
+
15
+ registered = true
16
+
17
+ const register = () => {
18
+ navigator.serviceWorker
19
+ .register("/catalyst-sw.js", {
20
+ scope: "/",
21
+ updateViaCache: "none",
22
+ })
23
+ .catch(() => {
24
+ registered = false
25
+ })
26
+ }
27
+
28
+ if (document.readyState === "complete") {
29
+ register()
30
+ } else {
31
+ window.addEventListener("load", register, { once: true })
32
+ }
33
+ }