proteum 2.1.0 → 2.1.2
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/AGENTS.md +44 -98
- package/README.md +143 -10
- package/agents/framework/AGENTS.md +146 -886
- package/agents/project/AGENTS.md +73 -127
- package/agents/project/client/AGENTS.md +22 -93
- package/agents/project/client/pages/AGENTS.md +24 -26
- package/agents/project/server/routes/AGENTS.md +10 -8
- package/agents/project/server/services/AGENTS.md +22 -159
- package/agents/project/tests/AGENTS.md +11 -8
- package/cli/app/config.ts +7 -20
- package/cli/bin.js +8 -0
- package/cli/commands/command.ts +243 -0
- package/cli/commands/commandLocalRunner.js +198 -0
- package/cli/commands/create.ts +5 -0
- package/cli/commands/deploy/web.ts +1 -2
- package/cli/commands/dev.ts +98 -2
- package/cli/commands/doctor.ts +8 -74
- package/cli/commands/explain.ts +8 -186
- package/cli/commands/init.ts +2 -94
- package/cli/commands/trace.ts +228 -0
- package/cli/compiler/artifacts/commands.ts +217 -0
- package/cli/compiler/artifacts/manifest.ts +35 -21
- package/cli/compiler/artifacts/services.ts +300 -1
- package/cli/compiler/client/index.ts +43 -8
- package/cli/compiler/common/commands.ts +175 -0
- package/cli/compiler/common/index.ts +1 -1
- package/cli/compiler/common/proteumManifest.ts +15 -114
- package/cli/compiler/index.ts +25 -2
- package/cli/compiler/server/index.ts +31 -6
- package/cli/index.ts +1 -4
- package/cli/paths.ts +16 -1
- package/cli/presentation/commands.ts +104 -14
- package/cli/presentation/devSession.ts +22 -3
- package/cli/presentation/proteum_logo_400x400_square_icon.txt +400 -0
- package/cli/runtime/commands.ts +121 -4
- package/cli/scaffold/index.ts +720 -0
- package/cli/scaffold/templates.ts +344 -0
- package/cli/scaffold/types.ts +26 -0
- package/cli/tsconfig.json +4 -1
- package/cli/utils/check.ts +1 -1
- package/client/app/component.tsx +13 -9
- package/client/dev/profiler/index.tsx +2511 -0
- package/client/dev/profiler/noop.tsx +5 -0
- package/client/dev/profiler/runtime.noop.ts +116 -0
- package/client/dev/profiler/runtime.ts +840 -0
- package/client/services/router/components/router.tsx +30 -2
- package/client/services/router/index.tsx +27 -3
- package/client/services/router/request/api.ts +133 -17
- package/commands/proteum/diagnostics.ts +11 -0
- package/common/dev/commands.ts +50 -0
- package/common/dev/diagnostics.ts +298 -0
- package/common/dev/profiler.ts +92 -0
- package/common/dev/proteumManifest.ts +135 -0
- package/common/dev/requestTrace.ts +115 -0
- package/common/env/proteumEnv.ts +284 -0
- package/common/router/index.ts +4 -22
- package/docs/dev-commands.md +93 -0
- package/docs/diagnostics.md +88 -0
- package/docs/request-tracing.md +132 -0
- package/eslint.js +11 -6
- package/package.json +3 -3
- package/server/app/commands.ts +35 -370
- package/server/app/commandsManager.ts +393 -0
- package/server/app/container/config.ts +11 -49
- package/server/app/container/console/index.ts +2 -3
- package/server/app/container/index.ts +5 -2
- package/server/app/container/trace/index.ts +364 -0
- package/server/app/devCommands.ts +192 -0
- package/server/app/devDiagnostics.ts +53 -0
- package/server/app/index.ts +29 -6
- package/server/index.ts +0 -1
- package/server/services/auth/index.ts +525 -61
- package/server/services/auth/router/index.ts +106 -7
- package/server/services/cron/CronTask.ts +73 -5
- package/server/services/cron/index.ts +34 -11
- package/server/services/fetch/index.ts +3 -10
- package/server/services/prisma/index.ts +66 -4
- package/server/services/router/http/index.ts +173 -6
- package/server/services/router/index.ts +200 -12
- package/server/services/router/request/api.ts +30 -1
- package/server/services/router/response/index.ts +83 -10
- package/server/services/router/response/page/document.tsx +16 -0
- package/server/services/router/response/page/index.tsx +27 -1
- package/skills/clean-project-code/SKILL.md +7 -2
- package/test-results/.last-run.json +4 -0
- package/types/aliases.d.ts +6 -0
- package/types/global/utils.d.ts +7 -14
- package/Rte.zip +0 -0
- package/agents/project/agents.md.zip +0 -0
- package/doc/TODO.md +0 -71
- package/doc/front/router.md +0 -27
- package/doc/workspace/workspace.png +0 -0
- package/doc/workspace/workspace2.png +0 -0
- package/doc/workspace/workspace_26.01.22.png +0 -0
- package/server/services/router/http/session.ts.old +0 -40
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import type { TScaffoldInitConfig, TScaffoldResult } from './types';
|
|
2
|
+
|
|
3
|
+
const renderJson = (value: unknown) => JSON.stringify(value, null, 4);
|
|
4
|
+
|
|
5
|
+
export const createPageTemplate = ({
|
|
6
|
+
routePath,
|
|
7
|
+
heading,
|
|
8
|
+
message,
|
|
9
|
+
}: {
|
|
10
|
+
routePath: string;
|
|
11
|
+
heading: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}) => `import Router from '@/client/router';
|
|
14
|
+
|
|
15
|
+
Router.page(
|
|
16
|
+
${JSON.stringify(routePath)},
|
|
17
|
+
() => ({
|
|
18
|
+
_auth: false,
|
|
19
|
+
_layout: false,
|
|
20
|
+
heading: ${JSON.stringify(heading)},
|
|
21
|
+
message: ${JSON.stringify(message)},
|
|
22
|
+
}),
|
|
23
|
+
({ heading, message }) => {
|
|
24
|
+
return (
|
|
25
|
+
<main>
|
|
26
|
+
<h1>{heading}</h1>
|
|
27
|
+
<p>{message}</p>
|
|
28
|
+
</main>
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
export const createControllerTemplate = ({
|
|
35
|
+
appIdentifier,
|
|
36
|
+
className,
|
|
37
|
+
methodName,
|
|
38
|
+
}: {
|
|
39
|
+
appIdentifier: string;
|
|
40
|
+
className: string;
|
|
41
|
+
methodName: string;
|
|
42
|
+
}) => `import Controller from '@server/app/controller';
|
|
43
|
+
|
|
44
|
+
export default class ${className} extends Controller<${appIdentifier}> {
|
|
45
|
+
public async ${methodName}() {
|
|
46
|
+
return {
|
|
47
|
+
ok: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
export const createCommandTemplate = ({
|
|
54
|
+
className,
|
|
55
|
+
methodName,
|
|
56
|
+
}: {
|
|
57
|
+
className: string;
|
|
58
|
+
methodName: string;
|
|
59
|
+
}) => `import { Commands } from '@server/app/commands';
|
|
60
|
+
import type App from '@/server/index';
|
|
61
|
+
|
|
62
|
+
export default class ${className} extends Commands<App> {
|
|
63
|
+
public async ${methodName}() {
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
app: this.app.identity.identifier,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
export const createRouteTemplate = ({
|
|
73
|
+
httpMethod,
|
|
74
|
+
routePath,
|
|
75
|
+
}: {
|
|
76
|
+
httpMethod: string;
|
|
77
|
+
routePath: string;
|
|
78
|
+
}) => `import { Router } from '@app';
|
|
79
|
+
|
|
80
|
+
Router.${httpMethod}(${JSON.stringify(routePath)}, {}, async () => {
|
|
81
|
+
return {
|
|
82
|
+
ok: true,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
export const createServiceTemplate = ({
|
|
88
|
+
appIdentifier,
|
|
89
|
+
className,
|
|
90
|
+
}: {
|
|
91
|
+
appIdentifier: string;
|
|
92
|
+
className: string;
|
|
93
|
+
}) => `import Service from '@server/app/service';
|
|
94
|
+
|
|
95
|
+
export type Config = {
|
|
96
|
+
debug?: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export default class ${className} extends Service<Config, {}, ${appIdentifier}, ${appIdentifier}> {
|
|
100
|
+
public async health() {
|
|
101
|
+
return {
|
|
102
|
+
ok: true,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
export const createServiceConfigTemplate = ({
|
|
109
|
+
configExportName,
|
|
110
|
+
serviceImportPath,
|
|
111
|
+
serviceImportName,
|
|
112
|
+
}: {
|
|
113
|
+
configExportName: string;
|
|
114
|
+
serviceImportPath: string;
|
|
115
|
+
serviceImportName: string;
|
|
116
|
+
}) => `import { Services } from '@server/app';
|
|
117
|
+
import ${serviceImportName} from ${JSON.stringify(serviceImportPath)};
|
|
118
|
+
|
|
119
|
+
export const ${configExportName} = Services.config(${serviceImportName}, {});
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
export const createRouterConfigTemplate = () => `import { type ServiceConfig } from '@server/app';
|
|
123
|
+
import AppContainer from '@server/app/container';
|
|
124
|
+
import Router from '@server/services/router';
|
|
125
|
+
|
|
126
|
+
type RouterBaseConfig = Omit<ServiceConfig<typeof Router>, 'plugins'>;
|
|
127
|
+
|
|
128
|
+
const currentDomain = AppContainer.Environment.router.currentDomain;
|
|
129
|
+
const currentUrl = new URL(currentDomain);
|
|
130
|
+
|
|
131
|
+
export const routerBaseConfig = {
|
|
132
|
+
currentDomain,
|
|
133
|
+
http: {
|
|
134
|
+
domain: currentUrl.hostname,
|
|
135
|
+
port: AppContainer.Environment.router.port,
|
|
136
|
+
ssl: currentUrl.protocol === 'https:',
|
|
137
|
+
upload: {
|
|
138
|
+
maxSize: '10mb',
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
context: () => ({}),
|
|
142
|
+
} satisfies RouterBaseConfig;
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
export const createServerIndexTemplate = ({ appIdentifier }: { appIdentifier: string }) => `import { Application } from '@server/app';
|
|
146
|
+
import Router from '@server/services/router';
|
|
147
|
+
import SchemaRouter from '@server/services/schema/router';
|
|
148
|
+
|
|
149
|
+
import * as appConfig from '@/server/config/app';
|
|
150
|
+
|
|
151
|
+
export default class ${appIdentifier} extends Application {
|
|
152
|
+
public Router = new Router(
|
|
153
|
+
this,
|
|
154
|
+
{
|
|
155
|
+
...appConfig.routerBaseConfig,
|
|
156
|
+
plugins: {
|
|
157
|
+
schema: new SchemaRouter({}, this),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
this,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
`;
|
|
164
|
+
|
|
165
|
+
export const createClientTsconfigTemplate = () => `{
|
|
166
|
+
"extends": "../node_modules/proteum/tsconfig.common.json",
|
|
167
|
+
"compilerOptions": {
|
|
168
|
+
"rootDir": "..",
|
|
169
|
+
"baseUrl": "..",
|
|
170
|
+
"noImplicitAny": true,
|
|
171
|
+
"noImplicitThis": true,
|
|
172
|
+
"strictBindCallApply": true,
|
|
173
|
+
"useUnknownInCatchVariables": true,
|
|
174
|
+
"paths": {
|
|
175
|
+
"@client/*": ["./node_modules/proteum/client/*"],
|
|
176
|
+
"@common/*": ["./node_modules/proteum/common/*"],
|
|
177
|
+
"@server/*": ["./node_modules/proteum/server/*"],
|
|
178
|
+
|
|
179
|
+
"@/client/context": ["./.proteum/client/context.ts"],
|
|
180
|
+
"@generated/client/*": ["./.proteum/client/*"],
|
|
181
|
+
"@generated/common/*": ["./.proteum/common/*"],
|
|
182
|
+
"@generated/server/*": ["./.proteum/server/*"],
|
|
183
|
+
"@/*": ["./*"],
|
|
184
|
+
|
|
185
|
+
"react": ["./node_modules/preact/compat"],
|
|
186
|
+
"react-dom/test-utils": ["./node_modules/preact/test-utils"],
|
|
187
|
+
"react-dom": ["./node_modules/preact/compat"],
|
|
188
|
+
"react/jsx-runtime": ["./node_modules/preact/jsx-runtime"]
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"include": [
|
|
192
|
+
".",
|
|
193
|
+
"../var/typings",
|
|
194
|
+
"../node_modules/proteum/types/global",
|
|
195
|
+
"../.proteum/client/services.d.ts",
|
|
196
|
+
"../server/index.ts"
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
200
|
+
|
|
201
|
+
export const createServerTsconfigTemplate = () => `{
|
|
202
|
+
"extends": "../node_modules/proteum/tsconfig.common.json",
|
|
203
|
+
"compilerOptions": {
|
|
204
|
+
"rootDir": "..",
|
|
205
|
+
"baseUrl": "..",
|
|
206
|
+
"noImplicitAny": true,
|
|
207
|
+
"noImplicitThis": true,
|
|
208
|
+
"strictBindCallApply": true,
|
|
209
|
+
"useUnknownInCatchVariables": true,
|
|
210
|
+
"moduleSuffixes": [".ssr", ""],
|
|
211
|
+
"paths": {
|
|
212
|
+
"@client/*": ["./node_modules/proteum/client/*"],
|
|
213
|
+
"@common/*": ["./node_modules/proteum/common/*"],
|
|
214
|
+
"@server/*": ["./node_modules/proteum/server/*"],
|
|
215
|
+
|
|
216
|
+
"@/client/context": ["./.proteum/client/context.ts"],
|
|
217
|
+
"@generated/client/*": ["./.proteum/client/*"],
|
|
218
|
+
"@generated/common/*": ["./.proteum/common/*"],
|
|
219
|
+
"@generated/server/*": ["./.proteum/server/*"],
|
|
220
|
+
"@/*": ["./*"],
|
|
221
|
+
|
|
222
|
+
"react": ["./node_modules/preact/compat"],
|
|
223
|
+
"react-dom/test-utils": ["./node_modules/preact/test-utils"],
|
|
224
|
+
"react-dom": ["./node_modules/preact/compat"],
|
|
225
|
+
"react/jsx-runtime": ["./node_modules/preact/jsx-runtime"]
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"include": [
|
|
229
|
+
".",
|
|
230
|
+
"../var/typings",
|
|
231
|
+
"../node_modules/proteum/types/global",
|
|
232
|
+
"../.proteum/server/services.d.ts",
|
|
233
|
+
"../server/index.ts"
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
|
|
238
|
+
export const createGitignoreTemplate = () => `node_modules
|
|
239
|
+
.proteum
|
|
240
|
+
.cache
|
|
241
|
+
bin
|
|
242
|
+
dev
|
|
243
|
+
var
|
|
244
|
+
.env
|
|
245
|
+
`;
|
|
246
|
+
|
|
247
|
+
export const createEnvTemplate = ({ port, url }: { port: number; url: string }) => `ENV_NAME=local
|
|
248
|
+
ENV_PROFILE=dev
|
|
249
|
+
PORT=${port}
|
|
250
|
+
URL=${url}
|
|
251
|
+
|
|
252
|
+
# Optional trace settings
|
|
253
|
+
# TRACE_ENABLE=true
|
|
254
|
+
# TRACE_CAPTURE=resolve
|
|
255
|
+
# TRACE_PERSIST_ON_ERROR=true
|
|
256
|
+
`;
|
|
257
|
+
|
|
258
|
+
export const createEslintConfigTemplate = () => `import proteumEslint from 'proteum/eslint.js';
|
|
259
|
+
|
|
260
|
+
const { createProteumEslintConfig } = proteumEslint;
|
|
261
|
+
|
|
262
|
+
export default createProteumEslintConfig();
|
|
263
|
+
`;
|
|
264
|
+
|
|
265
|
+
export const createPackageJsonTemplate = ({
|
|
266
|
+
packageName,
|
|
267
|
+
appDescription,
|
|
268
|
+
proteumDependency,
|
|
269
|
+
preactDependency,
|
|
270
|
+
}: {
|
|
271
|
+
packageName: string;
|
|
272
|
+
appDescription: string;
|
|
273
|
+
proteumDependency: string;
|
|
274
|
+
preactDependency: string;
|
|
275
|
+
}) =>
|
|
276
|
+
`${renderJson({
|
|
277
|
+
name: packageName,
|
|
278
|
+
version: '0.0.1',
|
|
279
|
+
private: true,
|
|
280
|
+
engines: {
|
|
281
|
+
node: '>=20.19.0',
|
|
282
|
+
npm: '>=3.10.10',
|
|
283
|
+
},
|
|
284
|
+
browserslist: ['>1%', 'not dead', 'not op_mini all'],
|
|
285
|
+
scripts: {
|
|
286
|
+
dev: 'NODE_ENV=development proteum dev',
|
|
287
|
+
refresh: 'npx proteum refresh',
|
|
288
|
+
typecheck: 'npx proteum typecheck',
|
|
289
|
+
lint: 'npx proteum lint',
|
|
290
|
+
check: 'npx proteum check',
|
|
291
|
+
build: 'npx proteum build --prod',
|
|
292
|
+
start: 'NODE_ENV=production node ./bin/server.js',
|
|
293
|
+
},
|
|
294
|
+
description: appDescription,
|
|
295
|
+
dependencies: {
|
|
296
|
+
preact: preactDependency,
|
|
297
|
+
proteum: proteumDependency,
|
|
298
|
+
},
|
|
299
|
+
})}\n`;
|
|
300
|
+
|
|
301
|
+
export const createIdentityTemplate = ({
|
|
302
|
+
appName,
|
|
303
|
+
appIdentifier,
|
|
304
|
+
appDescription,
|
|
305
|
+
}: {
|
|
306
|
+
appName: string;
|
|
307
|
+
appIdentifier: string;
|
|
308
|
+
appDescription: string;
|
|
309
|
+
}) => `name: ${appName}
|
|
310
|
+
identifier: ${appIdentifier}
|
|
311
|
+
description: ${JSON.stringify(appDescription)}
|
|
312
|
+
|
|
313
|
+
author:
|
|
314
|
+
name: ${appName}
|
|
315
|
+
url: localhost
|
|
316
|
+
email: team@example.com
|
|
317
|
+
|
|
318
|
+
social:
|
|
319
|
+
|
|
320
|
+
language: en
|
|
321
|
+
locale: en-US
|
|
322
|
+
maincolor: white
|
|
323
|
+
iconsPack: light
|
|
324
|
+
|
|
325
|
+
web:
|
|
326
|
+
title: ${JSON.stringify(appName)}
|
|
327
|
+
titleSuffix: ${JSON.stringify(appName)}
|
|
328
|
+
fullTitle: ${JSON.stringify(appName)}
|
|
329
|
+
description: ${JSON.stringify(appDescription)}
|
|
330
|
+
version: 0.0.1
|
|
331
|
+
`;
|
|
332
|
+
|
|
333
|
+
export const createInitSummary = (result: TScaffoldResult, config: TScaffoldInitConfig) => ({
|
|
334
|
+
...result,
|
|
335
|
+
project: {
|
|
336
|
+
directory: config.directory,
|
|
337
|
+
name: config.name,
|
|
338
|
+
identifier: config.identifier,
|
|
339
|
+
port: config.port,
|
|
340
|
+
url: config.url,
|
|
341
|
+
proteumDependency: config.proteumDependency,
|
|
342
|
+
install: config.install,
|
|
343
|
+
},
|
|
344
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type TScaffoldKind = 'page' | 'controller' | 'command' | 'route' | 'service';
|
|
2
|
+
|
|
3
|
+
export type TScaffoldFilePlan = {
|
|
4
|
+
relativePath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type TScaffoldResult = {
|
|
9
|
+
dryRun: boolean;
|
|
10
|
+
created: string[];
|
|
11
|
+
updated: string[];
|
|
12
|
+
skipped: string[];
|
|
13
|
+
notes: string[];
|
|
14
|
+
nextSteps: string[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type TScaffoldInitConfig = {
|
|
18
|
+
directory: string;
|
|
19
|
+
name: string;
|
|
20
|
+
identifier: string;
|
|
21
|
+
description: string;
|
|
22
|
+
port: number;
|
|
23
|
+
url: string;
|
|
24
|
+
install: boolean;
|
|
25
|
+
proteumDependency: string;
|
|
26
|
+
};
|
package/cli/tsconfig.json
CHANGED
|
@@ -29,9 +29,12 @@
|
|
|
29
29
|
"outDir": "./bin",
|
|
30
30
|
|
|
31
31
|
"paths": {
|
|
32
|
+
"@client/*": [ "../client/*" ],
|
|
32
33
|
"@cli/*": [ "./*" ],
|
|
33
34
|
"@cli/app": [ "./app" ],
|
|
34
|
-
"@cli": [ "./" ]
|
|
35
|
+
"@cli": [ "./" ],
|
|
36
|
+
"@common/*": [ "../common/*" ],
|
|
37
|
+
"@server/*": [ "../server/*" ]
|
|
35
38
|
},
|
|
36
39
|
},
|
|
37
40
|
|
package/cli/utils/check.ts
CHANGED
|
@@ -5,7 +5,7 @@ import cli from '..';
|
|
|
5
5
|
import Compiler from '../compiler';
|
|
6
6
|
import { runProcess } from './runProcess';
|
|
7
7
|
|
|
8
|
-
const tsconfigPaths = ['client/tsconfig.json', 'server/tsconfig.json'];
|
|
8
|
+
const tsconfigPaths = ['client/tsconfig.json', 'server/tsconfig.json', 'commands/tsconfig.json'];
|
|
9
9
|
const eslintConfigPaths = ['eslint.config.mjs', 'eslint.config.js', 'eslint.config.cjs'];
|
|
10
10
|
|
|
11
11
|
const resolveInstalledBinary = (name: string) => {
|
package/client/app/component.tsx
CHANGED
|
@@ -21,10 +21,17 @@ export default function App({ context }: { context: ClientContext }) {
|
|
|
21
21
|
const curLayout = context.page?.layout;
|
|
22
22
|
const [layout, setLayout] = React.useState<Layout | false | undefined>(curLayout);
|
|
23
23
|
const [apiData, setApiData] = React.useState<{ [k: string]: any } | null>(context.page?.data || {});
|
|
24
|
+
const shouldEnableDevProfiler = __DEV__ && typeof window !== 'undefined' && window.dev;
|
|
25
|
+
const [isDevProfilerMounted, setDevProfilerMounted] = React.useState(false);
|
|
24
26
|
|
|
25
27
|
// TODO: context.page is always provided in the context on the client side
|
|
26
28
|
if (context.app.side === 'client') context.app.setLayout = setLayout;
|
|
27
29
|
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
if (!shouldEnableDevProfiler) return;
|
|
32
|
+
setDevProfilerMounted(true);
|
|
33
|
+
}, [shouldEnableDevProfiler]);
|
|
34
|
+
|
|
28
35
|
const layoutProps: LayoutProps = {
|
|
29
36
|
...context,
|
|
30
37
|
context,
|
|
@@ -32,22 +39,19 @@ export default function App({ context }: { context: ClientContext }) {
|
|
|
32
39
|
menu: undefined,
|
|
33
40
|
children: undefined,
|
|
34
41
|
};
|
|
42
|
+
const DevProfiler = shouldEnableDevProfiler
|
|
43
|
+
? ((require('@client/dev/profiler') as typeof import('@client/dev/profiler')).default as React.ComponentType)
|
|
44
|
+
: null;
|
|
35
45
|
|
|
36
46
|
return (
|
|
37
47
|
<ReactClientContext.Provider value={context}>
|
|
38
48
|
<DialogManager />
|
|
49
|
+
{DevProfiler && isDevProfilerMounted ? <DevProfiler /> : null}
|
|
39
50
|
|
|
40
51
|
{!layout ? (
|
|
41
|
-
|
|
42
|
-
{/* TODO: move to app, because here, we're not aware that the router service has been defined */}
|
|
43
|
-
<RouterComponent service={context.Router} />
|
|
44
|
-
</>
|
|
52
|
+
<RouterComponent service={context.Router} />
|
|
45
53
|
) : (
|
|
46
|
-
|
|
47
|
-
{' '}
|
|
48
|
-
{/* Same as router/components/Page.tsx */}
|
|
49
|
-
<layout.Component {...layoutProps} />
|
|
50
|
-
</>
|
|
54
|
+
<layout.Component {...layoutProps} />
|
|
51
55
|
)}
|
|
52
56
|
</ReactClientContext.Provider>
|
|
53
57
|
);
|