@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 CHANGED
@@ -28,6 +28,8 @@ It also provides:
28
28
  - polling runtime events with per-runtime monotonic sequence and bounded retention
29
29
  - `cache.refresh` in-memory jobs with cooperative cancel and terminal retention
30
30
  - revision-bound derived read-only cache snapshots
31
+ - revision-bound project identity outlines for transaction planning
32
+ - revision-bound read-only project validation reports
31
33
  - explicit Node bridge boundaries for publish/restore
32
34
 
33
35
  It does **not** redefine transaction grammar or expose `Document`.
@@ -67,6 +69,12 @@ const runtime = new BackendRuntime();
67
69
  const opened = runtime.openProjectSession({ project: uamProject });
68
70
  if (!opened.ok) throw new Error(opened.error.message);
69
71
 
72
+ const outline = runtime.getProjectOutline({ sessionId: opened.data.sessionId });
73
+ if (!outline.ok) throw new Error(outline.error.message);
74
+
75
+ const validation = runtime.validateSession({ sessionId: opened.data.sessionId });
76
+ if (!validation.ok) throw new Error(validation.error.message);
77
+
70
78
  const applied = await runtime.applyTransaction({
71
79
  sessionId: opened.data.sessionId,
72
80
  expectedRevision: opened.data.revision,
package/dist/index.cjs CHANGED
@@ -2,9 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _openfairygui_core_uam = require("@openfairygui/core/uam");
3
3
  let _openfairygui_functions_uam = require("@openfairygui/functions/uam");
4
4
  let _openfairygui_core_project_io = require("@openfairygui/core/project-io");
5
+ let _openfairygui_functions = require("@openfairygui/functions");
5
6
  //#region src/contracts.ts
6
7
  const BACKEND_CONTRACT_VERSION = "1.1.0-p2";
7
- const BACKEND_CAPABILITY_SCHEMA_VERSION = 2;
8
+ const BACKEND_CAPABILITY_SCHEMA_VERSION = 3;
8
9
  const BACKEND_COMPATIBILITY_POLICY = {
9
10
  incompatibleChange: "requires contractVersion bump",
10
11
  capabilitySchemaChange: "requires capabilitySchemaVersion bump",
@@ -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: 2
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 = (0, _openfairygui_functions.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 document = await new _openfairygui_core_project_io.ProjectReader(createProjectReaderFileSystem(fileSystem)).read(fairyPath, { hydrateResourceBytes: true });
1297
+ const read = await new _openfairygui_core_project_io.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 = (0, _openfairygui_core_uam.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: (0, _openfairygui_core_uam.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: 2,
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/dist/index.d.cts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
2
- import { UamProject, UamTransactionOperation } from "@openfairygui/core/uam";
2
+ import { ProjectValidationReport } from "@openfairygui/core";
3
+ import { UamDisplayNodeKind, UamProject, UamResource, UamTransactionOperation } from "@openfairygui/core/uam";
3
4
  import { FileSystem } from "@openfairygui/core/project-io";
4
5
 
5
6
  //#region src/contracts.d.ts
6
7
  declare const BACKEND_CONTRACT_VERSION: "1.1.0-p2";
7
- declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 2;
8
+ declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 3;
8
9
  declare const BACKEND_COMPATIBILITY_POLICY: {
9
10
  readonly incompatibleChange: "requires contractVersion bump";
10
11
  readonly capabilitySchemaChange: "requires capabilitySchemaVersion bump";
@@ -130,10 +131,12 @@ interface BackendCapabilities {
130
131
  transactionKernelOwner: '@openfairygui/core';
131
132
  appSeamOwner: '@openfairygui/functions';
132
133
  runtimeOwner: '@openfairygui/backend';
133
- methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
134
+ methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'getProjectOutline', 'validateSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
134
135
  read: {
135
136
  capabilitySnapshot: true;
136
137
  sessionSnapshot: true;
138
+ projectOutline: true;
139
+ projectValidation: true;
137
140
  };
138
141
  authoring: {
139
142
  applyTransaction: true;
@@ -202,6 +205,49 @@ interface BackendSessionSnapshot {
202
205
  lockHeld: boolean;
203
206
  capabilities: BackendCapabilities;
204
207
  }
208
+ interface BackendProjectOutline {
209
+ sessionId: string;
210
+ revision: number;
211
+ projectId: string;
212
+ projectType: number;
213
+ version: string;
214
+ branches: string[];
215
+ packages: BackendProjectOutlinePackage[];
216
+ }
217
+ interface BackendProjectOutlinePackage {
218
+ id: string;
219
+ name: string;
220
+ branchNames: string[];
221
+ folders: Array<{
222
+ branch: string;
223
+ path: string;
224
+ }>;
225
+ resources: BackendProjectOutlineResource[];
226
+ }
227
+ interface BackendProjectOutlineResource {
228
+ id: string;
229
+ name: string;
230
+ path: string;
231
+ kind: UamResource['kind'];
232
+ branch: string;
233
+ component?: {
234
+ displayList: Array<{
235
+ id: string;
236
+ name: string;
237
+ kind: UamDisplayNodeKind;
238
+ }>;
239
+ controllers: Array<{
240
+ name: string;
241
+ pages: Array<{
242
+ id: string;
243
+ name: string;
244
+ }>;
245
+ }>;
246
+ transitions: Array<{
247
+ name: string;
248
+ }>;
249
+ };
250
+ }
205
251
  interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
206
252
  mode: 'fullProject';
207
253
  reason?: string;
@@ -427,6 +473,12 @@ interface ApplySessionTransactionInput {
427
473
  expectedRevision: number;
428
474
  operations: UamTransactionOperation[];
429
475
  }
476
+ interface GetProjectOutlineInput {
477
+ sessionId: string;
478
+ }
479
+ interface ValidateSessionInput {
480
+ sessionId: string;
481
+ }
430
482
  interface OpenProjectSessionInput {
431
483
  /** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
432
484
  project: UamProject;
@@ -490,6 +542,8 @@ declare class BackendRuntime {
490
542
  getSession(input: {
491
543
  sessionId: string;
492
544
  }): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
545
+ getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
546
+ validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
493
547
  applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
494
548
  saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
495
549
  materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
@@ -542,4 +596,4 @@ interface BackendAsyncStorageAdapter {
542
596
  type BackendStorageFileSystem = BackendFileSystem & FileSystem;
543
597
  declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
544
598
  //#endregion
545
- export { type AdvisoryLockConflictError, type ApplySessionTransactionInput, BACKEND_CAPABILITY_SCHEMA_VERSION, BACKEND_COMPATIBILITY_POLICY, BACKEND_CONTRACT_VERSION, type BackendArtifactBridgeCapability, type BackendAsyncStorageAdapter, type BackendCacheEntry, type BackendCacheSnapshot, type BackendCapabilities, type BackendCapabilityManifest, type BackendCapabilityUnavailableError, type BackendDiagnostic, type BackendError, type BackendEvent, type BackendEventKind, type BackendFailure, type BackendFileStat, type BackendFileSystem, type BackendHostAdapter, type BackendJobErrors, type BackendJobKind, type BackendJobListSnapshot, type BackendJobListStatusFilter, type BackendJobNotCancellableError, type BackendJobNotFoundError, type BackendJobProgress, type BackendJobSnapshot, type BackendJobStatus, type BackendMessage, type BackendProjectSessionStorage, type BackendResponseMeta, type BackendResult, BackendRuntime, type BackendRuntimeOptions, type BackendSessionLock, type BackendSessionSnapshot, type BackendStage, type BackendStorageFileSystem, type BackendStorageStatLike, type BackendSuccess, type CacheRefreshFailedError, type CancelJobInput, type EventCursorInvalidError, type GetCacheSnapshotInput, type GetEventsInput, type GetEventsSnapshot, type GetJobInput, type InProcessLockConflictError, type ListJobsInput, type MaterializeSessionInput, type MaterializeSessionSnapshot, type MaterializeValidationFailedError, type MaterializeWriteFailedError, type OpenProjectSessionInput, type RefreshCacheInput, type SavePartialFailureError, type SaveSessionInput, type SessionNotFoundError, type SessionStaleWriteError, type UamFidelityUnsupportedError, createBackendStorageFileSystem };
599
+ export { type AdvisoryLockConflictError, type ApplySessionTransactionInput, BACKEND_CAPABILITY_SCHEMA_VERSION, BACKEND_COMPATIBILITY_POLICY, BACKEND_CONTRACT_VERSION, type BackendArtifactBridgeCapability, type BackendAsyncStorageAdapter, type BackendCacheEntry, type BackendCacheSnapshot, type BackendCapabilities, type BackendCapabilityManifest, type BackendCapabilityUnavailableError, type BackendDiagnostic, type BackendError, type BackendEvent, type BackendEventKind, type BackendFailure, type BackendFileStat, type BackendFileSystem, type BackendHostAdapter, type BackendJobErrors, type BackendJobKind, type BackendJobListSnapshot, type BackendJobListStatusFilter, type BackendJobNotCancellableError, type BackendJobNotFoundError, type BackendJobProgress, type BackendJobSnapshot, type BackendJobStatus, type BackendMessage, type BackendProjectOutline, type BackendProjectOutlinePackage, type BackendProjectOutlineResource, type BackendProjectSessionStorage, type BackendResponseMeta, type BackendResult, BackendRuntime, type BackendRuntimeOptions, type BackendSessionLock, type BackendSessionSnapshot, type BackendStage, type BackendStorageFileSystem, type BackendStorageStatLike, type BackendSuccess, type CacheRefreshFailedError, type CancelJobInput, type EventCursorInvalidError, type GetCacheSnapshotInput, type GetEventsInput, type GetEventsSnapshot, type GetJobInput, type GetProjectOutlineInput, type InProcessLockConflictError, type ListJobsInput, type MaterializeSessionInput, type MaterializeSessionSnapshot, type MaterializeValidationFailedError, type MaterializeWriteFailedError, type OpenProjectSessionInput, type RefreshCacheInput, type SavePartialFailureError, type SaveSessionInput, type SessionNotFoundError, type SessionStaleWriteError, type UamFidelityUnsupportedError, type ValidateSessionInput, createBackendStorageFileSystem };
package/dist/index.d.mts CHANGED
@@ -1,10 +1,11 @@
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
3
  import { FileSystem } from "@openfairygui/core/project-io";
4
+ import { ProjectValidationReport } from "@openfairygui/core";
4
5
 
5
6
  //#region src/contracts.d.ts
6
7
  declare const BACKEND_CONTRACT_VERSION: "1.1.0-p2";
7
- declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 2;
8
+ declare const BACKEND_CAPABILITY_SCHEMA_VERSION: 3;
8
9
  declare const BACKEND_COMPATIBILITY_POLICY: {
9
10
  readonly incompatibleChange: "requires contractVersion bump";
10
11
  readonly capabilitySchemaChange: "requires capabilitySchemaVersion bump";
@@ -130,10 +131,12 @@ interface BackendCapabilities {
130
131
  transactionKernelOwner: '@openfairygui/core';
131
132
  appSeamOwner: '@openfairygui/functions';
132
133
  runtimeOwner: '@openfairygui/backend';
133
- methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
134
+ methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'getProjectOutline', 'validateSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
134
135
  read: {
135
136
  capabilitySnapshot: true;
136
137
  sessionSnapshot: true;
138
+ projectOutline: true;
139
+ projectValidation: true;
137
140
  };
138
141
  authoring: {
139
142
  applyTransaction: true;
@@ -202,6 +205,49 @@ interface BackendSessionSnapshot {
202
205
  lockHeld: boolean;
203
206
  capabilities: BackendCapabilities;
204
207
  }
208
+ interface BackendProjectOutline {
209
+ sessionId: string;
210
+ revision: number;
211
+ projectId: string;
212
+ projectType: number;
213
+ version: string;
214
+ branches: string[];
215
+ packages: BackendProjectOutlinePackage[];
216
+ }
217
+ interface BackendProjectOutlinePackage {
218
+ id: string;
219
+ name: string;
220
+ branchNames: string[];
221
+ folders: Array<{
222
+ branch: string;
223
+ path: string;
224
+ }>;
225
+ resources: BackendProjectOutlineResource[];
226
+ }
227
+ interface BackendProjectOutlineResource {
228
+ id: string;
229
+ name: string;
230
+ path: string;
231
+ kind: UamResource['kind'];
232
+ branch: string;
233
+ component?: {
234
+ displayList: Array<{
235
+ id: string;
236
+ name: string;
237
+ kind: UamDisplayNodeKind;
238
+ }>;
239
+ controllers: Array<{
240
+ name: string;
241
+ pages: Array<{
242
+ id: string;
243
+ name: string;
244
+ }>;
245
+ }>;
246
+ transitions: Array<{
247
+ name: string;
248
+ }>;
249
+ };
250
+ }
205
251
  interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
206
252
  mode: 'fullProject';
207
253
  reason?: string;
@@ -427,6 +473,12 @@ interface ApplySessionTransactionInput {
427
473
  expectedRevision: number;
428
474
  operations: UamTransactionOperation[];
429
475
  }
476
+ interface GetProjectOutlineInput {
477
+ sessionId: string;
478
+ }
479
+ interface ValidateSessionInput {
480
+ sessionId: string;
481
+ }
430
482
  interface OpenProjectSessionInput {
431
483
  /** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
432
484
  project: UamProject;
@@ -490,6 +542,8 @@ declare class BackendRuntime {
490
542
  getSession(input: {
491
543
  sessionId: string;
492
544
  }): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
545
+ getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
546
+ validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
493
547
  applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
494
548
  saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
495
549
  materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
@@ -542,4 +596,4 @@ interface BackendAsyncStorageAdapter {
542
596
  type BackendStorageFileSystem = BackendFileSystem & FileSystem;
543
597
  declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
544
598
  //#endregion
545
- export { type AdvisoryLockConflictError, type ApplySessionTransactionInput, BACKEND_CAPABILITY_SCHEMA_VERSION, BACKEND_COMPATIBILITY_POLICY, BACKEND_CONTRACT_VERSION, type BackendArtifactBridgeCapability, type BackendAsyncStorageAdapter, type BackendCacheEntry, type BackendCacheSnapshot, type BackendCapabilities, type BackendCapabilityManifest, type BackendCapabilityUnavailableError, type BackendDiagnostic, type BackendError, type BackendEvent, type BackendEventKind, type BackendFailure, type BackendFileStat, type BackendFileSystem, type BackendHostAdapter, type BackendJobErrors, type BackendJobKind, type BackendJobListSnapshot, type BackendJobListStatusFilter, type BackendJobNotCancellableError, type BackendJobNotFoundError, type BackendJobProgress, type BackendJobSnapshot, type BackendJobStatus, type BackendMessage, type BackendProjectSessionStorage, type BackendResponseMeta, type BackendResult, BackendRuntime, type BackendRuntimeOptions, type BackendSessionLock, type BackendSessionSnapshot, type BackendStage, type BackendStorageFileSystem, type BackendStorageStatLike, type BackendSuccess, type CacheRefreshFailedError, type CancelJobInput, type EventCursorInvalidError, type GetCacheSnapshotInput, type GetEventsInput, type GetEventsSnapshot, type GetJobInput, type InProcessLockConflictError, type ListJobsInput, type MaterializeSessionInput, type MaterializeSessionSnapshot, type MaterializeValidationFailedError, type MaterializeWriteFailedError, type OpenProjectSessionInput, type RefreshCacheInput, type SavePartialFailureError, type SaveSessionInput, type SessionNotFoundError, type SessionStaleWriteError, type UamFidelityUnsupportedError, createBackendStorageFileSystem };
599
+ export { type AdvisoryLockConflictError, type ApplySessionTransactionInput, BACKEND_CAPABILITY_SCHEMA_VERSION, BACKEND_COMPATIBILITY_POLICY, BACKEND_CONTRACT_VERSION, type BackendArtifactBridgeCapability, type BackendAsyncStorageAdapter, type BackendCacheEntry, type BackendCacheSnapshot, type BackendCapabilities, type BackendCapabilityManifest, type BackendCapabilityUnavailableError, type BackendDiagnostic, type BackendError, type BackendEvent, type BackendEventKind, type BackendFailure, type BackendFileStat, type BackendFileSystem, type BackendHostAdapter, type BackendJobErrors, type BackendJobKind, type BackendJobListSnapshot, type BackendJobListStatusFilter, type BackendJobNotCancellableError, type BackendJobNotFoundError, type BackendJobProgress, type BackendJobSnapshot, type BackendJobStatus, type BackendMessage, type BackendProjectOutline, type BackendProjectOutlinePackage, type BackendProjectOutlineResource, type BackendProjectSessionStorage, type BackendResponseMeta, type BackendResult, BackendRuntime, type BackendRuntimeOptions, type BackendSessionLock, type BackendSessionSnapshot, type BackendStage, type BackendStorageFileSystem, type BackendStorageStatLike, type BackendSuccess, type CacheRefreshFailedError, type CancelJobInput, type EventCursorInvalidError, type GetCacheSnapshotInput, type GetEventsInput, type GetEventsSnapshot, type GetJobInput, type GetProjectOutlineInput, type InProcessLockConflictError, type ListJobsInput, type MaterializeSessionInput, type MaterializeSessionSnapshot, type MaterializeValidationFailedError, type MaterializeWriteFailedError, type OpenProjectSessionInput, type RefreshCacheInput, type SavePartialFailureError, type SaveSessionInput, type SessionNotFoundError, type SessionStaleWriteError, type UamFidelityUnsupportedError, type ValidateSessionInput, createBackendStorageFileSystem };
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import { UAM_SUPPORTED_MATERIALIZATION_SCOPE, UAM_SUPPORTED_TRANSACTION_SCOPE, commitUamProjectSourcePaths, liftDocumentToUamProject, materializeUamProject, normalizeUamProject, staleBranchDirectories, staleResourceFolders, staleSourceFiles, validateUamProject } from "@openfairygui/core/uam";
2
2
  import { applyUamTransactionAppAsync } from "@openfairygui/functions/uam";
3
3
  import { ProjectReader, ProjectWriter } from "@openfairygui/core/project-io";
4
+ import { validateProject } from "@openfairygui/functions";
4
5
  //#region src/contracts.ts
5
6
  const BACKEND_CONTRACT_VERSION = "1.1.0-p2";
6
- const BACKEND_CAPABILITY_SCHEMA_VERSION = 2;
7
+ const BACKEND_CAPABILITY_SCHEMA_VERSION = 3;
7
8
  const BACKEND_COMPATIBILITY_POLICY = {
8
9
  incompatibleChange: "requires contractVersion bump",
9
10
  capabilitySchemaChange: "requires capabilitySchemaVersion bump",
@@ -96,7 +97,7 @@ function createMeta(stage, startedAt, options) {
96
97
  diagnostics: options?.diagnostics ?? [],
97
98
  stage,
98
99
  contractVersion: BACKEND_CONTRACT_VERSION,
99
- capabilitySchemaVersion: 2
100
+ capabilitySchemaVersion: 3
100
101
  };
101
102
  }
102
103
  function success(stage, startedAt, data, options) {
@@ -1050,6 +1051,48 @@ var JobService = class {
1050
1051
  };
1051
1052
  //#endregion
1052
1053
  //#region src/services/read-service.ts
1054
+ function toProjectOutline(session) {
1055
+ const project = session.project;
1056
+ return {
1057
+ sessionId: session.sessionId,
1058
+ revision: session.revision,
1059
+ projectId: project.projectId,
1060
+ projectType: project.projectType,
1061
+ version: project.version,
1062
+ branches: [...project.branches],
1063
+ packages: project.packages.map((pkg) => ({
1064
+ id: pkg.id,
1065
+ name: pkg.name,
1066
+ branchNames: [...pkg.branchNames],
1067
+ folders: pkg.folders.map((folder) => ({
1068
+ branch: folder.branch,
1069
+ path: folder.path
1070
+ })),
1071
+ resources: pkg.resources.map((resource) => ({
1072
+ id: resource.id,
1073
+ name: resource.name,
1074
+ path: resource.path,
1075
+ kind: resource.kind,
1076
+ branch: resource.branch,
1077
+ ...resource.kind === "component" ? { component: {
1078
+ displayList: resource.component.displayList.map((node) => ({
1079
+ id: node.id,
1080
+ name: node.name,
1081
+ kind: node.kind
1082
+ })),
1083
+ controllers: resource.component.controllers.map((controller) => ({
1084
+ name: controller.name,
1085
+ pages: controller.pages.map((page) => ({
1086
+ id: page.id,
1087
+ name: page.name
1088
+ }))
1089
+ })),
1090
+ transitions: resource.component.transitions.map((transition) => ({ name: transition.name }))
1091
+ } } : {}
1092
+ }))
1093
+ }))
1094
+ };
1095
+ }
1053
1096
  var ReadService = class {
1054
1097
  constructor(context) {
1055
1098
  this.context = context;
@@ -1066,6 +1109,35 @@ var ReadService = class {
1066
1109
  revision: session.revision
1067
1110
  });
1068
1111
  }
1112
+ getProjectOutline(input) {
1113
+ const startedAt = Date.now();
1114
+ const session = this.context.sessions.get(input.sessionId);
1115
+ if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
1116
+ return success("read", startedAt, toProjectOutline(session), {
1117
+ sessionId: session.sessionId,
1118
+ revision: session.revision
1119
+ });
1120
+ }
1121
+ validateSession(input) {
1122
+ const startedAt = Date.now();
1123
+ const session = this.context.sessions.get(input.sessionId);
1124
+ if (!session || session.closed) return failure("read", startedAt, createSessionNotFoundError(input.sessionId));
1125
+ const report = validateProject(session.project, {
1126
+ readDiagnostics: session.readDiagnostics,
1127
+ complete: session.readComplete,
1128
+ validateSources: true
1129
+ });
1130
+ return success("read", startedAt, report, {
1131
+ sessionId: session.sessionId,
1132
+ revision: session.revision,
1133
+ diagnostics: report.diagnostics.map(({ code, message, severity, path }) => ({
1134
+ code,
1135
+ message,
1136
+ severity,
1137
+ path
1138
+ }))
1139
+ });
1140
+ }
1069
1141
  };
1070
1142
  //#endregion
1071
1143
  //#region src/services/runtime-service.ts
@@ -1221,7 +1293,9 @@ var RuntimeService = class {
1221
1293
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1222
1294
  canonicalPathKey
1223
1295
  }));
1224
- const document = await new ProjectReader(createProjectReaderFileSystem(fileSystem)).read(fairyPath, { hydrateResourceBytes: true });
1296
+ const read = await new ProjectReader(createProjectReaderFileSystem(fileSystem)).readDetailed(fairyPath, { hydrateResourceBytes: true });
1297
+ if (!read.document) throw new Error(read.diagnostics[0]?.message ?? `Unable to read project: ${fairyPath}`);
1298
+ const document = read.document;
1225
1299
  const project = liftDocumentToUamProject(document);
1226
1300
  const sessionId = randomId();
1227
1301
  const session = {
@@ -1233,6 +1307,8 @@ var RuntimeService = class {
1233
1307
  sessionLock,
1234
1308
  fileSystem,
1235
1309
  project,
1310
+ readDiagnostics: read.diagnostics,
1311
+ readComplete: read.complete,
1236
1312
  uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
1237
1313
  revision: 0,
1238
1314
  lastSavedRevision: 0,
@@ -1296,6 +1372,8 @@ var RuntimeService = class {
1296
1372
  sessionLock: null,
1297
1373
  fileSystem: storage?.fileSystem,
1298
1374
  project: normalizeUamProject(input.project),
1375
+ readDiagnostics: [],
1376
+ readComplete: true,
1299
1377
  uamFidelity: "full",
1300
1378
  revision: 0,
1301
1379
  lastSavedRevision: 0,
@@ -1379,6 +1457,8 @@ const BACKEND_METHODS = [
1379
1457
  "openSession",
1380
1458
  "openProjectSession",
1381
1459
  "getSession",
1460
+ "getProjectOutline",
1461
+ "validateSession",
1382
1462
  "applyTransaction",
1383
1463
  "saveSession",
1384
1464
  "materializeSession",
@@ -1400,14 +1480,16 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
1400
1480
  function createCapabilities() {
1401
1481
  return {
1402
1482
  contractVersion: BACKEND_CONTRACT_VERSION,
1403
- capabilitySchemaVersion: 2,
1483
+ capabilitySchemaVersion: 3,
1404
1484
  transactionKernelOwner: "@openfairygui/core",
1405
1485
  appSeamOwner: "@openfairygui/functions",
1406
1486
  runtimeOwner: "@openfairygui/backend",
1407
1487
  methods: BACKEND_METHODS,
1408
1488
  read: {
1409
1489
  capabilitySnapshot: true,
1410
- sessionSnapshot: true
1490
+ sessionSnapshot: true,
1491
+ projectOutline: true,
1492
+ projectValidation: true
1411
1493
  },
1412
1494
  authoring: {
1413
1495
  applyTransaction: true,
@@ -1547,6 +1629,12 @@ var BackendRuntime = class {
1547
1629
  getSession(input) {
1548
1630
  return this.readService.getSession(input);
1549
1631
  }
1632
+ getProjectOutline(input) {
1633
+ return this.readService.getProjectOutline(input);
1634
+ }
1635
+ validateSession(input) {
1636
+ return this.readService.validateSession(input);
1637
+ }
1550
1638
  async applyTransaction(input) {
1551
1639
  return this.authoringService.applyTransaction(input);
1552
1640
  }