@mochabug/adaptkit 0.14.6 → 1.0.0-beta.10

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 (70) hide show
  1. package/assets/build-client.js +107 -0
  2. package/assets/build.js +57 -0
  3. package/assets/configurator.App.tsx +123 -0
  4. package/assets/configurator.main.tsx +19 -0
  5. package/assets/configurator.ssg.tsx +31 -0
  6. package/assets/{configurator.ts → configurator_none.ts} +1 -1
  7. package/assets/configurator_react.tsx +38 -0
  8. package/assets/executor.App.tsx +103 -0
  9. package/assets/executor.main.tsx +19 -0
  10. package/assets/executor.ssg.tsx +31 -0
  11. package/assets/{executor_browser.ts → executor_browser_none.ts} +1 -1
  12. package/assets/executor_browser_react.tsx +51 -0
  13. package/assets/gitignore +3 -0
  14. package/assets/global.d.ts +7 -0
  15. package/assets/inject.js +15 -0
  16. package/assets/tsconf.json +9 -3
  17. package/bin/index.js +12 -3247
  18. package/bin/index.js.map +7 -0
  19. package/package.json +10 -22
  20. package/assets/rollup.config.ts +0 -40
  21. package/bin/add.d.ts +0 -3
  22. package/bin/add.d.ts.map +0 -1
  23. package/bin/genproto/buf/validate/validate.d.ts +0 -4657
  24. package/bin/genproto/buf/validate/validate.d.ts.map +0 -1
  25. package/bin/genproto/google/api/client.d.ts +0 -785
  26. package/bin/genproto/google/api/client.d.ts.map +0 -1
  27. package/bin/genproto/google/api/http.d.ts +0 -452
  28. package/bin/genproto/google/api/http.d.ts.map +0 -1
  29. package/bin/genproto/google/api/launch_stage.d.ts +0 -78
  30. package/bin/genproto/google/api/launch_stage.d.ts.map +0 -1
  31. package/bin/genproto/google/protobuf/descriptor.d.ts +0 -2337
  32. package/bin/genproto/google/protobuf/descriptor.d.ts.map +0 -1
  33. package/bin/genproto/google/protobuf/duration.d.ts +0 -113
  34. package/bin/genproto/google/protobuf/duration.d.ts.map +0 -1
  35. package/bin/genproto/google/protobuf/struct.d.ts +0 -185
  36. package/bin/genproto/google/protobuf/struct.d.ts.map +0 -1
  37. package/bin/genproto/google/protobuf/timestamp.d.ts +0 -156
  38. package/bin/genproto/google/protobuf/timestamp.d.ts.map +0 -1
  39. package/bin/genproto/mochabugapis/adapt/graph/exchange.d.ts +0 -50
  40. package/bin/genproto/mochabugapis/adapt/graph/exchange.d.ts.map +0 -1
  41. package/bin/genproto/mochabugapis/adapt/graph/jtd_schema.d.ts +0 -129
  42. package/bin/genproto/mochabugapis/adapt/graph/jtd_schema.d.ts.map +0 -1
  43. package/bin/genproto/mochabugapis/adapt/graph/receiver.d.ts +0 -46
  44. package/bin/genproto/mochabugapis/adapt/graph/receiver.d.ts.map +0 -1
  45. package/bin/genproto/mochabugapis/adapt/graph/signal_binding.d.ts +0 -93
  46. package/bin/genproto/mochabugapis/adapt/graph/signal_binding.d.ts.map +0 -1
  47. package/bin/genproto/mochabugapis/adapt/graph/signal_descriptor.d.ts +0 -56
  48. package/bin/genproto/mochabugapis/adapt/graph/signal_descriptor.d.ts.map +0 -1
  49. package/bin/genproto/mochabugapis/adapt/graph/transceiver.d.ts +0 -44
  50. package/bin/genproto/mochabugapis/adapt/graph/transceiver.d.ts.map +0 -1
  51. package/bin/genproto/mochabugapis/adapt/graph/transmitter.d.ts +0 -50
  52. package/bin/genproto/mochabugapis/adapt/graph/transmitter.d.ts.map +0 -1
  53. package/bin/genproto/mochabugapis/adapt/graph/vertex_config.d.ts +0 -68
  54. package/bin/genproto/mochabugapis/adapt/graph/vertex_config.d.ts.map +0 -1
  55. package/bin/genproto/mochabugapis/adapt/plugins/v1/plugins.client.d.ts +0 -46
  56. package/bin/genproto/mochabugapis/adapt/plugins/v1/plugins.client.d.ts.map +0 -1
  57. package/bin/genproto/mochabugapis/adapt/plugins/v1/plugins.d.ts +0 -840
  58. package/bin/genproto/mochabugapis/adapt/plugins/v1/plugins.d.ts.map +0 -1
  59. package/bin/index.d.ts +0 -2
  60. package/bin/index.d.ts.map +0 -1
  61. package/bin/init.d.ts +0 -2
  62. package/bin/init.d.ts.map +0 -1
  63. package/bin/oauth2.d.ts +0 -2
  64. package/bin/oauth2.d.ts.map +0 -1
  65. package/bin/publish.d.ts +0 -4
  66. package/bin/publish.d.ts.map +0 -1
  67. package/bin/utils.d.ts +0 -6
  68. package/bin/utils.d.ts.map +0 -1
  69. package/bin/vertices.d.ts +0 -3
  70. package/bin/vertices.d.ts.map +0 -1
