@openfairygui/backend 0.3.0-alpha.1 → 0.3.0-alpha.3
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 +4 -0
- package/dist/index.cjs +37 -5
- package/dist/index.d.cts +9 -3
- package/dist/index.d.mts +9 -3
- package/dist/index.mjs +37 -5
- package/dist/node.cjs +36 -4
- package/dist/node.d.cts +8 -2
- package/dist/node.d.mts +8 -2
- package/dist/node.mjs +36 -4
- package/package.json +3 -3
- package/src/contracts.ts +1 -1
- package/src/index.ts +1 -0
- package/src/runtime/capabilities.ts +2 -0
- package/src/runtime/contracts.ts +6 -0
- package/src/runtime.ts +8 -0
- package/src/services/context.ts +2 -0
- package/src/services/read-service.ts +22 -0
- package/src/services/runtime-service.ts +7 -1
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ It also provides:
|
|
|
29
29
|
- `cache.refresh` in-memory jobs with cooperative cancel and terminal retention
|
|
30
30
|
- revision-bound derived read-only cache snapshots
|
|
31
31
|
- revision-bound project identity outlines for transaction planning
|
|
32
|
+
- revision-bound read-only project validation reports
|
|
32
33
|
- explicit Node bridge boundaries for publish/restore
|
|
33
34
|
|
|
34
35
|
It does **not** redefine transaction grammar or expose `Document`.
|
|
@@ -71,6 +72,9 @@ if (!opened.ok) throw new Error(opened.error.message);
|
|
|
71
72
|
const outline = runtime.getProjectOutline({ sessionId: opened.data.sessionId });
|
|
72
73
|
if (!outline.ok) throw new Error(outline.error.message);
|
|
73
74
|
|
|
75
|
+
const validation = runtime.validateSession({ sessionId: opened.data.sessionId });
|
|
76
|
+
if (!validation.ok) throw new Error(validation.error.message);
|
|
77
|
+
|
|
74
78
|
const applied = await runtime.applyTransaction({
|
|
75
79
|
sessionId: opened.data.sessionId,
|
|
76
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 =
|
|
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:
|
|
101
|
+
capabilitySchemaVersion: 3
|
|
101
102
|
};
|
|
102
103
|
}
|
|
103
104
|
function success(stage, startedAt, data, options) {
|
|
@@ -1118,6 +1119,26 @@ var ReadService = class {
|
|
|
1118
1119
|
revision: session.revision
|
|
1119
1120
|
});
|
|
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
|
+
}
|
|
1121
1142
|
};
|
|
1122
1143
|
//#endregion
|
|
1123
1144
|
//#region src/services/runtime-service.ts
|
|
@@ -1273,7 +1294,9 @@ var RuntimeService = class {
|
|
|
1273
1294
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1274
1295
|
canonicalPathKey
|
|
1275
1296
|
}));
|
|
1276
|
-
const
|
|
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;
|
|
1277
1300
|
const project = (0, _openfairygui_core_uam.liftDocumentToUamProject)(document);
|
|
1278
1301
|
const sessionId = randomId();
|
|
1279
1302
|
const session = {
|
|
@@ -1285,6 +1308,8 @@ var RuntimeService = class {
|
|
|
1285
1308
|
sessionLock,
|
|
1286
1309
|
fileSystem,
|
|
1287
1310
|
project,
|
|
1311
|
+
readDiagnostics: read.diagnostics,
|
|
1312
|
+
readComplete: read.complete,
|
|
1288
1313
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1289
1314
|
revision: 0,
|
|
1290
1315
|
lastSavedRevision: 0,
|
|
@@ -1348,6 +1373,8 @@ var RuntimeService = class {
|
|
|
1348
1373
|
sessionLock: null,
|
|
1349
1374
|
fileSystem: storage?.fileSystem,
|
|
1350
1375
|
project: (0, _openfairygui_core_uam.normalizeUamProject)(input.project),
|
|
1376
|
+
readDiagnostics: [],
|
|
1377
|
+
readComplete: true,
|
|
1351
1378
|
uamFidelity: "full",
|
|
1352
1379
|
revision: 0,
|
|
1353
1380
|
lastSavedRevision: 0,
|
|
@@ -1432,6 +1459,7 @@ const BACKEND_METHODS = [
|
|
|
1432
1459
|
"openProjectSession",
|
|
1433
1460
|
"getSession",
|
|
1434
1461
|
"getProjectOutline",
|
|
1462
|
+
"validateSession",
|
|
1435
1463
|
"applyTransaction",
|
|
1436
1464
|
"saveSession",
|
|
1437
1465
|
"materializeSession",
|
|
@@ -1453,7 +1481,7 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1453
1481
|
function createCapabilities() {
|
|
1454
1482
|
return {
|
|
1455
1483
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1456
|
-
capabilitySchemaVersion:
|
|
1484
|
+
capabilitySchemaVersion: 3,
|
|
1457
1485
|
transactionKernelOwner: "@openfairygui/core",
|
|
1458
1486
|
appSeamOwner: "@openfairygui/functions",
|
|
1459
1487
|
runtimeOwner: "@openfairygui/backend",
|
|
@@ -1461,7 +1489,8 @@ function createCapabilities() {
|
|
|
1461
1489
|
read: {
|
|
1462
1490
|
capabilitySnapshot: true,
|
|
1463
1491
|
sessionSnapshot: true,
|
|
1464
|
-
projectOutline: true
|
|
1492
|
+
projectOutline: true,
|
|
1493
|
+
projectValidation: true
|
|
1465
1494
|
},
|
|
1466
1495
|
authoring: {
|
|
1467
1496
|
applyTransaction: true,
|
|
@@ -1604,6 +1633,9 @@ var BackendRuntime = class {
|
|
|
1604
1633
|
getProjectOutline(input) {
|
|
1605
1634
|
return this.readService.getProjectOutline(input);
|
|
1606
1635
|
}
|
|
1636
|
+
validateSession(input) {
|
|
1637
|
+
return this.readService.validateSession(input);
|
|
1638
|
+
}
|
|
1607
1639
|
async applyTransaction(input) {
|
|
1608
1640
|
return this.authoringService.applyTransaction(input);
|
|
1609
1641
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
|
|
2
|
+
import { ProjectValidationReport } from "@openfairygui/core";
|
|
2
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:
|
|
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,11 +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', 'getProjectOutline', '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;
|
|
137
138
|
projectOutline: true;
|
|
139
|
+
projectValidation: true;
|
|
138
140
|
};
|
|
139
141
|
authoring: {
|
|
140
142
|
applyTransaction: true;
|
|
@@ -474,6 +476,9 @@ interface ApplySessionTransactionInput {
|
|
|
474
476
|
interface GetProjectOutlineInput {
|
|
475
477
|
sessionId: string;
|
|
476
478
|
}
|
|
479
|
+
interface ValidateSessionInput {
|
|
480
|
+
sessionId: string;
|
|
481
|
+
}
|
|
477
482
|
interface OpenProjectSessionInput {
|
|
478
483
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
479
484
|
project: UamProject;
|
|
@@ -538,6 +543,7 @@ declare class BackendRuntime {
|
|
|
538
543
|
sessionId: string;
|
|
539
544
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
540
545
|
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
546
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
541
547
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
542
548
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
543
549
|
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
@@ -590,4 +596,4 @@ interface BackendAsyncStorageAdapter {
|
|
|
590
596
|
type BackendStorageFileSystem = BackendFileSystem & FileSystem;
|
|
591
597
|
declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
|
|
592
598
|
//#endregion
|
|
593
|
-
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, 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
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:
|
|
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,11 +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', 'getProjectOutline', '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;
|
|
137
138
|
projectOutline: true;
|
|
139
|
+
projectValidation: true;
|
|
138
140
|
};
|
|
139
141
|
authoring: {
|
|
140
142
|
applyTransaction: true;
|
|
@@ -474,6 +476,9 @@ interface ApplySessionTransactionInput {
|
|
|
474
476
|
interface GetProjectOutlineInput {
|
|
475
477
|
sessionId: string;
|
|
476
478
|
}
|
|
479
|
+
interface ValidateSessionInput {
|
|
480
|
+
sessionId: string;
|
|
481
|
+
}
|
|
477
482
|
interface OpenProjectSessionInput {
|
|
478
483
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
479
484
|
project: UamProject;
|
|
@@ -538,6 +543,7 @@ declare class BackendRuntime {
|
|
|
538
543
|
sessionId: string;
|
|
539
544
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
540
545
|
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
546
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
541
547
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
542
548
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
543
549
|
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
@@ -590,4 +596,4 @@ interface BackendAsyncStorageAdapter {
|
|
|
590
596
|
type BackendStorageFileSystem = BackendFileSystem & FileSystem;
|
|
591
597
|
declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
|
|
592
598
|
//#endregion
|
|
593
|
-
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, 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 =
|
|
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:
|
|
100
|
+
capabilitySchemaVersion: 3
|
|
100
101
|
};
|
|
101
102
|
}
|
|
102
103
|
function success(stage, startedAt, data, options) {
|
|
@@ -1117,6 +1118,26 @@ var ReadService = class {
|
|
|
1117
1118
|
revision: session.revision
|
|
1118
1119
|
});
|
|
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
|
+
}
|
|
1120
1141
|
};
|
|
1121
1142
|
//#endregion
|
|
1122
1143
|
//#region src/services/runtime-service.ts
|
|
@@ -1272,7 +1293,9 @@ var RuntimeService = class {
|
|
|
1272
1293
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1273
1294
|
canonicalPathKey
|
|
1274
1295
|
}));
|
|
1275
|
-
const
|
|
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;
|
|
1276
1299
|
const project = liftDocumentToUamProject(document);
|
|
1277
1300
|
const sessionId = randomId();
|
|
1278
1301
|
const session = {
|
|
@@ -1284,6 +1307,8 @@ var RuntimeService = class {
|
|
|
1284
1307
|
sessionLock,
|
|
1285
1308
|
fileSystem,
|
|
1286
1309
|
project,
|
|
1310
|
+
readDiagnostics: read.diagnostics,
|
|
1311
|
+
readComplete: read.complete,
|
|
1287
1312
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1288
1313
|
revision: 0,
|
|
1289
1314
|
lastSavedRevision: 0,
|
|
@@ -1347,6 +1372,8 @@ var RuntimeService = class {
|
|
|
1347
1372
|
sessionLock: null,
|
|
1348
1373
|
fileSystem: storage?.fileSystem,
|
|
1349
1374
|
project: normalizeUamProject(input.project),
|
|
1375
|
+
readDiagnostics: [],
|
|
1376
|
+
readComplete: true,
|
|
1350
1377
|
uamFidelity: "full",
|
|
1351
1378
|
revision: 0,
|
|
1352
1379
|
lastSavedRevision: 0,
|
|
@@ -1431,6 +1458,7 @@ const BACKEND_METHODS = [
|
|
|
1431
1458
|
"openProjectSession",
|
|
1432
1459
|
"getSession",
|
|
1433
1460
|
"getProjectOutline",
|
|
1461
|
+
"validateSession",
|
|
1434
1462
|
"applyTransaction",
|
|
1435
1463
|
"saveSession",
|
|
1436
1464
|
"materializeSession",
|
|
@@ -1452,7 +1480,7 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1452
1480
|
function createCapabilities() {
|
|
1453
1481
|
return {
|
|
1454
1482
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1455
|
-
capabilitySchemaVersion:
|
|
1483
|
+
capabilitySchemaVersion: 3,
|
|
1456
1484
|
transactionKernelOwner: "@openfairygui/core",
|
|
1457
1485
|
appSeamOwner: "@openfairygui/functions",
|
|
1458
1486
|
runtimeOwner: "@openfairygui/backend",
|
|
@@ -1460,7 +1488,8 @@ function createCapabilities() {
|
|
|
1460
1488
|
read: {
|
|
1461
1489
|
capabilitySnapshot: true,
|
|
1462
1490
|
sessionSnapshot: true,
|
|
1463
|
-
projectOutline: true
|
|
1491
|
+
projectOutline: true,
|
|
1492
|
+
projectValidation: true
|
|
1464
1493
|
},
|
|
1465
1494
|
authoring: {
|
|
1466
1495
|
applyTransaction: true,
|
|
@@ -1603,6 +1632,9 @@ var BackendRuntime = class {
|
|
|
1603
1632
|
getProjectOutline(input) {
|
|
1604
1633
|
return this.readService.getProjectOutline(input);
|
|
1605
1634
|
}
|
|
1635
|
+
validateSession(input) {
|
|
1636
|
+
return this.readService.validateSession(input);
|
|
1637
|
+
}
|
|
1606
1638
|
async applyTransaction(input) {
|
|
1607
1639
|
return this.authoringService.applyTransaction(input);
|
|
1608
1640
|
}
|
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) {
|
|
@@ -1143,6 +1144,26 @@ var ReadService = class {
|
|
|
1143
1144
|
revision: session.revision
|
|
1144
1145
|
});
|
|
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
|
+
}
|
|
1146
1167
|
};
|
|
1147
1168
|
//#endregion
|
|
1148
1169
|
//#region src/services/runtime-service.ts
|
|
@@ -1298,7 +1319,9 @@ var RuntimeService = class {
|
|
|
1298
1319
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1299
1320
|
canonicalPathKey
|
|
1300
1321
|
}));
|
|
1301
|
-
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;
|
|
1302
1325
|
const project = (0, _openfairygui_core_uam.liftDocumentToUamProject)(document);
|
|
1303
1326
|
const sessionId = randomId();
|
|
1304
1327
|
const session = {
|
|
@@ -1310,6 +1333,8 @@ var RuntimeService = class {
|
|
|
1310
1333
|
sessionLock,
|
|
1311
1334
|
fileSystem,
|
|
1312
1335
|
project,
|
|
1336
|
+
readDiagnostics: read.diagnostics,
|
|
1337
|
+
readComplete: read.complete,
|
|
1313
1338
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1314
1339
|
revision: 0,
|
|
1315
1340
|
lastSavedRevision: 0,
|
|
@@ -1373,6 +1398,8 @@ var RuntimeService = class {
|
|
|
1373
1398
|
sessionLock: null,
|
|
1374
1399
|
fileSystem: storage?.fileSystem,
|
|
1375
1400
|
project: (0, _openfairygui_core_uam.normalizeUamProject)(input.project),
|
|
1401
|
+
readDiagnostics: [],
|
|
1402
|
+
readComplete: true,
|
|
1376
1403
|
uamFidelity: "full",
|
|
1377
1404
|
revision: 0,
|
|
1378
1405
|
lastSavedRevision: 0,
|
|
@@ -1457,6 +1484,7 @@ const BACKEND_METHODS = [
|
|
|
1457
1484
|
"openProjectSession",
|
|
1458
1485
|
"getSession",
|
|
1459
1486
|
"getProjectOutline",
|
|
1487
|
+
"validateSession",
|
|
1460
1488
|
"applyTransaction",
|
|
1461
1489
|
"saveSession",
|
|
1462
1490
|
"materializeSession",
|
|
@@ -1478,7 +1506,7 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1478
1506
|
function createCapabilities() {
|
|
1479
1507
|
return {
|
|
1480
1508
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1481
|
-
capabilitySchemaVersion:
|
|
1509
|
+
capabilitySchemaVersion: 3,
|
|
1482
1510
|
transactionKernelOwner: "@openfairygui/core",
|
|
1483
1511
|
appSeamOwner: "@openfairygui/functions",
|
|
1484
1512
|
runtimeOwner: "@openfairygui/backend",
|
|
@@ -1486,7 +1514,8 @@ function createCapabilities() {
|
|
|
1486
1514
|
read: {
|
|
1487
1515
|
capabilitySnapshot: true,
|
|
1488
1516
|
sessionSnapshot: true,
|
|
1489
|
-
projectOutline: true
|
|
1517
|
+
projectOutline: true,
|
|
1518
|
+
projectValidation: true
|
|
1490
1519
|
},
|
|
1491
1520
|
authoring: {
|
|
1492
1521
|
applyTransaction: true,
|
|
@@ -1629,6 +1658,9 @@ var BackendRuntime = class {
|
|
|
1629
1658
|
getProjectOutline(input) {
|
|
1630
1659
|
return this.readService.getProjectOutline(input);
|
|
1631
1660
|
}
|
|
1661
|
+
validateSession(input) {
|
|
1662
|
+
return this.readService.validateSession(input);
|
|
1663
|
+
}
|
|
1632
1664
|
async applyTransaction(input) {
|
|
1633
1665
|
return this.authoringService.applyTransaction(input);
|
|
1634
1666
|
}
|
package/dist/node.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
|
|
2
|
+
import { ProjectValidationReport } from "@openfairygui/core";
|
|
2
3
|
import { UamDisplayNodeKind, UamProject, UamResource, UamTransactionOperation } from "@openfairygui/core/uam";
|
|
3
4
|
|
|
4
5
|
//#region src/path-policy.d.ts
|
|
@@ -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,11 +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', 'getProjectOutline', '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;
|
|
136
137
|
projectOutline: true;
|
|
138
|
+
projectValidation: true;
|
|
137
139
|
};
|
|
138
140
|
authoring: {
|
|
139
141
|
applyTransaction: true;
|
|
@@ -472,6 +474,9 @@ interface ApplySessionTransactionInput {
|
|
|
472
474
|
interface GetProjectOutlineInput {
|
|
473
475
|
sessionId: string;
|
|
474
476
|
}
|
|
477
|
+
interface ValidateSessionInput {
|
|
478
|
+
sessionId: string;
|
|
479
|
+
}
|
|
475
480
|
interface OpenProjectSessionInput {
|
|
476
481
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
477
482
|
project: UamProject;
|
|
@@ -536,6 +541,7 @@ declare class BackendRuntime {
|
|
|
536
541
|
sessionId: string;
|
|
537
542
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
538
543
|
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
544
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
539
545
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
540
546
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
541
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
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,11 +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', 'getProjectOutline', '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;
|
|
136
137
|
projectOutline: true;
|
|
138
|
+
projectValidation: true;
|
|
137
139
|
};
|
|
138
140
|
authoring: {
|
|
139
141
|
applyTransaction: true;
|
|
@@ -472,6 +474,9 @@ interface ApplySessionTransactionInput {
|
|
|
472
474
|
interface GetProjectOutlineInput {
|
|
473
475
|
sessionId: string;
|
|
474
476
|
}
|
|
477
|
+
interface ValidateSessionInput {
|
|
478
|
+
sessionId: string;
|
|
479
|
+
}
|
|
475
480
|
interface OpenProjectSessionInput {
|
|
476
481
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
477
482
|
project: UamProject;
|
|
@@ -536,6 +541,7 @@ declare class BackendRuntime {
|
|
|
536
541
|
sessionId: string;
|
|
537
542
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
538
543
|
getProjectOutline(input: GetProjectOutlineInput): BackendResult<BackendProjectOutline, SessionNotFoundError>;
|
|
544
|
+
validateSession(input: ValidateSessionInput): BackendResult<ProjectValidationReport, SessionNotFoundError>;
|
|
539
545
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
540
546
|
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
541
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) {
|
|
@@ -1118,6 +1119,26 @@ var ReadService = class {
|
|
|
1118
1119
|
revision: session.revision
|
|
1119
1120
|
});
|
|
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
|
+
}
|
|
1121
1142
|
};
|
|
1122
1143
|
//#endregion
|
|
1123
1144
|
//#region src/services/runtime-service.ts
|
|
@@ -1273,7 +1294,9 @@ var RuntimeService = class {
|
|
|
1273
1294
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1274
1295
|
canonicalPathKey
|
|
1275
1296
|
}));
|
|
1276
|
-
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;
|
|
1277
1300
|
const project = liftDocumentToUamProject(document);
|
|
1278
1301
|
const sessionId = randomId();
|
|
1279
1302
|
const session = {
|
|
@@ -1285,6 +1308,8 @@ var RuntimeService = class {
|
|
|
1285
1308
|
sessionLock,
|
|
1286
1309
|
fileSystem,
|
|
1287
1310
|
project,
|
|
1311
|
+
readDiagnostics: read.diagnostics,
|
|
1312
|
+
readComplete: read.complete,
|
|
1288
1313
|
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1289
1314
|
revision: 0,
|
|
1290
1315
|
lastSavedRevision: 0,
|
|
@@ -1348,6 +1373,8 @@ var RuntimeService = class {
|
|
|
1348
1373
|
sessionLock: null,
|
|
1349
1374
|
fileSystem: storage?.fileSystem,
|
|
1350
1375
|
project: normalizeUamProject(input.project),
|
|
1376
|
+
readDiagnostics: [],
|
|
1377
|
+
readComplete: true,
|
|
1351
1378
|
uamFidelity: "full",
|
|
1352
1379
|
revision: 0,
|
|
1353
1380
|
lastSavedRevision: 0,
|
|
@@ -1432,6 +1459,7 @@ const BACKEND_METHODS = [
|
|
|
1432
1459
|
"openProjectSession",
|
|
1433
1460
|
"getSession",
|
|
1434
1461
|
"getProjectOutline",
|
|
1462
|
+
"validateSession",
|
|
1435
1463
|
"applyTransaction",
|
|
1436
1464
|
"saveSession",
|
|
1437
1465
|
"materializeSession",
|
|
@@ -1453,7 +1481,7 @@ const ARTIFACT_BRIDGE_CAPABILITY = {
|
|
|
1453
1481
|
function createCapabilities() {
|
|
1454
1482
|
return {
|
|
1455
1483
|
contractVersion: BACKEND_CONTRACT_VERSION,
|
|
1456
|
-
capabilitySchemaVersion:
|
|
1484
|
+
capabilitySchemaVersion: 3,
|
|
1457
1485
|
transactionKernelOwner: "@openfairygui/core",
|
|
1458
1486
|
appSeamOwner: "@openfairygui/functions",
|
|
1459
1487
|
runtimeOwner: "@openfairygui/backend",
|
|
@@ -1461,7 +1489,8 @@ function createCapabilities() {
|
|
|
1461
1489
|
read: {
|
|
1462
1490
|
capabilitySnapshot: true,
|
|
1463
1491
|
sessionSnapshot: true,
|
|
1464
|
-
projectOutline: true
|
|
1492
|
+
projectOutline: true,
|
|
1493
|
+
projectValidation: true
|
|
1465
1494
|
},
|
|
1466
1495
|
authoring: {
|
|
1467
1496
|
applyTransaction: true,
|
|
@@ -1604,6 +1633,9 @@ var BackendRuntime = class {
|
|
|
1604
1633
|
getProjectOutline(input) {
|
|
1605
1634
|
return this.readService.getProjectOutline(input);
|
|
1606
1635
|
}
|
|
1636
|
+
validateSession(input) {
|
|
1637
|
+
return this.readService.validateSession(input);
|
|
1638
|
+
}
|
|
1607
1639
|
async applyTransaction(input) {
|
|
1608
1640
|
return this.authoringService.applyTransaction(input);
|
|
1609
1641
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfairygui/backend",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.3",
|
|
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/functions": "0.3.0-alpha.
|
|
56
|
-
"@openfairygui/core": "0.3.0-alpha.
|
|
55
|
+
"@openfairygui/functions": "0.3.0-alpha.3",
|
|
56
|
+
"@openfairygui/core": "0.3.0-alpha.3"
|
|
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
|
@@ -17,6 +17,7 @@ const BACKEND_METHODS = [
|
|
|
17
17
|
'openProjectSession',
|
|
18
18
|
'getSession',
|
|
19
19
|
'getProjectOutline',
|
|
20
|
+
'validateSession',
|
|
20
21
|
'applyTransaction',
|
|
21
22
|
'saveSession',
|
|
22
23
|
'materializeSession',
|
|
@@ -49,6 +50,7 @@ export function createCapabilities(): BackendCapabilities {
|
|
|
49
50
|
capabilitySnapshot: true,
|
|
50
51
|
sessionSnapshot: true,
|
|
51
52
|
projectOutline: true,
|
|
53
|
+
projectValidation: true,
|
|
52
54
|
},
|
|
53
55
|
authoring: {
|
|
54
56
|
applyTransaction: true,
|
package/src/runtime/contracts.ts
CHANGED
|
@@ -100,6 +100,7 @@ export interface BackendCapabilities {
|
|
|
100
100
|
'openProjectSession',
|
|
101
101
|
'getSession',
|
|
102
102
|
'getProjectOutline',
|
|
103
|
+
'validateSession',
|
|
103
104
|
'applyTransaction',
|
|
104
105
|
'saveSession',
|
|
105
106
|
'materializeSession',
|
|
@@ -115,6 +116,7 @@ export interface BackendCapabilities {
|
|
|
115
116
|
capabilitySnapshot: true;
|
|
116
117
|
sessionSnapshot: true;
|
|
117
118
|
projectOutline: true;
|
|
119
|
+
projectValidation: true;
|
|
118
120
|
};
|
|
119
121
|
authoring: {
|
|
120
122
|
applyTransaction: true;
|
|
@@ -518,6 +520,10 @@ export interface GetProjectOutlineInput {
|
|
|
518
520
|
sessionId: string;
|
|
519
521
|
}
|
|
520
522
|
|
|
523
|
+
export interface ValidateSessionInput {
|
|
524
|
+
sessionId: string;
|
|
525
|
+
}
|
|
526
|
+
|
|
521
527
|
export interface OpenProjectSessionInput {
|
|
522
528
|
/** Authoritative UAM project. Use BackendRuntime.openSession() when importing an existing project from storage. */
|
|
523
529
|
project: UamProject;
|
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';
|
|
@@ -33,6 +34,7 @@ import type {
|
|
|
33
34
|
GetEventsSnapshot,
|
|
34
35
|
GetJobInput,
|
|
35
36
|
GetProjectOutlineInput,
|
|
37
|
+
ValidateSessionInput,
|
|
36
38
|
InProcessLockConflictError,
|
|
37
39
|
ListJobsInput,
|
|
38
40
|
MaterializeSessionInput,
|
|
@@ -121,6 +123,12 @@ export class BackendRuntime {
|
|
|
121
123
|
return this.readService.getProjectOutline(input);
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
public validateSession(
|
|
127
|
+
input: ValidateSessionInput,
|
|
128
|
+
): BackendResult<ProjectValidationReport, SessionNotFoundError> {
|
|
129
|
+
return this.readService.validateSession(input);
|
|
130
|
+
}
|
|
131
|
+
|
|
124
132
|
public async applyTransaction(
|
|
125
133
|
input: ApplySessionTransactionInput,
|
|
126
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;
|
|
@@ -8,6 +8,8 @@ import type {
|
|
|
8
8
|
SessionNotFoundError,
|
|
9
9
|
} from '../runtime.js';
|
|
10
10
|
import { createSessionNotFoundError, toSessionSnapshot } from './session-utils.js';
|
|
11
|
+
import { validateProject } from '@openfairygui/functions';
|
|
12
|
+
import type { ProjectValidationReport } from '@openfairygui/core';
|
|
11
13
|
|
|
12
14
|
function toProjectOutline(session: BackendSessionState): BackendProjectOutline {
|
|
13
15
|
const project = session.project;
|
|
@@ -81,4 +83,24 @@ export class ReadService {
|
|
|
81
83
|
revision: session.revision,
|
|
82
84
|
});
|
|
83
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
|
+
}
|
|
84
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,
|