@kapeta/local-cluster-service 0.67.5 → 0.68.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.68.0](https://github.com/kapetacom/local-cluster-service/compare/v0.67.5...v0.68.0) (2024-09-03)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add fallback page to ui server requests ([45bcf5d](https://github.com/kapetacom/local-cluster-service/commit/45bcf5d596ca359a9ddd63512b705ca840a555c8))
7
+
1
8
  ## [0.67.5](https://github.com/kapetacom/local-cluster-service/compare/v0.67.4...v0.67.5) (2024-09-02)
2
9
 
3
10
 
@@ -115,15 +115,101 @@ exports.readPageFromDiskAsString = readPageFromDiskAsString;
115
115
  function readPageFromDisk(systemId, path, method, res) {
116
116
  const filePath = resolveReadPath(systemId, path, method);
117
117
  if (!filePath || !fs_extra_1.default.existsSync(filePath)) {
118
- res.status(404).send('Page not found');
118
+ if (method === 'HEAD') {
119
+ // For HEAD requests, only return the status and headers
120
+ res.status(202).set('Retry-After', '3').end();
121
+ }
122
+ else {
123
+ // For GET requests, return the fallback HTML with status 202
124
+ res.status(202).set('Retry-After', '3').send(getFallbackHtml(path, method));
125
+ }
119
126
  return;
120
127
  }
121
128
  res.type(filePath.split('.').pop());
122
129
  const content = fs_extra_1.default.readFileSync(filePath);
123
- res.write(content);
124
- res.end();
130
+ if (method === 'HEAD') {
131
+ // For HEAD requests, just end the response after setting headers
132
+ res.status(200).end();
133
+ }
134
+ else {
135
+ // For GET requests, return the full content
136
+ res.write(content);
137
+ res.end();
138
+ }
125
139
  }
126
140
  exports.readPageFromDisk = readPageFromDisk;
141
+ function getFallbackHtml(path, method) {
142
+ return `
143
+ <!DOCTYPE html>
144
+ <html lang="en">
145
+
146
+ <head>
147
+ <meta charset="UTF-8">
148
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
149
+ <title>Page Not Ready</title>
150
+ <style>
151
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;600&display=swap');
152
+
153
+ body {
154
+ margin: 0;
155
+ padding: 0;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ height: 100vh;
160
+ font-family: 'Roboto', sans-serif;
161
+ background: #1E1F20;
162
+ color: white;
163
+ text-align: center;
164
+ }
165
+
166
+ h1 {
167
+ font-size: 2rem;
168
+ font-weight: 600;
169
+ margin-bottom: 1rem;
170
+ }
171
+
172
+ p {
173
+ font-size: 1rem;
174
+ font-weight: 400;
175
+ }
176
+ </style>
177
+ </head>
178
+
179
+ <body>
180
+ <div>
181
+ <h1>Page Not Ready</h1>
182
+ <p>Henrik is still working on this page. Please wait...</p>
183
+ </div>
184
+ <script>
185
+ const checkInterval = 3000;
186
+ function checkPageReady() {
187
+ fetch('${path}', { method: 'HEAD' })
188
+ .then(response => {
189
+ if (response.status === 200) {
190
+ // The page is ready, reload to fetch it
191
+ window.location.reload();
192
+ } else if (response.status === 202) {
193
+ const retryAfter = response.headers.get('Retry-After');
194
+ const retryInterval = retryAfter ? parseInt(retryAfter) * 1000 : 3000;
195
+ setTimeout(checkPageReady, retryInterval);
196
+ } else {
197
+ // Handle other unexpected statuses
198
+ setTimeout(checkPageReady, 3000);
199
+ }
200
+ })
201
+ .catch(error => {
202
+ console.error('Error checking page status:', error);
203
+ setTimeout(checkPageReady, checkInterval);
204
+ });
205
+ }
206
+ setTimeout(checkPageReady, checkInterval);
207
+ </script>
208
+ </body>
209
+
210
+ </html>
211
+ `;
212
+ }
127
213
  function readConversationFromFile(filename) {
128
214
  if (!fs_extra_1.default.existsSync(filename)) {
129
215
  return [];
@@ -115,15 +115,101 @@ exports.readPageFromDiskAsString = readPageFromDiskAsString;
115
115
  function readPageFromDisk(systemId, path, method, res) {
116
116
  const filePath = resolveReadPath(systemId, path, method);
117
117
  if (!filePath || !fs_extra_1.default.existsSync(filePath)) {
118
- res.status(404).send('Page not found');
118
+ if (method === 'HEAD') {
119
+ // For HEAD requests, only return the status and headers
120
+ res.status(202).set('Retry-After', '3').end();
121
+ }
122
+ else {
123
+ // For GET requests, return the fallback HTML with status 202
124
+ res.status(202).set('Retry-After', '3').send(getFallbackHtml(path, method));
125
+ }
119
126
  return;
120
127
  }
121
128
  res.type(filePath.split('.').pop());
122
129
  const content = fs_extra_1.default.readFileSync(filePath);
123
- res.write(content);
124
- res.end();
130
+ if (method === 'HEAD') {
131
+ // For HEAD requests, just end the response after setting headers
132
+ res.status(200).end();
133
+ }
134
+ else {
135
+ // For GET requests, return the full content
136
+ res.write(content);
137
+ res.end();
138
+ }
125
139
  }
126
140
  exports.readPageFromDisk = readPageFromDisk;
141
+ function getFallbackHtml(path, method) {
142
+ return `
143
+ <!DOCTYPE html>
144
+ <html lang="en">
145
+
146
+ <head>
147
+ <meta charset="UTF-8">
148
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
149
+ <title>Page Not Ready</title>
150
+ <style>
151
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;600&display=swap');
152
+
153
+ body {
154
+ margin: 0;
155
+ padding: 0;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ height: 100vh;
160
+ font-family: 'Roboto', sans-serif;
161
+ background: #1E1F20;
162
+ color: white;
163
+ text-align: center;
164
+ }
165
+
166
+ h1 {
167
+ font-size: 2rem;
168
+ font-weight: 600;
169
+ margin-bottom: 1rem;
170
+ }
171
+
172
+ p {
173
+ font-size: 1rem;
174
+ font-weight: 400;
175
+ }
176
+ </style>
177
+ </head>
178
+
179
+ <body>
180
+ <div>
181
+ <h1>Page Not Ready</h1>
182
+ <p>Henrik is still working on this page. Please wait...</p>
183
+ </div>
184
+ <script>
185
+ const checkInterval = 3000;
186
+ function checkPageReady() {
187
+ fetch('${path}', { method: 'HEAD' })
188
+ .then(response => {
189
+ if (response.status === 200) {
190
+ // The page is ready, reload to fetch it
191
+ window.location.reload();
192
+ } else if (response.status === 202) {
193
+ const retryAfter = response.headers.get('Retry-After');
194
+ const retryInterval = retryAfter ? parseInt(retryAfter) * 1000 : 3000;
195
+ setTimeout(checkPageReady, retryInterval);
196
+ } else {
197
+ // Handle other unexpected statuses
198
+ setTimeout(checkPageReady, 3000);
199
+ }
200
+ })
201
+ .catch(error => {
202
+ console.error('Error checking page status:', error);
203
+ setTimeout(checkPageReady, checkInterval);
204
+ });
205
+ }
206
+ setTimeout(checkPageReady, checkInterval);
207
+ </script>
208
+ </body>
209
+
210
+ </html>
211
+ `;
212
+ }
127
213
  function readConversationFromFile(filename) {
128
214
  if (!fs_extra_1.default.existsSync(filename)) {
129
215
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.67.5",
3
+ "version": "0.68.0",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -144,15 +144,101 @@ export function readPageFromDiskAsString(systemId: string, path: string, method:
144
144
  export function readPageFromDisk(systemId: string, path: string, method: string, res: Response) {
145
145
  const filePath = resolveReadPath(systemId, path, method);
146
146
  if (!filePath || !FS.existsSync(filePath)) {
147
- res.status(404).send('Page not found');
147
+ if (method === 'HEAD') {
148
+ // For HEAD requests, only return the status and headers
149
+ res.status(202).set('Retry-After', '3').end();
150
+ } else {
151
+ // For GET requests, return the fallback HTML with status 202
152
+ res.status(202).set('Retry-After', '3').send(getFallbackHtml(path, method));
153
+ }
148
154
  return;
149
155
  }
150
156
 
151
157
  res.type(filePath.split('.').pop() as string);
152
158
 
153
159
  const content = FS.readFileSync(filePath);
154
- res.write(content);
155
- res.end();
160
+
161
+ if (method === 'HEAD') {
162
+ // For HEAD requests, just end the response after setting headers
163
+ res.status(200).end();
164
+ } else {
165
+ // For GET requests, return the full content
166
+ res.write(content);
167
+ res.end();
168
+ }
169
+ }
170
+
171
+ function getFallbackHtml(path: string, method: string): string {
172
+ return `
173
+ <!DOCTYPE html>
174
+ <html lang="en">
175
+
176
+ <head>
177
+ <meta charset="UTF-8">
178
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
179
+ <title>Page Not Ready</title>
180
+ <style>
181
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;600&display=swap');
182
+
183
+ body {
184
+ margin: 0;
185
+ padding: 0;
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ height: 100vh;
190
+ font-family: 'Roboto', sans-serif;
191
+ background: #1E1F20;
192
+ color: white;
193
+ text-align: center;
194
+ }
195
+
196
+ h1 {
197
+ font-size: 2rem;
198
+ font-weight: 600;
199
+ margin-bottom: 1rem;
200
+ }
201
+
202
+ p {
203
+ font-size: 1rem;
204
+ font-weight: 400;
205
+ }
206
+ </style>
207
+ </head>
208
+
209
+ <body>
210
+ <div>
211
+ <h1>Page Not Ready</h1>
212
+ <p>Henrik is still working on this page. Please wait...</p>
213
+ </div>
214
+ <script>
215
+ const checkInterval = 3000;
216
+ function checkPageReady() {
217
+ fetch('${path}', { method: 'HEAD' })
218
+ .then(response => {
219
+ if (response.status === 200) {
220
+ // The page is ready, reload to fetch it
221
+ window.location.reload();
222
+ } else if (response.status === 202) {
223
+ const retryAfter = response.headers.get('Retry-After');
224
+ const retryInterval = retryAfter ? parseInt(retryAfter) * 1000 : 3000;
225
+ setTimeout(checkPageReady, retryInterval);
226
+ } else {
227
+ // Handle other unexpected statuses
228
+ setTimeout(checkPageReady, 3000);
229
+ }
230
+ })
231
+ .catch(error => {
232
+ console.error('Error checking page status:', error);
233
+ setTimeout(checkPageReady, checkInterval);
234
+ });
235
+ }
236
+ setTimeout(checkPageReady, checkInterval);
237
+ </script>
238
+ </body>
239
+
240
+ </html>
241
+ `;
156
242
  }
157
243
 
158
244
  export interface Conversation {