@@ -0,0 +1,107 @@
1
+ import { build } from 'esbuild';
2
+ import { sync as glob } from 'glob';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+
6
+ if (!process.env.PLUGINS_CDN) {
7
+ console.error('PLUGINS_CDN is required');
8
+ process.exit(1);
9
+ }
10
+
11
+ // Load the manifest.json file and read organization, name and version of the plugin
12
+ const manifest = JSON.parse(fs.readFileSync('./manifest.json', 'utf8'));
13
+ if (!manifest.organization || !manifest.name || !manifest.version) {
14
+ throw new Error('Manifest file is missing organization, name or version');
15
+ }
16
+ const CDN_PATH = `${process.env.PLUGINS_CDN}/${manifest.organization}/${manifest.name}/${manifest.version}`;
17
+
18
+ fs.rmSync('./cdn', { recursive: true });
19
+
20
+ // Build the client and place all the assets onto the corresponding CDN for the plugin
21
+ const loader = {
22
+ '.css': 'css',
23
+ '.woff': 'file',
24
+ '.woff2': 'file',
25
+ '.png': 'file',
26
+ '.jpg': 'file',
27
+ '.jpeg': 'file',
28
+ '.gif': 'file',
29
+ '.svg': 'file',
30
+ '.ttf': 'file',
31
+ '.otf': 'file',
32
+ };
33
+ const result = await build({
34
+ entryPoints: glob('./src/vertices/**/ui/*.main.tsx'),
35
+ outdir: 'cdn',
36
+ bundle: true,
37
+ minify: true,
38
+ platform: 'browser',
39
+ splitting: true,
40
+ tsconfig: 'tsconfig.json',
41
+ format: 'esm',
42
+ metafile: true,
43
+ publicPath: CDN_PATH,
44
+ loader,
45
+ });
46
+
47
+ const entrypoints = {
48
+ configurators: {},
49
+ executors: {},
50
+ vertices: [],
51
+ };
52
+ for (const [outputPath, outputMeta] of Object.entries(result.metafile.outputs)) {
53
+ if (!outputMeta.entryPoint) {
54
+ continue;
55
+ }
56
+ let vertex = path.dirname(path.dirname(path.relative('./src/vertices', outputMeta.entryPoint)));
57
+ if (entrypoints.vertices.findIndex((v) => v === vertex) === -1 && manifest.vertices.find((v) => v.name === vertex)) {
58
+ entrypoints.vertices.push(vertex);
59
+ }
60
+ if (outputMeta.entryPoint.endsWith('executor.main.tsx')) {
61
+ entrypoints.executors[vertex] = { js: `${CDN_PATH}/${outputPath.substring(4)}` };
62
+ if (outputMeta.cssBundle) {
63
+ entrypoints.executors[vertex].css = `${CDN_PATH}/${outputMeta.cssBundle.substring(4)}`;
64
+ }
65
+ } else if (outputMeta.entryPoint.endsWith('configurator.main.tsx')) {
66
+ entrypoints.configurators[vertex] = { js: `${CDN_PATH}/${outputPath.substring(4)}` };
67
+ if (outputMeta.cssBundle) {
68
+ entrypoints.configurators[vertex].css = `${CDN_PATH}/${outputMeta.cssBundle.substring(4)}`;
69
+ }
70
+ }
71
+ }
72
+
73
+ // Build the static site, make sure that we have the CDN as the public path for the assets
74
+ await build({
75
+ entryPoints: glob('./src/vertices/**/*.ssg.tsx'),
76
+ outdir: 'dist',
77
+ tsconfig: 'tsconfig.json',
78
+ bundle: true,
79
+ platform: 'node',
80
+ format: 'cjs',
81
+ target: 'esnext',
82
+ publicPath: CDN_PATH,
83
+ loader,
84
+ outExtension: {
85
+ '.js': '.cjs',
86
+ },
87
+ });
88
+
89
+ const configIndices = {};
90
+ for (const file of glob('./dist/**/configurator.ssg.cjs')) {
91
+ const { default: render } = await import(`file://${path.resolve(file)}`);
92
+ const vertex = entrypoints.vertices.length === 1 ? entrypoints.vertices[0] : path.dirname(path.dirname(path.relative('./dist', file)));
93
+ const entrypoint = entrypoints.configurators[vertex];
94
+ if (entrypoint) {
95
+ configIndices[vertex] = render.default(entrypoint.js, entrypoint.css);
96
+ }
97
+ }
98
+ fs.writeFileSync('./dist/configurator-index-html.json', JSON.stringify(configIndices));
99
+ const execIndices = {};
100
+ for (const file of glob('./dist/**/executor.ssg.cjs')) {
101
+ const { default: render } = await import(`file://${path.resolve(file)}`);
102
+ const vertex = entrypoints.vertices.length === 1 ? entrypoints.vertices[0] : path.dirname(path.dirname(path.relative('./dist', file)));
103
+
104
+ const entrypoint = entrypoints.executors[vertex];
105
+ execIndices[vertex] = render.default(entrypoint.js, entrypoint.css);
106
+ }
107
+ fs.writeFileSync('./dist/executor-index-html.json', JSON.stringify(execIndices));
@@ -0,0 +1,57 @@
1
+ import { cloudflare } from "@cloudflare/unenv-preset";
2
+ import { build } from 'esbuild';
3
+ import fs from 'node:fs';
4
+ import { defineEnv } from 'unenv';
5
+
6
+ if (!process.env.PLUGINS_CDN) {
7
+ console.error('PLUGINS_CDN is required');
8
+ process.exit(1);
9
+ }
10
+
11
+ // Load the manifest.json file and read organization, name and version of the plugin
12
+ const manifest = JSON.parse(fs.readFileSync('./manifest.json', 'utf8'));
13
+ if (!manifest.organization || !manifest.name || !manifest.version) {
14
+ throw new Error('Manifest file is missing organization, name or version');
15
+ }
16
+ const CDN_PATH = `${process.env.PLUGINS_CDN}/${manifest.organization}/${manifest.name}/${manifest.version}`;
17
+
18
+ const { env } = defineEnv({ nodeCompat: true, presets: [cloudflare] });
19
+
20
+ const entryPoints = ['./src/executors']
21
+ if (fs.existsSync('./src/configurators.ts')) {
22
+ entryPoints.push('./src/configurators')
23
+ }
24
+
25
+ // Set up the defines, this will automatically load ssg index.html files if they exists
26
+ const define = {
27
+ PLUGINS_CDN: JSON.stringify(CDN_PATH)
28
+ };
29
+ if (fs.existsSync('./dist/configurator-index-html.json')) {
30
+ const CONFIGURATOR_INDEX_HTML = fs.readFileSync('./dist/configurator-index-html.json', 'utf8');
31
+ define.CONFIGURATOR_INDEX_HTML = CONFIGURATOR_INDEX_HTML;
32
+ }
33
+ if (fs.existsSync('./dist/executor-index-html.json')) {
34
+ const EXECUTOR_INDEX_HTML = fs.readFileSync('./dist/executor-index-html.json', 'utf8');
35
+ define.EXECUTOR_INDEX_HTML = EXECUTOR_INDEX_HTML;
36
+ }
37
+
38
+ await build({
39
+ entryPoints,
40
+ outdir: 'dist',
41
+ bundle: true,
42
+ minify: true,
43
+ treeShaking: true,
44
+ sourcemap: false,
45
+ splitting: false,
46
+ format: 'esm',
47
+ platform: 'node',
48
+ target: 'esnext',
49
+ tsconfig: 'tsconfig.json',
50
+ inject: ['./inject.js'],
51
+ mainFields: ["module", "main"],
52
+ conditions: ["workerd"],
53
+ external: env.external,
54
+ alias: env.alias,
55
+ publicPath: CDN_PATH,
56
+ define,
57
+ });
@@ -0,0 +1,123 @@
1
+ import React, { useState, type CSSProperties } from 'react';
2
+
3
+ function App() {
4
+ const [config, setConfig] = useState<Record<string, unknown> | null>(null);
5
+ const [error, setError] = useState<string | null>(null);
6
+ const [isHovering, setIsHovering] = useState(false);
7
+
8
+ async function handleFetchConfig() {
9
+ setError(null);
10
+ try {
11
+ const hash = window.location.hash.substring(1).trim();
12
+ const token = decodeURIComponent(hash);
13
+ const response = await fetch('/api/config', {
14
+ headers: {
15
+ Authorization: `Bearer ${token}`,
16
+ },
17
+ });
18
+ if (!response.ok) {
19
+ throw new Error(`Request failed with status ${response.status}`);
20
+ }
21
+ const data = (await response.json()) as Record<string, unknown>;
22
+ setConfig(data);
23
+ } catch (err: unknown) {
24
+ if (err instanceof Error) {
25
+ setError(err.message);
26
+ } else {
27
+ setError('An unknown error occurred.');
28
+ }
29
+ }
30
+ }
31
+
32
+ // Black & yellow theme
33
+ const containerStyle: CSSProperties = {
34
+ display: 'flex',
35
+ flexDirection: 'column',
36
+ justifyContent: 'center',
37
+ alignItems: 'center',
38
+ height: '100vh',
39
+ margin: 0,
40
+ background: 'linear-gradient(to bottom, #000000, #1c1c1c)',
41
+ fontFamily: 'Arial, Helvetica, sans-serif',
42
+ color: '#ffd700',
43
+ };
44
+
45
+ const cardStyle: CSSProperties = {
46
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
47
+ padding: '2rem',
48
+ borderRadius: '8px',
49
+ textAlign: 'center',
50
+ boxShadow: '0 4px 20px rgba(0, 0, 0, 0.7)',
51
+ maxWidth: '600px',
52
+ width: '90%',
53
+ border: '2px solid #ffd700',
54
+ };
55
+
56
+ const headingStyle: CSSProperties = {
57
+ marginBottom: '1rem',
58
+ textShadow: '0 0 6px rgba(255, 215, 0, 0.5)',
59
+ fontSize: '2rem',
60
+ };
61
+
62
+ const buttonStyle: CSSProperties = {
63
+ cursor: 'pointer',
64
+ marginTop: '1rem',
65
+ padding: '0.75rem 1.5rem',
66
+ fontSize: '1rem',
67
+ borderRadius: '4px',
68
+ border: '2px solid #ffd700',
69
+ backgroundColor: '#000',
70
+ color: '#ffd700',
71
+ transition: 'transform 0.3s, box-shadow 0.3s',
72
+ outline: 'none',
73
+ };
74
+
75
+ const buttonHoverStyle: CSSProperties = {
76
+ ...buttonStyle,
77
+ transform: 'scale(1.05)',
78
+ boxShadow: '0 4px 10px rgba(255, 215, 0, 0.4)',
79
+ };
80
+
81
+ return (
82
+ <div style={containerStyle}>
83
+ <h1 style={headingStyle}>Spectacular Mochabug Placeholder</h1>
84
+ <div style={cardStyle}>
85
+ <p style={{ marginBottom: '1rem' }}>
86
+ Click the button below to fetch configuration data!
87
+ </p>
88
+ <button
89
+ style={isHovering ? buttonHoverStyle : buttonStyle}
90
+ onMouseEnter={() => setIsHovering(true)}
91
+ onMouseLeave={() => setIsHovering(false)}
92
+ onClick={handleFetchConfig}
93
+ >
94
+ Fetch Config
95
+ </button>
96
+
97
+ {error && (
98
+ <p style={{ color: '#ff4c4c', marginTop: '1rem' }}>
99
+ {error}
100
+ </p>
101
+ )}
102
+ {config && (
103
+ <pre
104
+ style={{
105
+ textAlign: 'left',
106
+ backgroundColor: 'rgba(255, 215, 0, 0.1)',
107
+ color: '#ffd700',
108
+ padding: '1rem',
109
+ borderRadius: '4px',
110
+ marginTop: '1rem',
111
+ overflowX: 'auto',
112
+ border: '1px solid #ffd700',
113
+ }}
114
+ >
115
+ {JSON.stringify(config, null, 2)}
116
+ </pre>
117
+ )}
118
+ </div>
119
+ </div>
120
+ );
121
+ }
122
+
123
+ export default App;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * This file serves as the main entry point for the React application. It uses
3
+ * `hydrateRoot` from `react-dom/client` to attach the React component tree, starting
4
+ * with the `<App />` component, to the DOM element with the ID of "root".
5
+ *
6
+ * When server-side rendering (SSR) or static site generation (SSG) is used,
7
+ * `hydrateRoot` reuses existing markup on the page, preserving performance and
8
+ * maintaining any server-rendered content. If you are not using SSR, you may see
9
+ * `createRoot` used in a similar manner instead.
10
+ *
11
+ * The `<App />` component is the root component of the application, where all
12
+ * child components are nested. This setup ensures that the React application is
13
+ * rendered and managed within the specified DOM node.
14
+ */
15
+ import React from 'react';
16
+ import { hydrateRoot } from 'react-dom/client';
17
+ import App from './configurator.App';
18
+
19
+ hydrateRoot(document.getElementById('root')!, <App />);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * This file demonstrates the generation of HTML from a React application on the server
3
+ * (or ahead of time). It exports a single function that takes a CDN base path as an
4
+ * argument and returns an HTML string. Within that HTML, the `<App>` component is
5
+ * rendered to a string via `renderToString` and injected into the `<div id="root">`.
6
+ *
7
+ * This approach can be used for server-side rendering (SSR) or static site generation
8
+ * (SSG). By pre-rendering the React component, you can improve performance and
9
+ * provide faster initial page loads.
10
+ */
11
+ import React from 'react';
12
+ import { renderToString } from 'react-dom/server';
13
+ import App from './configurator.App';
14
+
15
+ export default function (js: string, css?: string) {
16
+ return `
17
+ <!DOCTYPE html>
18
+ <html lang="en">
19
+ <head>
20
+ <meta charset="utf-8" />
21
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
22
+ <title>Title</title>
23
+ ${css ? `<link rel="stylesheet" href="${css}" />` : ''}
24
+ </head>
25
+ <body>
26
+ <div id="root">${renderToString(<App />)}</div>
27
+ <script type="module" src="${js}"></script>
28
+ </body>
29
+ </html>
30
+ `;
31
+ }
@@ -106,7 +106,7 @@ const helloWorldPage = `
106
106
  <pre id="jsonOutput"></pre>
107
107
  <script>
108
108
  document.getElementById('assimilateButton').addEventListener('click', function() {
109
- const hash = window.location.hash.substr(1).trim();
109
+ const hash = window.location.hash.substring(1).trim();
110
110
  const token = decodeURIComponent(hash);
111
111
  fetch('/api/config', {
112
112
  method: 'GET',
@@ -0,0 +1,38 @@
1
+ import {
2
+ mapErrorToHttpError,
3
+ RpcError
4
+ } from '@mochabug/adapt-plugin-toolkit/api';
5
+ import {
6
+ ExternalConfiguratorRouter,
7
+ InternalConfiguratorRouter
8
+ } from '@mochabug/adapt-plugin-toolkit/router';
9
+
10
+ export default {
11
+ external: new ExternalConfiguratorRouter()
12
+ .useRequestLogging()
13
+ .useBearerAuthorization(['/api'])
14
+ .useErrorHandling(async (e) => {
15
+ console.error(e);
16
+ if (e instanceof RpcError) {
17
+ return new Response(null, { status: mapErrorToHttpError(e.code) });
18
+ }
19
+ return new Response(null, {
20
+ status: 500,
21
+ statusText: 'Internal server error'
22
+ });
23
+ })
24
+ .add('GET', '/api/config', async (_req, api) => {
25
+ const res = await api.getVertexConfig();
26
+ return new Response(JSON.stringify(res.metadata), {
27
+ headers: {
28
+ 'Content-Type': 'application/json'
29
+ }
30
+ });
31
+ })
32
+ .add('GET', '{*any}', async () => {
33
+ return new Response(CONFIGURATOR_INDEX_HTML['___VERTEX_NAME___'], {
34
+ headers: { 'Content-Type': 'text/html' }
35
+ });
36
+ }),
37
+ internal: new InternalConfiguratorRouter()
38
+ };
@@ -0,0 +1,103 @@
1
+ import React, { useState, type CSSProperties } from 'react';
2
+
3
+ function App() {
4
+ const [error, setError] = useState<string | null>(null);
5
+ const [isHovering, setIsHovering] = useState(false);
6
+
7
+ async function handleFetchConfig() {
8
+ setError(null);
9
+ try {
10
+ const hash = window.location.hash.substring(1).trim();
11
+ const token = decodeURIComponent(hash);
12
+ const response = await fetch('/api/done', {
13
+ method: 'POST',
14
+ headers: {
15
+ Authorization: `Bearer ${token}`
16
+ }
17
+ });
18
+ if (!response.ok) {
19
+ throw new Error(`Request failed with status ${response.status}`);
20
+ }
21
+ } catch (err: unknown) {
22
+ if (err instanceof Error) {
23
+ setError(err.message);
24
+ } else {
25
+ setError('An unknown error occurred.');
26
+ }
27
+ }
28
+ }
29
+
30
+ // Black & yellow theme
31
+ const containerStyle: CSSProperties = {
32
+ display: 'flex',
33
+ flexDirection: 'column',
34
+ justifyContent: 'center',
35
+ alignItems: 'center',
36
+ height: '100vh',
37
+ margin: 0,
38
+ background: 'linear-gradient(to bottom, #000000, #1c1c1c)',
39
+ fontFamily: 'Arial, Helvetica, sans-serif',
40
+ color: '#ffd700'
41
+ };
42
+
43
+ const cardStyle: CSSProperties = {
44
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
45
+ padding: '2rem',
46
+ borderRadius: '8px',
47
+ textAlign: 'center',
48
+ boxShadow: '0 4px 20px rgba(0, 0, 0, 0.7)',
49
+ maxWidth: '600px',
50
+ width: '90%',
51
+ border: '2px solid #ffd700'
52
+ };
53
+
54
+ const headingStyle: CSSProperties = {
55
+ marginBottom: '1rem',
56
+ textShadow: '0 0 6px rgba(255, 215, 0, 0.5)',
57
+ fontSize: '2rem'
58
+ };
59
+
60
+ const buttonStyle: CSSProperties = {
61
+ cursor: 'pointer',
62
+ marginTop: '1rem',
63
+ padding: '0.75rem 1.5rem',
64
+ fontSize: '1rem',
65
+ borderRadius: '4px',
66
+ border: '2px solid #ffd700',
67
+ backgroundColor: '#000',
68
+ color: '#ffd700',
69
+ transition: 'transform 0.3s, box-shadow 0.3s',
70
+ outline: 'none'
71
+ };
72
+
73
+ const buttonHoverStyle: CSSProperties = {
74
+ ...buttonStyle,
75
+ transform: 'scale(1.05)',
76
+ boxShadow: '0 4px 10px rgba(255, 215, 0, 0.4)'
77
+ };
78
+
79
+ return (
80
+ <div style={containerStyle}>
81
+ <h1 style={headingStyle}>Spectacular Mochabug Placeholder</h1>
82
+ <div style={cardStyle}>
83
+ <p style={{ marginBottom: '1rem' }}>
84
+ Click below to finalize execution
85
+ </p>
86
+ <button
87
+ style={isHovering ? buttonHoverStyle : buttonStyle}
88
+ onMouseEnter={() => setIsHovering(true)}
89
+ onMouseLeave={() => setIsHovering(false)}
90
+ onClick={handleFetchConfig}
91
+ >
92
+ Done
93
+ </button>
94
+
95
+ {error && (
96
+ <p style={{ color: '#ff4c4c', marginTop: '1rem' }}>{error}</p>
97
+ )}
98
+ </div>
99
+ </div>
100
+ );
101
+ }
102
+
103
+ export default App;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * This file serves as the main entry point for the React application. It uses
3
+ * `hydrateRoot` from `react-dom/client` to attach the React component tree, starting
4
+ * with the `<App />` component, to the DOM element with the ID of "root".
5
+ *
6
+ * When server-side rendering (SSR) or static site generation (SSG) is used,
7
+ * `hydrateRoot` reuses existing markup on the page, preserving performance and
8
+ * maintaining any server-rendered content. If you are not using SSR, you may see
9
+ * `createRoot` used in a similar manner instead.
10
+ *
11
+ * The `<App />` component is the root component of the application, where all
12
+ * child components are nested. This setup ensures that the React application is
13
+ * rendered and managed within the specified DOM node.
14
+ */
15
+ import React from 'react';
16
+ import { hydrateRoot } from 'react-dom/client';
17
+ import App from './executor.App';
18
+
19
+ hydrateRoot(document.getElementById('root')!, <App />);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * This file demonstrates the generation of HTML from a React application on the server
3
+ * (or ahead of time). It exports a single function that takes a CDN base path as an
4
+ * argument and returns an HTML string. Within that HTML, the `<App>` component is
5
+ * rendered to a string via `renderToString` and injected into the `<div id="root">`.
6
+ *
7
+ * This approach can be used for server-side rendering (SSR) or static site generation
8
+ * (SSG). By pre-rendering the React component, you can improve performance and
9
+ * provide faster initial page loads.
10
+ */
11
+ import React from 'react';
12
+ import { renderToString } from 'react-dom/server';
13
+ import App from './executor.App';
14
+
15
+ export default function (js: string, css?: string) {
16
+ return `
17
+ <!DOCTYPE html>
18
+ <html lang="en">
19
+ <head>
20
+ <meta charset="utf-8" />
21
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
22
+ <title>Title</title>
23
+ ${css ? `<link rel="stylesheet" href="${css}" />` : ''}
24
+ </head>
25
+ <body>
26
+ <div id="root">${renderToString(<App />)}</div>
27
+ <script type="module" src="${js}"></script>
28
+ </body>
29
+ </html>
30
+ `;
31
+ }
@@ -97,7 +97,7 @@ const helloWorld = `
97
97
  <button id="doneButton">Done</button>
