@openfairygui/backend 0.2.0 → 0.3.0-alpha.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/README.md +8 -0
- package/dist/index.cjs +93 -5
- package/dist/index.d.cts +58 -4
- package/dist/index.d.mts +58 -4
- package/dist/index.mjs +93 -5
- package/dist/node.cjs +92 -4
- package/dist/node.d.cts +57 -3
- package/dist/node.d.mts +57 -3
- package/dist/node.mjs +92 -4
- package/package.json +3 -3
- package/src/contracts.ts +1 -1
- package/src/index.ts +5 -0
- package/src/runtime/capabilities.ts +4 -0
- package/src/runtime/contracts.ts +49 -1
- package/src/runtime.ts +16 -0
- package/src/services/context.ts +2 -0
- package/src/services/read-service.ts +85 -2
- package/src/services/runtime-service.ts +7 -1
package/src/runtime.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ApplyUamTransactionAppError } from '@openfairygui/functions/uam';
|
|
2
|
+
import type { ProjectValidationReport } from '@openfairygui/core';
|
|
2
3
|
import type { PathPolicyViolationError } from './path-policy.js';
|
|
3
4
|
import { AuthoringService } from './services/authoring-service.js';
|
|
4
5
|
import { CacheService } from './services/cache-service.js';
|
|
@@ -21,6 +22,7 @@ import type {
|
|
|
21
22
|
BackendJobNotCancellableError,
|
|
22
23
|
BackendJobNotFoundError,
|
|
23
24
|
BackendJobSnapshot,
|
|
25
|
+
BackendProjectOutline,
|
|
24
26
|
BackendResult,
|
|
25
27
|
BackendRuntimeOptions,
|
|
26
28
|
BackendSessionSnapshot,
|
|
@@ -31,6 +33,8 @@ import type {
|
|
|
31
33
|
GetEventsInput,
|
|
32
34
|
GetEventsSnapshot,
|
|
33
35
|
GetJobInput,
|
|
36
|
+
GetProjectOutlineInput,
|
|
37
|
+
ValidateSessionInput,
|
|
34
38
|
InProcessLockConflictError,
|
|
35
39
|
ListJobsInput,
|
|
36
40
|
MaterializeSessionInput,
|
|
@@ -113,6 +117,18 @@ export class BackendRuntime {
|
|
|
113
117
|
return this.readService.getSession(input);
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
public getProjectOutline(
|
|
121
|
+
input: GetProjectOutlineInput,
|
|
122
|
+
): BackendResult<BackendProjectOutline, SessionNotFoundError> {
|
|
123
|
+
return this.readService.getProjectOutline(input);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public validateSession(
|
|
127
|
+
input: ValidateSessionInput,
|
|
128
|
+
): BackendResult<ProjectValidationReport, SessionNotFoundError> {
|
|
129
|
+
return this.readService.validateSession(input);
|
|
130
|
+
}
|
|
131
|
+
|
|
116
132
|
public async applyTransaction(
|
|
117
133
|
input: ApplySessionTransactionInput,
|
|
118
134
|
): Promise<
|
package/src/services/context.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface BackendSessionState {
|
|
|
29
29
|
sessionLock: BackendSessionLock | null;
|
|
30
30
|
fileSystem?: BackendFileSystem;
|
|
31
31
|
project: import('@openfairygui/core/uam').UamProject;
|
|
32
|
+
readDiagnostics: import('@openfairygui/core').ProjectDiagnostic[];
|
|
33
|
+
readComplete: boolean;
|
|
32
34
|
uamFidelity: 'full' | 'unsupported';
|
|
33
35
|
revision: number;
|
|
34
36
|
lastSavedRevision: number;
|
|
@@ -1,6 +1,55 @@
|
|
|
1
|
-
import { failure, success, type BackendContext } from './context.js';
|
|
2
|
-
import type {
|
|
1
|
+
import { failure, success, type BackendContext, type BackendSessionState } from './context.js';
|
|
2
|
+
import type {
|
|
3
|
+
BackendCapabilities,
|
|
4
|
+
BackendProjectOutline,
|
|
5
|
+
BackendResult,
|
|
6
|
+
BackendSessionSnapshot,
|
|
7
|
+
GetProjectOutlineInput,
|
|
8
|
+
SessionNotFoundError,
|
|
9
|
+
} from '../runtime.js';
|
|
3
10
|
import { createSessionNotFoundError, toSessionSnapshot } from './session-utils.js';
|
|
11
|
+
import { validateProject } from '@openfairygui/functions';
|
|
12
|
+
import type { ProjectValidationReport } from '@openfairygui/core';
|
|
13
|
+
|
|
14
|
+
function toProjectOutline(session: BackendSessionState): BackendProjectOutline {
|
|
15
|
+
const project = session.project;
|
|
16
|
+
// ponytail: full outline is O(project size); add filters or pagination only if payload size becomes a measured problem.
|
|
17
|
+
return {
|
|
18
|
+
sessionId: session.sessionId,
|
|
19
|
+
revision: session.revision,
|
|
20
|
+
projectId: project.projectId,
|
|
21
|
+
projectType: project.projectType,
|
|
22
|
+
version: project.version,
|
|
23
|
+
branches: [...project.branches],
|
|
24
|
+
packages: project.packages.map((pkg) => ({
|
|
25
|
+
id: pkg.id,
|
|
26
|
+
name: pkg.name,
|
|
27
|
+
branchNames: [...pkg.branchNames],
|
|
28
|
+
folders: pkg.folders.map((folder) => ({ branch: folder.branch, path: folder.path })),
|
|
29
|
+
resources: pkg.resources.map((resource) => ({
|
|
30
|
+
id: resource.id,
|
|
31
|
+
name: resource.name,
|
|
32
|
+
path: resource.path,
|
|
33
|
+
kind: resource.kind,
|
|
34
|
+
branch: resource.branch,
|
|
35
|
+
...(resource.kind === 'component' ? {
|
|
36
|
+
component: {
|
|
37
|
+
displayList: resource.component.displayList.map((node) => ({
|
|
38
|
+
id: node.id,
|
|
39
|
+
name: node.name,
|
|
40
|
+
kind: node.kind,
|
|
41
|
+
})),
|
|
42
|
+
controllers: resource.component.controllers.map((controller) => ({
|
|
43
|
+
name: controller.name,
|
|
44
|
+
pages: controller.pages.map((page) => ({ id: page.id, name: page.name })),
|
|
45
|
+
})),
|
|
46
|
+
transitions: resource.component.transitions.map((transition) => ({ name: transition.name })),
|
|
47
|
+
},
|
|
48
|
+
} : {}),
|
|
49
|
+
})),
|
|
50
|
+
})),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
4
53
|
|
|
5
54
|
export class ReadService {
|
|
6
55
|
public constructor(private readonly context: BackendContext) {}
|
|
@@ -20,4 +69,38 @@ export class ReadService {
|
|
|
20
69
|
revision: session.revision,
|
|
21
70
|
});
|
|
22
71
|
}
|
|
72
|
+
|
|
73
|
+
public getProjectOutline(
|
|
74
|
+
input: GetProjectOutlineInput,
|
|
75
|
+
): BackendResult<BackendProjectOutline, SessionNotFoundError> {
|
|
76
|
+
const startedAt = Date.now();
|
|
77
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
78
|
+
if (!session || session.closed) {
|
|
79
|
+
return failure('read', startedAt, createSessionNotFoundError(input.sessionId));
|
|
80
|
+
}
|
|
81
|
+
return success('read', startedAt, toProjectOutline(session), {
|
|
82
|
+
sessionId: session.sessionId,
|
|
83
|
+
revision: session.revision,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public validateSession(
|
|
88
|
+
input: { sessionId: string },
|
|
89
|
+
): BackendResult<ProjectValidationReport, SessionNotFoundError> {
|
|
90
|
+
const startedAt = Date.now();
|
|
91
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
92
|
+
if (!session || session.closed) {
|
|
93
|
+
return failure('read', startedAt, createSessionNotFoundError(input.sessionId));
|
|
94
|
+
}
|
|
95
|
+
const report = validateProject(session.project, {
|
|
96
|
+
readDiagnostics: session.readDiagnostics,
|
|
97
|
+
complete: session.readComplete,
|
|
98
|
+
validateSources: true,
|
|
99
|
+
});
|
|
100
|
+
return success('read', startedAt, report, {
|
|
101
|
+
sessionId: session.sessionId,
|
|
102
|
+
revision: session.revision,
|
|
103
|
+
diagnostics: report.diagnostics.map(({ code, message, severity, path }) => ({ code, message, severity, path })),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
23
106
|
}
|
|
@@ -220,7 +220,9 @@ export class RuntimeService {
|
|
|
220
220
|
),
|
|
221
221
|
);
|
|
222
222
|
const reader = new ProjectReader(createProjectReaderFileSystem(fileSystem));
|
|
223
|
-
const
|
|
223
|
+
const read = await reader.readDetailed(fairyPath, { hydrateResourceBytes: true });
|
|
224
|
+
if (!read.document) throw new Error(read.diagnostics[0]?.message ?? `Unable to read project: ${fairyPath}`);
|
|
225
|
+
const document = read.document;
|
|
224
226
|
const project = liftDocumentToUamProject(document);
|
|
225
227
|
const sessionId = randomId();
|
|
226
228
|
const session: BackendSessionState = {
|
|
@@ -232,6 +234,8 @@ export class RuntimeService {
|
|
|
232
234
|
sessionLock,
|
|
233
235
|
fileSystem,
|
|
234
236
|
project,
|
|
237
|
+
readDiagnostics: read.diagnostics,
|
|
238
|
+
readComplete: read.complete,
|
|
235
239
|
uamFidelity: (await hasFullUamFidelity(document, project)) ? 'full' : 'unsupported',
|
|
236
240
|
revision: 0,
|
|
237
241
|
lastSavedRevision: 0,
|
|
@@ -305,6 +309,8 @@ export class RuntimeService {
|
|
|
305
309
|
sessionLock: null,
|
|
306
310
|
fileSystem: storage?.fileSystem,
|
|
307
311
|
project: normalizeUamProject(input.project),
|
|
312
|
+
readDiagnostics: [],
|
|
313
|
+
readComplete: true,
|
|
308
314
|
uamFidelity: 'full',
|
|
309
315
|
revision: 0,
|
|
310
316
|
lastSavedRevision: 0,
|