@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/dist/node.cjs
CHANGED
|
@@ -28,6 +28,7 @@ node_path = __toESM(node_path);
|
|
|
28
28
|
let _openfairygui_core_uam = require("@openfairygui/core/uam");
|
|
29
29
|
let _openfairygui_functions_uam = require("@openfairygui/functions/uam");
|
|
30
30
|
let _openfairygui_core_project_io = require("@openfairygui/core/project-io");
|
|
31
|
+
let _openfairygui_functions = require("@openfairygui/functions");
|
|
31
32
|
//#region src/path-policy.ts
|
|
32
33
|
function normalizeComparablePath(value) {
|
|
33
34
|
const normalized = value.replace(/[/\\]+$/, "").replace(/\\/g, "/");
|
|
@@ -122,7 +123,7 @@ function createMeta(stage, startedAt, options) {
|
|
|
122
123
|
diagnostics: options?.diagnostics ?? [],
|
|
123
124
|
stage,
|
|
124
125
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
125
|
-
capabilitySchemaVersion:
|
|
126
|
+
capabilitySchemaVersion: 3
|
|
126
127
|
};
|
|
127
128
|
}
|
|
128
129
|
function success(stage, startedAt, data, options) {
|
|
@@ -1076,6 +1077,48 @@ var JobService = class {
|
|
|
1076
1077
|
};
|
|
1077
1078
|
//#endregion
|
|
1078
1079
|
//#region src/services/read-service.ts
|
|
1080
|
+
function toProjectOutline(session) {
|
|
1081
|
+
const project = session.project;
|
|
1082
|
+
return {
|
|
1083
|
+
sessionId: session.sessionId,
|
|
1084
|
+
revision: session.revision,
|
|
1085
|
+
projectId: project.projectId,
|
|
1086
|
+
projectType: project.projectType,
|
|
1087
|
+
version: project.version,
|
|
1088
|
+
branches: [...project.branches],
|
|
1089
|
+
packages: project.packages.map((pkg) => ({
|
|
1090
|
+
id: pkg.id,
|
|
1091
|
+
name: pkg.name,
|
|
1092
|
+
branchNames: [...pkg.branchNames],
|
|
1093
|
+
folders: pkg.folders.map((folder) => ({
|
|
1094
|
+
branch: folder.branch,
|
|
1095
|
+
path: folder.path
|
|
1096
|
+
})),
|
|
1097
|
+
resources: pkg.resources.map((resource) => ({
|
|
1098
|
+
id: resource.id,
|
|
1099
|
+
name: resource.name,
|
|
1100
|
+
path: resource.path,
|
|
1101
|
+
kind: resource.kind,
|
|
1102
|
+
branch: resource.branch,
|
|
1103
|
+
...resource.kind === "component" ? { component: {
|
|
1104
|
+
displayList: resource.component.displayList.map((node) => ({
|
|
1105
|
+
id: node.id,
|
|
1106
|
+
name: node.name,
|
|
1107
|
+
kind: node.kind
|
|
1108
|
+
})),
|
|
1109
|
+
controllers: resource.component.controllers.map((controller) => ({
|
|
1110
|
+
name: controller.name,
|
|
1111
|
+
pages: controller.pages.map((page) => ({
|
|
1112
|
+
id: page.id,
|
|
1113
|
+
name: page.name
|
|
1114
|
+
}))
|
|
1115
|
+
})),
|
|
1116
|
+
transitions: resource.component.transitions.map((transition) => ({ name: transition.name }))
|
|
1117
|
+
} } : {}
|
|
1118
|
+
}))
|
|
1119
|
+
}))
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1079
1122
|
var ReadService = class {
|
|
1080
1123
|
constructor(context) {
|
|
1081
1124
|
this.context = context;
|
|
@@ -1092,6 +1135,35 @@ var ReadService = class {
|
|
|
1092
1135
|
revision: session.revision
|
|
1093
1136
|
});
|
|
1094
1137
|
}
|
|
1138
|
+
getProjectOutline(input) {
|
|
1139
|
+
const startedAt = Date.now();
|
|
1140
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
1141
|
+
if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
|
|
1142
|
+
return success("read", startedAt, toProjectOutline(session), {
|
|
1143
|
+
sessionId: session.sessionId,
|
|
1144
|
+
revision: session.revision
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
validateSession(input) {
|
|
1148
|
+
const startedAt = Date.now();
|
|
1149
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
1150
|
+
if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
|
|
1151
|
+
const report = (0, _openfairygui_functions.validateProject)(session.project, {
|
|
1152
|
+
readDiagnostics: session.readDiagnostics,
|
|
1153
|
+
complete: session.readComplete,
|
|
1154
|
+
validateSources: true
|
|
1155
|
+
});
|
|
1156
|
+
return success("read", startedAt, report, {
|
|
1157
|
+
sessionId: session.sessionId,
|
|
1158
|
+
revision: session.revision,
|
|
1159
|
+
diagnostics: report.diagnostics.map(({ code, message, severity, path }) => ({
|
|
1160
|
+
code,
|
|
1161
|
+
message,
|
|
1162
|
+
severity,
|
|
1163
|
+
path
|
|
1164
|
+
}))
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1095
1167
|
};
|
|
1096
1168
|
//#endregion
|
|
1097
1169
|
//#region src/services/runtime-service.ts
|
|
@@ -1247,7 +1319,9 @@ var RuntimeService = class {
|
|
|
1247
1319
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1248
1320
|
canonicalPathKey
|
|
1249
1321
|
}));
|
|
1250
|
-
const
|
|
1322
|
+
const read = await new _openfairygui_core_project_io.ProjectReader(createProjectReaderFileSystem(fileSystem)).readDetailed(fairyPath, { hydrateResourceBytes: true });
|
|
1323
|
+
if (!read.document) throw new Error(read.diagnostics[0]?.message ?? `Unable to read project: ${fairyPath}`);
|
|
1324
|
+
const document = read.document;
|
|
1251
1325
|
const project = (0, _openfairygui_core_uam.liftDocumentToUamProject)(document);
|
|
1252
1326
|
const sessionId = randomId();
|
|
1253
1327
|
const session = {
|
|
@@ -1259,6 +1333,8 @@ var RuntimeService = class {
|
|
|
1259
1333
|
sessionLock,
|
|
1260
1334
|
fileSystem,
|
|
1261
1335
|
project,
|
|
1336
|
+
readDiagnostics: read.diagnostics,
|
|
1337
|
+
readComplete: read.complete,
|
|
1262
1338
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1263
1339
|
revision: 0,
|
|
1264
1340
|
lastSavedRevision: 0,
|
|
@@ -1322,6 +1398,8 @@ var RuntimeService = class {
|
|
|
1322
1398
|
sessionLock: null,
|
|
1323
1399
|
fileSystem: storage?.fileSystem,
|
|
1324
1400
|
project: (0, _openfairygui_core_uam.normalizeUamProject)(input.project),
|
|
1401
|
+
readDiagnostics: [],
|
|
1402
|
+
readComplete: true,
|
|
1325
1403
|
uamFidelity: "full",
|
|
1326
1404
|
revision: 0,
|
|
1327
1405
|
lastSavedRevision: 0,
|
|
@@ -1405,6 +1483,8 @@ const BACKEND_METHODS = [
|
|
|
1405
1483
|
"openSession",
|
|
1406
1484
|
"openProjectSession",
|
|
1407
1485
|
"getSession",
|
|
1486
|
+
"getProjectOutline",
|
|
1487
|
+
"validateSession",
|
|
1408
1488
|
"applyTransaction",
|
|
1409
1489
|
"saveSession",
|
|
1410
1490
|
"materializeSession",
|
|
@@ -1426,14 +1506,16 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1426
1506
|
function createCapabilities() {
|
|
1427
1507
|
return {
|
|
1428
1508
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1429
|
-
capabilitySchemaVersion:
|
|
1509
|
+
capabilitySchemaVersion: 3,
|
|
1430
1510
|
transactionKernelOwner: "@openfairygui/core",
|
|
1431
1511
|
appSeamOwner: "@openfairygui/functions",
|
|
1432
1512
|
runtimeOwner: "@openfairygui/backend",
|
|
1433
1513
|
methods: BACKEND_METHODS,
|
|
1434
1514
|
read: {
|
|
1435
1515
|
capabilitySnapshot: true,
|
|
1436
|
-
sessionSnapshot: true
|
|
1516
|
+
sessionSnapshot: true,
|
|
1517
|
+
projectOutline: true,
|
|
1518
|
+
projectValidation: true
|
|
1437
1519
|
},
|
|
1438
1520
|
authoring: {
|
|
1439
1521
|
applyTransaction: true,
|
|
@@ -1573,6 +1655,12 @@ var BackendRuntime = class {
|
|
|
1573
1655
|
getSession(input) {
|
|
1574
1656
|
return this.readService.getSession(input);
|
|
1575
1657
|
}
|
|
1658
|
+
getProjectOutline(input) {
|
|
1659
|
+
return this.readService.getProjectOutline(input);
|
|
1660
|
+
}
|
|
1661
|
+
validateSession(input) {
|
|
1662
|
+
return this.readService.validateSession(input);
|
|
1663
|
+
}
|
|
1576
1664
|
async applyTransaction(input) {
|
|
1577
1665
|
return this.authoringService.applyTransaction(input);
|
|
1578
1666
|
}
|
package/dist/node.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
|
|
2
|
-
import {
|
|
2
|
+
import { ProjectValidationReport } from "@openfairygui/core";
|
|
3
|
+
import { UamDisplayNodeKind, UamProject, UamResource, UamTransactionOperation } from "@openfairygui/core/uam";
|
|
3
4
|
|
|
4
5
|
//#region src/path-policy.d.ts
|
|
5
6
|
interface PathPolicyViolationError {
|
|
@@ -12,7 +13,7 @@ interface PathPolicyViolationError {
|
|
|
12
13
|
//#endregion
|
|
13
14
|
//#region src/contracts.d.ts
|
|
14
15
|
declare const BACKEND_CONTRACT_VERSION: "1.1.0-p2";
|
|
15
|
-
declare const BACKEND_CAPABILITY_SCHEMA_VERSION:
|
|
16
|
+
declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 3;
|
|
16
17
|
declare const BACKEND_COMPATIBILITY_POLICY: {
|
|
17
18
|
readonly incompatibleChange: "requires contractVersion bump";
|
|
18
19
|
readonly capabilitySchemaChange: "requires capabilitySchemaVersion bump";
|
|
@@ -129,10 +130,12 @@ interface BackendCapabilities {
|
|
|
129
130
|
transactionKernelOwner: '@openfairygui/core';
|
|
130
131
|
appSeamOwner: '@openfairygui/functions';
|
|
131
132
|
runtimeOwner: '@openfairygui/backend';
|
|
132
|
-
methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
|
|
133
|
+
methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'getProjectOutline', 'validateSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
|
|
133
134
|
read: {
|
|
134
135
|
capabilitySnapshot: true;
|
|
135
136
|
sessionSnapshot: true;
|
|
137
|
+
projectOutline: true;
|
|
138
|
+
projectValidation: true;
|
|
136
139
|
};
|
|
137
140
|
authoring: {
|
|
138
141
|
applyTransaction: true;
|
|
@@ -201,6 +204,49 @@ interface BackendSessionSnapshot {
|
|
|
201
204
|
lockHeld: boolean;
|
|
202
205
|
capabilities: BackendCapabilities;
|
|
203
206
|
}
|
|
207
|
+
interface BackendProjectOutline {
|
|
208
|
+
sessionId: string;
|
|
209
|
+
revision: number;
|
|
210
|
+
projectId: string;
|
|
211
|
+
projectType: number;
|
|
212
|
+
version: string;
|
|
213
|
+
branches: string[];
|
|
214
|
+
packages: BackendProjectOutlinePackage[];
|
|
215
|
+
}
|
|
216
|
+
interface BackendProjectOutlinePackage {
|
|
217
|
+
id: string;
|
|
218
|
+
name: string;
|
|
219
|
+
branchNames: string[];
|
|
220
|
+
folders: Array<{
|
|
221
|
+
branch: string;
|
|
222
|
+
path: string;
|
|
223
|
+
}>;
|
|
224
|
+
resources: BackendProjectOutlineResource[];
|
|
225
|
+
}
|
|
226
|
+
interface BackendProjectOutlineResource {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string;
|
|
229
|
+
path: string;
|
|
230
|
+
kind: UamResource['kind'];
|
|
231
|
+
branch: string;
|
|
232
|
+
component?: {
|
|
233
|
+
displayList: Array<{
|
|
234
|
+
id: string;
|
|
235
|
+
name: string;
|
|
236
|
+
kind: UamDisplayNodeKind;
|
|
237
|
+
}>;
|
|
238
|
+
controllers: Array<{
|
|
239
|
+
name: string;
|
|
240
|
+
pages: Array<{
|
|
241
|
+
id: string;
|
|
242
|
+
name: string;
|
|
243
|
+
}>;
|
|
244
|
+
}>;
|
|
245
|
+
transitions: Array<{
|
|
246
|
+
name: string;
|
|
247
|
+
}>;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
204
250
|
interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
|
|
205
251
|
mode: 'fullProject';
|
|
206
252
|
reason?: string;
|
|
@@ -425,6 +471,12 @@ interface ApplySessionTransactionInput {
|
|
|
425
471
|
expectedRevision: number;
|
|
426
472
|
operations: UamTransactionOperation[];
|
|
427
473
|
}
|
|
474
|
+
interface GetProjectOutlineInput {
|
|
475
|
+
sessionId: string;
|
|
476
|
+
}
|
|
477
|
+
interface ValidateSessionInput {
|
|
478
|
+
sessionId: string;
|
|
479
|
+
}
|
|
428
480
|
interface OpenProjectSessionInput {
|
|
429
481
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
430
482
|
project: UamProject;
|
|
@@ -488,6 +540,8 @@ declare class BackendRuntime {
|
|
|
488
540
|
getSession(input: {
|
|
489
541
|
sessionId: string;
|
|
490
542
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
543
|
+
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
544
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
491
545
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
492
546
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
493
547
|
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
package/dist/node.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { UamProject, UamTransactionOperation } from "@openfairygui/core/uam";
|
|
1
|
+
import { UamDisplayNodeKind, UamProject, UamResource, UamTransactionOperation } from "@openfairygui/core/uam";
|
|
2
2
|
import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
|
|
3
|
+
import { ProjectValidationReport } from "@openfairygui/core";
|
|
3
4
|
|
|
4
5
|
//#region src/path-policy.d.ts
|
|
5
6
|
interface PathPolicyViolationError {
|
|
@@ -12,7 +13,7 @@ interface PathPolicyViolationError {
|
|
|
12
13
|
//#endregion
|
|
13
14
|
//#region src/contracts.d.ts
|
|
14
15
|
declare const BACKEND_CONTRACT_VERSION: "1.1.0-p2";
|
|
15
|
-
declare const BACKEND_CAPABILITY_SCHEMA_VERSION:
|
|
16
|
+
declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 3;
|
|
16
17
|
declare const BACKEND_COMPATIBILITY_POLICY: {
|
|
17
18
|
readonly incompatibleChange: "requires contractVersion bump";
|
|
18
19
|
readonly capabilitySchemaChange: "requires capabilitySchemaVersion bump";
|
|
@@ -129,10 +130,12 @@ interface BackendCapabilities {
|
|
|
129
130
|
transactionKernelOwner: '@openfairygui/core';
|
|
130
131
|
appSeamOwner: '@openfairygui/functions';
|
|
131
132
|
runtimeOwner: '@openfairygui/backend';
|
|
132
|
-
methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
|
|
133
|
+
methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'getProjectOutline', 'validateSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
|
|
133
134
|
read: {
|
|
134
135
|
capabilitySnapshot: true;
|
|
135
136
|
sessionSnapshot: true;
|
|
137
|
+
projectOutline: true;
|
|
138
|
+
projectValidation: true;
|
|
136
139
|
};
|
|
137
140
|
authoring: {
|
|
138
141
|
applyTransaction: true;
|
|
@@ -201,6 +204,49 @@ interface BackendSessionSnapshot {
|
|
|
201
204
|
lockHeld: boolean;
|
|
202
205
|
capabilities: BackendCapabilities;
|
|
203
206
|
}
|
|
207
|
+
interface BackendProjectOutline {
|
|
208
|
+
sessionId: string;
|
|
209
|
+
revision: number;
|
|
210
|
+
projectId: string;
|
|
211
|
+
projectType: number;
|
|
212
|
+
version: string;
|
|
213
|
+
branches: string[];
|
|
214
|
+
packages: BackendProjectOutlinePackage[];
|
|
215
|
+
}
|
|
216
|
+
interface BackendProjectOutlinePackage {
|
|
217
|
+
id: string;
|
|
218
|
+
name: string;
|
|
219
|
+
branchNames: string[];
|
|
220
|
+
folders: Array<{
|
|
221
|
+
branch: string;
|
|
222
|
+
path: string;
|
|
223
|
+
}>;
|
|
224
|
+
resources: BackendProjectOutlineResource[];
|
|
225
|
+
}
|
|
226
|
+
interface BackendProjectOutlineResource {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string;
|
|
229
|
+
path: string;
|
|
230
|
+
kind: UamResource['kind'];
|
|
231
|
+
branch: string;
|
|
232
|
+
component?: {
|
|
233
|
+
displayList: Array<{
|
|
234
|
+
id: string;
|
|
235
|
+
name: string;
|
|
236
|
+
kind: UamDisplayNodeKind;
|
|
237
|
+
}>;
|
|
238
|
+
controllers: Array<{
|
|
239
|
+
name: string;
|
|
240
|
+
pages: Array<{
|
|
241
|
+
id: string;
|
|
242
|
+
name: string;
|
|
243
|
+
}>;
|
|
244
|
+
}>;
|
|
245
|
+
transitions: Array<{
|
|
246
|
+
name: string;
|
|
247
|
+
}>;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
204
250
|
interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
|
|
205
251
|
mode: 'fullProject';
|
|
206
252
|
reason?: string;
|
|
@@ -425,6 +471,12 @@ interface ApplySessionTransactionInput {
|
|
|
425
471
|
expectedRevision: number;
|
|
426
472
|
operations: UamTransactionOperation[];
|
|
427
473
|
}
|
|
474
|
+
interface GetProjectOutlineInput {
|
|
475
|
+
sessionId: string;
|
|
476
|
+
}
|
|
477
|
+
interface ValidateSessionInput {
|
|
478
|
+
sessionId: string;
|
|
479
|
+
}
|
|
428
480
|
interface OpenProjectSessionInput {
|
|
429
481
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
430
482
|
project: UamProject;
|
|
@@ -488,6 +540,8 @@ declare class BackendRuntime {
|
|
|
488
540
|
getSession(input: {
|
|
489
541
|
sessionId: string;
|
|
490
542
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
543
|
+
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
544
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
491
545
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
492
546
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
493
547
|
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
package/dist/node.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { UAM_SUPPORTED_MATERIALIZATION_SCOPE, UAM_SUPPORTED_TRANSACTION_SCOPE, commitUamProjectSourcePaths, liftDocumentToUamProject, materializeUamProject, normalizeUamProject, staleBranchDirectories, staleResourceFolders, staleSourceFiles, validateUamProject } from "@openfairygui/core/uam";
|
|
4
4
|
import { applyUamTransactionAppAsync } from "@openfairygui/functions/uam";
|
|
5
5
|
import { ProjectReader, ProjectWriter } from "@openfairygui/core/project-io";
|
|
6
|
+
import { validateProject } from "@openfairygui/functions";
|
|
6
7
|
//#region src/path-policy.ts
|
|
7
8
|
function normalizeComparablePath(value) {
|
|
8
9
|
const normalized = value.replace(/[/\\]+$/, "").replace(/\\/g, "/");
|
|
@@ -97,7 +98,7 @@ function createMeta(stage, startedAt, options) {
|
|
|
97
98
|
diagnostics: options?.diagnostics ?? [],
|
|
98
99
|
stage,
|
|
99
100
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
100
|
-
capabilitySchemaVersion:
|
|
101
|
+
capabilitySchemaVersion: 3
|
|
101
102
|
};
|
|
102
103
|
}
|
|
103
104
|
function success(stage, startedAt, data, options) {
|
|
@@ -1051,6 +1052,48 @@ var JobService = class {
|
|
|
1051
1052
|
};
|
|
1052
1053
|
//#endregion
|
|
1053
1054
|
//#region src/services/read-service.ts
|
|
1055
|
+
function toProjectOutline(session) {
|
|
1056
|
+
const project = session.project;
|
|
1057
|
+
return {
|
|
1058
|
+
sessionId: session.sessionId,
|
|
1059
|
+
revision: session.revision,
|
|
1060
|
+
projectId: project.projectId,
|
|
1061
|
+
projectType: project.projectType,
|
|
1062
|
+
version: project.version,
|
|
1063
|
+
branches: [...project.branches],
|
|
1064
|
+
packages: project.packages.map((pkg) => ({
|
|
1065
|
+
id: pkg.id,
|
|
1066
|
+
name: pkg.name,
|
|
1067
|
+
branchNames: [...pkg.branchNames],
|
|
1068
|
+
folders: pkg.folders.map((folder) => ({
|
|
1069
|
+
branch: folder.branch,
|
|
1070
|
+
path: folder.path
|
|
1071
|
+
})),
|
|
1072
|
+
resources: pkg.resources.map((resource) => ({
|
|
1073
|
+
id: resource.id,
|
|
1074
|
+
name: resource.name,
|
|
1075
|
+
path: resource.path,
|
|
1076
|
+
kind: resource.kind,
|
|
1077
|
+
branch: resource.branch,
|
|
1078
|
+
...resource.kind === "component" ? { component: {
|
|
1079
|
+
displayList: resource.component.displayList.map((node) => ({
|
|
1080
|
+
id: node.id,
|
|
1081
|
+
name: node.name,
|
|
1082
|
+
kind: node.kind
|
|
1083
|
+
})),
|
|
1084
|
+
controllers: resource.component.controllers.map((controller) => ({
|
|
1085
|
+
name: controller.name,
|
|
1086
|
+
pages: controller.pages.map((page) => ({
|
|
1087
|
+
id: page.id,
|
|
1088
|
+
name: page.name
|
|
1089
|
+
}))
|
|
1090
|
+
})),
|
|
1091
|
+
transitions: resource.component.transitions.map((transition) => ({ name: transition.name }))
|
|
1092
|
+
} } : {}
|
|
1093
|
+
}))
|
|
1094
|
+
}))
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1054
1097
|
var ReadService = class {
|
|
1055
1098
|
constructor(context) {
|
|
1056
1099
|
this.context = context;
|
|
@@ -1067,6 +1110,35 @@ var ReadService = class {
|
|
|
1067
1110
|
revision: session.revision
|
|
1068
1111
|
});
|
|
1069
1112
|
}
|
|
1113
|
+
getProjectOutline(input) {
|
|
1114
|
+
const startedAt = Date.now();
|
|
1115
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
1116
|
+
if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
|
|
1117
|
+
return success("read", startedAt, toProjectOutline(session), {
|
|
1118
|
+
sessionId: session.sessionId,
|
|
1119
|
+
revision: session.revision
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
validateSession(input) {
|
|
1123
|
+
const startedAt = Date.now();
|
|
1124
|
+
const session = this.context.sessions.get(input.sessionId);
|
|
1125
|
+
if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
|
|
1126
|
+
const report = validateProject(session.project, {
|
|
1127
|
+
readDiagnostics: session.readDiagnostics,
|
|
1128
|
+
complete: session.readComplete,
|
|
1129
|
+
validateSources: true
|
|
1130
|
+
});
|
|
1131
|
+
return success("read", startedAt, report, {
|
|
1132
|
+
sessionId: session.sessionId,
|
|
1133
|
+
revision: session.revision,
|
|
1134
|
+
diagnostics: report.diagnostics.map(({ code, message, severity, path }) => ({
|
|
1135
|
+
code,
|
|
1136
|
+
message,
|
|
1137
|
+
severity,
|
|
1138
|
+
path
|
|
1139
|
+
}))
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1070
1142
|
};
|
|
1071
1143
|
//#endregion
|
|
1072
1144
|
//#region src/services/runtime-service.ts
|
|
@@ -1222,7 +1294,9 @@ var RuntimeService = class {
|
|
|
1222
1294
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1223
1295
|
canonicalPathKey
|
|
1224
1296
|
}));
|
|
1225
|
-
const
|
|
1297
|
+
const read = await new ProjectReader(createProjectReaderFileSystem(fileSystem)).readDetailed(fairyPath, { hydrateResourceBytes: true });
|
|
1298
|
+
if (!read.document) throw new Error(read.diagnostics[0]?.message ?? `Unable to read project: ${fairyPath}`);
|
|
1299
|
+
const document = read.document;
|
|
1226
1300
|
const project = liftDocumentToUamProject(document);
|
|
1227
1301
|
const sessionId = randomId();
|
|
1228
1302
|
const session = {
|
|
@@ -1234,6 +1308,8 @@ var RuntimeService = class {
|
|
|
1234
1308
|
sessionLock,
|
|
1235
1309
|
fileSystem,
|
|
1236
1310
|
project,
|
|
1311
|
+
readDiagnostics: read.diagnostics,
|
|
1312
|
+
readComplete: read.complete,
|
|
1237
1313
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1238
1314
|
revision: 0,
|
|
1239
1315
|
lastSavedRevision: 0,
|
|
@@ -1297,6 +1373,8 @@ var RuntimeService = class {
|
|
|
1297
1373
|
sessionLock: null,
|
|
1298
1374
|
fileSystem: storage?.fileSystem,
|
|
1299
1375
|
project: normalizeUamProject(input.project),
|
|
1376
|
+
readDiagnostics: [],
|
|
1377
|
+
readComplete: true,
|
|
1300
1378
|
uamFidelity: "full",
|
|
1301
1379
|
revision: 0,
|
|
1302
1380
|
lastSavedRevision: 0,
|
|
@@ -1380,6 +1458,8 @@ const BACKEND_METHODS = [
|
|
|
1380
1458
|
"openSession",
|
|
1381
1459
|
"openProjectSession",
|
|
1382
1460
|
"getSession",
|
|
1461
|
+
"getProjectOutline",
|
|
1462
|
+
"validateSession",
|
|
1383
1463
|
"applyTransaction",
|
|
1384
1464
|
"saveSession",
|
|
1385
1465
|
"materializeSession",
|
|
@@ -1401,14 +1481,16 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1401
1481
|
function createCapabilities() {
|
|
1402
1482
|
return {
|
|
1403
1483
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1404
|
-
capabilitySchemaVersion:
|
|
1484
|
+
capabilitySchemaVersion: 3,
|
|
1405
1485
|
transactionKernelOwner: "@openfairygui/core",
|
|
1406
1486
|
appSeamOwner: "@openfairygui/functions",
|
|
1407
1487
|
runtimeOwner: "@openfairygui/backend",
|
|
1408
1488
|
methods: BACKEND_METHODS,
|
|
1409
1489
|
read: {
|
|
1410
1490
|
capabilitySnapshot: true,
|
|
1411
|
-
sessionSnapshot: true
|
|
1491
|
+
sessionSnapshot: true,
|
|
1492
|
+
projectOutline: true,
|
|
1493
|
+
projectValidation: true
|
|
1412
1494
|
},
|
|
1413
1495
|
authoring: {
|
|
1414
1496
|
applyTransaction: true,
|
|
@@ -1548,6 +1630,12 @@ var BackendRuntime = class {
|
|
|
1548
1630
|
getSession(input) {
|
|
1549
1631
|
return this.readService.getSession(input);
|
|
1550
1632
|
}
|
|
1633
|
+
getProjectOutline(input) {
|
|
1634
|
+
return this.readService.getProjectOutline(input);
|
|
1635
|
+
}
|
|
1636
|
+
validateSession(input) {
|
|
1637
|
+
return this.readService.validateSession(input);
|
|
1638
|
+
}
|
|
1551
1639
|
async applyTransaction(input) {
|
|
1552
1640
|
return this.authoringService.applyTransaction(input);
|
|
1553
1641
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfairygui/backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-alpha.2",
|
|
4
4
|
"description": "FairyGUI Headless Authoring SDK — stateful backend runtime and session services.",
|
|
5
5
|
"author": "OpenFairyGUI Contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"runtime"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@openfairygui/core": "0.
|
|
56
|
-
"@openfairygui/functions": "0.
|
|
55
|
+
"@openfairygui/core": "0.3.0-alpha.2",
|
|
56
|
+
"@openfairygui/functions": "0.3.0-alpha.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"ava": "^7.0.0",
|
package/src/contracts.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const BACKEND_CONTRACT_VERSION = '1.1.0-p2' as const;
|
|
2
|
-
export const BACKEND_CAPABILITY_SCHEMA_VERSION =
|
|
2
|
+
export const BACKEND_CAPABILITY_SCHEMA_VERSION = 3 as const;
|
|
3
3
|
export const BACKEND_COMPATIBILITY_POLICY = {
|
|
4
4
|
incompatibleChange: 'requires contractVersion bump',
|
|
5
5
|
capabilitySchemaChange: 'requires capabilitySchemaVersion bump',
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,9 @@ export {
|
|
|
32
32
|
type BackendJobProgress,
|
|
33
33
|
type BackendJobSnapshot,
|
|
34
34
|
type BackendJobStatus,
|
|
35
|
+
type BackendProjectOutline,
|
|
36
|
+
type BackendProjectOutlinePackage,
|
|
37
|
+
type BackendProjectOutlineResource,
|
|
35
38
|
type BackendProjectSessionStorage,
|
|
36
39
|
type BackendResult,
|
|
37
40
|
BackendRuntime,
|
|
@@ -46,6 +49,7 @@ export {
|
|
|
46
49
|
type GetEventsInput,
|
|
47
50
|
type GetEventsSnapshot,
|
|
48
51
|
type GetJobInput,
|
|
52
|
+
type GetProjectOutlineInput,
|
|
49
53
|
type InProcessLockConflictError,
|
|
50
54
|
type ListJobsInput,
|
|
51
55
|
type MaterializeSessionInput,
|
|
@@ -59,6 +63,7 @@ export {
|
|
|
59
63
|
type SessionNotFoundError,
|
|
60
64
|
type SessionStaleWriteError,
|
|
61
65
|
type UamFidelityUnsupportedError,
|
|
66
|
+
type ValidateSessionInput,
|
|
62
67
|
} from './runtime.js';
|
|
63
68
|
export {
|
|
64
69
|
type BackendAsyncStorageAdapter,
|
|
@@ -16,6 +16,8 @@ const BACKEND_METHODS = [
|
|
|
16
16
|
'openSession',
|
|
17
17
|
'openProjectSession',
|
|
18
18
|
'getSession',
|
|
19
|
+
'getProjectOutline',
|
|
20
|
+
'validateSession',
|
|
19
21
|
'applyTransaction',
|
|
20
22
|
'saveSession',
|
|
21
23
|
'materializeSession',
|
|
@@ -47,6 +49,8 @@ export function createCapabilities(): BackendCapabilities {
|
|
|
47
49
|
read: {
|
|
48
50
|
capabilitySnapshot: true,
|
|
49
51
|
sessionSnapshot: true,
|
|
52
|
+
projectOutline: true,
|
|
53
|
+
projectValidation: true,
|
|
50
54
|
},
|
|
51
55
|
authoring: {
|
|
52
56
|
applyTransaction: true,
|
package/src/runtime/contracts.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
UamDisplayNodeKind,
|
|
3
|
+
UamProject,
|
|
4
|
+
UamResource,
|
|
5
|
+
UamTransactionOperation,
|
|
6
|
+
} from '@openfairygui/core/uam';
|
|
2
7
|
import type { ApplyUamTransactionAppError } from '@openfairygui/functions/uam';
|
|
3
8
|
import type {
|
|
4
9
|
BACKEND_CAPABILITY_SCHEMA_VERSION,
|
|
@@ -94,6 +99,8 @@ export interface BackendCapabilities {
|
|
|
94
99
|
'openSession',
|
|
95
100
|
'openProjectSession',
|
|
96
101
|
'getSession',
|
|
102
|
+
'getProjectOutline',
|
|
103
|
+
'validateSession',
|
|
97
104
|
'applyTransaction',
|
|
98
105
|
'saveSession',
|
|
99
106
|
'materializeSession',
|
|
@@ -108,6 +115,8 @@ export interface BackendCapabilities {
|
|
|
108
115
|
read: {
|
|
109
116
|
capabilitySnapshot: true;
|
|
110
117
|
sessionSnapshot: true;
|
|
118
|
+
projectOutline: true;
|
|
119
|
+
projectValidation: true;
|
|
111
120
|
};
|
|
112
121
|
authoring: {
|
|
113
122
|
applyTransaction: true;
|
|
@@ -178,6 +187,37 @@ export interface BackendSessionSnapshot {
|
|
|
178
187
|
capabilities: BackendCapabilities;
|
|
179
188
|
}
|
|
180
189
|
|
|
190
|
+
export interface BackendProjectOutline {
|
|
191
|
+
sessionId: string;
|
|
192
|
+
revision: number;
|
|
193
|
+
projectId: string;
|
|
194
|
+
projectType: number;
|
|
195
|
+
version: string;
|
|
196
|
+
branches: string[];
|
|
197
|
+
packages: BackendProjectOutlinePackage[];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface BackendProjectOutlinePackage {
|
|
201
|
+
id: string;
|
|
202
|
+
name: string;
|
|
203
|
+
branchNames: string[];
|
|
204
|
+
folders: Array<{ branch: string; path: string }>;
|
|
205
|
+
resources: BackendProjectOutlineResource[];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface BackendProjectOutlineResource {
|
|
209
|
+
id: string;
|
|
210
|
+
name: string;
|
|
211
|
+
path: string;
|
|
212
|
+
kind: UamResource['kind'];
|
|
213
|
+
branch: string;
|
|
214
|
+
component?: {
|
|
215
|
+
displayList: Array<{ id: string; name: string; kind: UamDisplayNodeKind }>;
|
|
216
|
+
controllers: Array<{ name: string; pages: Array<{ id: string; name: string }> }>;
|
|
217
|
+
transitions: Array<{ name: string }>;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
181
221
|
export interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
|
|
182
222
|
mode: 'fullProject';
|
|
183
223
|
reason?: string;
|
|
@@ -476,6 +516,14 @@ export interface ApplySessionTransactionInput {
|
|
|
476
516
|
operations: UamTransactionOperation[];
|
|
477
517
|
}
|
|
478
518
|
|
|
519
|
+
export interface GetProjectOutlineInput {
|
|
520
|
+
sessionId: string;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export interface ValidateSessionInput {
|
|
524
|
+
sessionId: string;
|
|
525
|
+
}
|
|
526
|
+
|
|
479
527
|
export interface OpenProjectSessionInput {
|
|
480
528
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
481
529
|
project: UamProject;
|