98
98
  <script>
99
99
  document.getElementById('doneButton').addEventListener('click', function() {
100
- const hash = window.location.hash.substr(1).trim();
100
+ const hash = window.location.hash.substring(1).trim();
101
101
  const token = decodeURIComponent(hash);
102
102
  fetch('/api/done', {
103
103
  method: 'POST',
@@ -0,0 +1,51 @@
1
+ import {
2
+ mapErrorToHttpError,
3
+ RpcError
4
+ } from '@mochabug/adapt-plugin-toolkit/api';
5
+ import {
6
+ ExternalExecutorRouter,
7
+ InternalExecutorRouter
8
+ } from '@mochabug/adapt-plugin-toolkit/router';
9
+
10
+ export default {
11
+ external: new ExternalExecutorRouter()
12
+ .useRequestLogging()
13
+ .useBearerAuthorization(['/api'])
14
+ .useErrorHandling(async (e) => {
15
+ console.error(e);
16
+ if (e instanceof RpcError) {
17
+ return new Response(null, { status: mapErrorToHttpError(e.code) });
18
+ }
19
+ return new Response(null, {
20
+ status: 500,
21
+ statusText: 'Internal server error'
22
+ });
23
+ })
24
+ .add('POST', '/api/done', async (req, api, _route, ctx) => {
25
+ const sapi = api.getSessionApi(req.headers.get('Authorization')!);
26
+ ctx.waitUntil(sapi.complete('output', {}));
27
+ return new Response();
28
+ })
29
+ .add('GET', '{*any}', async () => {
30
+ return new Response(EXECUTOR_INDEX_HTML['___VERTEX_NAME___'], {
31
+ headers: { 'Content-Type': 'text/html' }
32
+ });
33
+ }),
34
+ internal: new InternalExecutorRouter()
35
+ .onStart(async (start, _api) => {
36
+ console.log('Start has been called');
37
+ console.log(start);
38
+ })
39
+ .onStop(async (stop, _api) => {
40
+ console.log('Stop has been called');
41
+ console.log(stop);
42
+ })
43
+ .onStream(async (res, _api, name) => {
44
+ console.log(`Stream ${name} has been called`);
45
+ console.log(res);
46
+ })
47
+ .onProcedure(async (res, _api, name) => {
48
+ console.log(`Procedure ${name} has been called`);
49
+ console.log(res);
50
+ })
51
+ };
package/assets/gitignore CHANGED
@@ -1,3 +1,6 @@
1
+ # Cdn files
2
+ cdn/**
3
+
1
4
  # Logs
2
5
  logs
3
6
  *.log
@@ -0,0 +1,7 @@
1
+ declare global {
2
+ const PLUGINS_CDN: string;
3
+ const CONFIGURATOR_INDEX_HTML: Record<string, string>;
4
+ const EXECUTOR_INDEX_HTML: Record<string, string>;
5
+ }
6
+
7
+ export {};
@@ -0,0 +1,15 @@
1
+ import 'unenv/runtime/polyfill/node-global'
2
+ import 'unenv/runtime/polyfill/process'
3
+ import 'unenv/runtime/polyfill/performance'
4
+ import processModule from '@cloudflare/unenv-preset/runtime/node/process/index'
5
+ if (typeof globalThis.process === 'undefined') {
6
+ globalThis.process = processModule
7
+ }
8
+ import consoleModule from '@cloudflare/unenv-preset/runtime/node/console/index'
9
+ if (typeof globalThis.console === 'undefined') {
10
+ globalThis.console = consoleModule
11
+ }
12
+ import perfModule from 'unenv/runtime/polyfill/performance'
13
+ if (typeof globalThis.performance === 'undefined') {
14
+ globalThis.performance = perfModule
15
+ }
@@ -5,16 +5,19 @@
5
5
  "target": "esnext",
6
6
  "module": "esnext",
7
7
  "lib": [
8
- "esnext"
8
+ "esnext",
9
+ "dom"
9
10
  ],
10
11
  "moduleResolution": "Bundler",
11
12
  "types": [
13
+ "node",
12
14
  "@mochabug/adapt-plugin-typings"
13
15
  ],
14
16
  "resolveJsonModule": true,
15
17
  "allowJs": true,
16
18
  "checkJs": false,
17
19
  "noEmit": true,
20
+ "esModuleInterop": true,
18
21
  "isolatedModules": true,
19
22
  "allowSyntheticDefaultImports": true,
20
23
  "forceConsistentCasingInFileNames": true,
@@ -30,7 +33,10 @@
30
33
  },
31
34
  "exclude": [
32
35
  "dist/**",
36
+ "cdn/**",
33
37
  "assets/**",
34
- "rollup.config.js"
35
- ]
38
+ "build.js",
39
+ "inject.js",
40
+ "build-client.js"
41
+ ],
36
42
  }