@openfairygui/backend 0.2.0-alpha.13 → 0.2.0-alpha.15
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 +9 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/node.cjs +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{runtime-GyNVxAQ0.d.mts → runtime-B6UjcyIt.d.cts} +11 -4
- package/dist/{runtime-Jec6FcF5.d.cts → runtime-BihiQW-H.d.mts} +11 -4
- package/dist/{runtime-GKzsXJdO.cjs → runtime-C5N7GLsG.cjs} +159 -4
- package/dist/{runtime-DFatY9W0.mjs → runtime-CxH7aT_v.mjs} +160 -5
- package/package.json +3 -3
- package/src/index.ts +17 -16
- package/src/runtime.ts +17 -2
- package/src/services/authoring-service.ts +201 -41
- package/src/services/context.ts +11 -8
- package/src/services/runtime-service.ts +103 -15
- package/src/services/session-utils.ts +5 -1
- package/src/storage.ts +5 -3
package/README.md
CHANGED
|
@@ -34,7 +34,14 @@ It does **not** redefine transaction grammar or expose `Document`.
|
|
|
34
34
|
It also does **not** implement MCP or any transport-specific wire protocol.
|
|
35
35
|
The root `@openfairygui/backend` entrypoint is browser-safe: pure authoring sessions can run in memory,
|
|
36
36
|
and browser editors can inject an async storage adapter for OPFS, IndexedDB, ZIP-backed virtual filesystems,
|
|
37
|
-
or File System Access API bridges.
|
|
37
|
+
or File System Access API bridges. Storage adapters must implement `unlink()` so resource rename/move/remove
|
|
38
|
+
can clean up stale source files. The default Node filesystem/runtime lives under `@openfairygui/backend/node`.
|
|
39
|
+
File-backed `openSession` hydrates primary resource bytes so browser-safe transactions can rename/move
|
|
40
|
+
assets or add/replace/remove binary resources. `saveSession` writes replacement bytes before it removes
|
|
41
|
+
stale source files, preserving the prior file when a write fails.
|
|
42
|
+
It also compares the source project with a UAM round trip through `ProjectWriter`; sessions with
|
|
43
|
+
unrepresented persisted properties expose `uamFidelity: 'unsupported'`, and write attempts fail with
|
|
44
|
+
`uam_fidelity_unsupported`. Transactions, saves, and materialization are serialized per session.
|
|
38
45
|
|
|
39
46
|
## Relationship to other packages
|
|
40
47
|
|
|
@@ -73,6 +80,7 @@ const fileSystem = createBackendStorageFileSystem({
|
|
|
73
80
|
async mkdir(dirPath) { await storage.mkdir(dirPath); },
|
|
74
81
|
async readdir(dirPath) { return storage.readdir(dirPath); },
|
|
75
82
|
async exists(filePath) { return storage.exists(filePath); },
|
|
83
|
+
async unlink(filePath) { await storage.remove(filePath); },
|
|
76
84
|
});
|
|
77
85
|
|
|
78
86
|
const runtime = new BackendRuntime();
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_runtime = require("./runtime-
|
|
2
|
+
const require_runtime = require("./runtime-C5N7GLsG.cjs");
|
|
3
3
|
//#region src/storage.ts
|
|
4
4
|
var StorageFileStat = class {
|
|
5
5
|
constructor(kind) {
|
|
@@ -71,6 +71,7 @@ async function inferStat(storage, filePath) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
function createBackendStorageFileSystem(storage) {
|
|
74
|
+
if (typeof storage.unlink !== "function") throw createPathError("ENOTSUP", "Storage adapter must provide unlink() for project resource lifecycle writes.");
|
|
74
75
|
const lockedPaths = /* @__PURE__ */ new Set();
|
|
75
76
|
const fileSystem = {
|
|
76
77
|
stat(filePath) {
|
|
@@ -128,8 +129,7 @@ function createBackendStorageFileSystem(storage) {
|
|
|
128
129
|
unlink(filePath) {
|
|
129
130
|
const resolved = fileSystem.resolve(filePath);
|
|
130
131
|
lockedPaths.delete(resolved);
|
|
131
|
-
|
|
132
|
-
throw createPathError("ENOTSUP", "Storage adapter does not provide unlink().");
|
|
132
|
+
return storage.unlink(resolved);
|
|
133
133
|
},
|
|
134
134
|
join(...paths) {
|
|
135
135
|
return storage.join ? storage.join(...paths) : joinStoragePath(...paths);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as BACKEND_COMPATIBILITY_POLICY, A as BackendSessionSnapshot, B as ListJobsInput, C as BackendJobProgress, D as BackendResult, E as BackendProjectSessionStorage, F as GetCacheSnapshotInput, G as OpenProjectSessionInput, H as MaterializeSessionSnapshot, I as GetEventsInput, J as SaveSessionInput, K as RefreshCacheInput, L as GetEventsSnapshot, M as CacheRefreshFailedError, N as CancelJobInput, O as BackendRuntime, P as EventCursorInvalidError, Q as BACKEND_CAPABILITY_SCHEMA_VERSION, R as GetJobInput, S as BackendJobNotFoundError, T as BackendJobStatus, U as MaterializeValidationFailedError, V as MaterializeSessionInput, W as MaterializeWriteFailedError, X as SessionStaleWriteError, Y as SessionNotFoundError, Z as UamFidelityUnsupportedError, _ as BackendJobErrors, a as BackendCacheSnapshot, b as BackendJobListStatusFilter, c as BackendCapabilityUnavailableError, d as BackendEventKind, et as BACKEND_CONTRACT_VERSION, f as BackendFailure, g as BackendHostAdapter, h as BackendFileSystem, i as BackendCacheEntry, it as BackendStage, j as BackendSuccess, k as BackendRuntimeOptions, l as BackendError, m as BackendFileStat, n as ApplySessionTransactionInput, nt as BackendMessage, o as BackendCapabilities, p as BackendFileHandle, q as SavePartialFailureError, r as BackendArtifactBridgeCapability, rt as BackendResponseMeta, s as BackendCapabilityManifest, t as AdvisoryLockConflictError, tt as BackendDiagnostic, u as BackendEvent, v as BackendJobKind, w as BackendJobSnapshot, x as BackendJobNotCancellableError, y as BackendJobListSnapshot, z as InProcessLockConflictError } from "./runtime-B6UjcyIt.cjs";
|
|
2
2
|
import { FileSystem } from "@openfairygui/core/project-io";
|
|
3
3
|
|
|
4
4
|
//#region src/storage.d.ts
|
|
@@ -22,7 +22,7 @@ interface BackendAsyncStorageAdapter {
|
|
|
22
22
|
stat?(filePath: string): Promise<BackendStorageStatLike>;
|
|
23
23
|
resolvePath?(filePath: string): Promise<string>;
|
|
24
24
|
openExclusive?(filePath: string): Promise<BackendFileHandle>;
|
|
25
|
-
unlink
|
|
25
|
+
unlink(filePath: string): Promise<void>;
|
|
26
26
|
join?(...paths: string[]): string;
|
|
27
27
|
dirname?(filePath: string): string;
|
|
28
28
|
resolve?(...paths: string[]): string;
|
|
@@ -30,4 +30,4 @@ interface BackendAsyncStorageAdapter {
|
|
|
30
30
|
type BackendStorageFileSystem = BackendFileSystem & FileSystem;
|
|
31
31
|
declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
|
|
32
32
|
//#endregion
|
|
33
|
-
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 BackendFileHandle, 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 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, createBackendStorageFileSystem };
|
|
33
|
+
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 BackendFileHandle, 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 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 };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as BACKEND_COMPATIBILITY_POLICY, A as BackendSessionSnapshot, B as ListJobsInput, C as BackendJobProgress, D as BackendResult, E as BackendProjectSessionStorage, F as GetCacheSnapshotInput, G as OpenProjectSessionInput, H as MaterializeSessionSnapshot, I as GetEventsInput, J as SaveSessionInput, K as RefreshCacheInput, L as GetEventsSnapshot, M as CacheRefreshFailedError, N as CancelJobInput, O as BackendRuntime, P as EventCursorInvalidError, Q as BACKEND_CAPABILITY_SCHEMA_VERSION, R as GetJobInput, S as BackendJobNotFoundError, T as BackendJobStatus, U as MaterializeValidationFailedError, V as MaterializeSessionInput, W as MaterializeWriteFailedError, X as SessionStaleWriteError, Y as SessionNotFoundError, Z as UamFidelityUnsupportedError, _ as BackendJobErrors, a as BackendCacheSnapshot, b as BackendJobListStatusFilter, c as BackendCapabilityUnavailableError, d as BackendEventKind, et as BACKEND_CONTRACT_VERSION, f as BackendFailure, g as BackendHostAdapter, h as BackendFileSystem, i as BackendCacheEntry, it as BackendStage, j as BackendSuccess, k as BackendRuntimeOptions, l as BackendError, m as BackendFileStat, n as ApplySessionTransactionInput, nt as BackendMessage, o as BackendCapabilities, p as BackendFileHandle, q as SavePartialFailureError, r as BackendArtifactBridgeCapability, rt as BackendResponseMeta, s as BackendCapabilityManifest, t as AdvisoryLockConflictError, tt as BackendDiagnostic, u as BackendEvent, v as BackendJobKind, w as BackendJobSnapshot, x as BackendJobNotCancellableError, y as BackendJobListSnapshot, z as InProcessLockConflictError } from "./runtime-BihiQW-H.mjs";
|
|
2
2
|
import { FileSystem } from "@openfairygui/core/project-io";
|
|
3
3
|
|
|
4
4
|
//#region src/storage.d.ts
|
|
@@ -22,7 +22,7 @@ interface BackendAsyncStorageAdapter {
|
|
|
22
22
|
stat?(filePath: string): Promise<BackendStorageStatLike>;
|
|
23
23
|
resolvePath?(filePath: string): Promise<string>;
|
|
24
24
|
openExclusive?(filePath: string): Promise<BackendFileHandle>;
|
|
25
|
-
unlink
|
|
25
|
+
unlink(filePath: string): Promise<void>;
|
|
26
26
|
join?(...paths: string[]): string;
|
|
27
27
|
dirname?(filePath: string): string;
|
|
28
28
|
resolve?(...paths: string[]): string;
|
|
@@ -30,4 +30,4 @@ interface BackendAsyncStorageAdapter {
|
|
|
30
30
|
type BackendStorageFileSystem = BackendFileSystem & FileSystem;
|
|
31
31
|
declare function createBackendStorageFileSystem(storage: BackendAsyncStorageAdapter): BackendStorageFileSystem;
|
|
32
32
|
//#endregion
|
|
33
|
-
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 BackendFileHandle, 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 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, createBackendStorageFileSystem };
|
|
33
|
+
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 BackendFileHandle, 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 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 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as BACKEND_CONTRACT_VERSION, n as BACKEND_CAPABILITY_SCHEMA_VERSION, r as BACKEND_COMPATIBILITY_POLICY, t as BackendRuntime } from "./runtime-
|
|
1
|
+
import { i as BACKEND_CONTRACT_VERSION, n as BACKEND_CAPABILITY_SCHEMA_VERSION, r as BACKEND_COMPATIBILITY_POLICY, t as BackendRuntime } from "./runtime-CxH7aT_v.mjs";
|
|
2
2
|
//#region src/storage.ts
|
|
3
3
|
var StorageFileStat = class {
|
|
4
4
|
constructor(kind) {
|
|
@@ -70,6 +70,7 @@ async function inferStat(storage, filePath) {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
function createBackendStorageFileSystem(storage) {
|
|
73
|
+
if (typeof storage.unlink !== "function") throw createPathError("ENOTSUP", "Storage adapter must provide unlink() for project resource lifecycle writes.");
|
|
73
74
|
const lockedPaths = /* @__PURE__ */ new Set();
|
|
74
75
|
const fileSystem = {
|
|
75
76
|
stat(filePath) {
|
|
@@ -127,8 +128,7 @@ function createBackendStorageFileSystem(storage) {
|
|
|
127
128
|
unlink(filePath) {
|
|
128
129
|
const resolved = fileSystem.resolve(filePath);
|
|
129
130
|
lockedPaths.delete(resolved);
|
|
130
|
-
|
|
131
|
-
throw createPathError("ENOTSUP", "Storage adapter does not provide unlink().");
|
|
131
|
+
return storage.unlink(resolved);
|
|
132
132
|
},
|
|
133
133
|
join(...paths) {
|
|
134
134
|
return storage.join ? storage.join(...paths) : joinStoragePath(...paths);
|
package/dist/node.cjs
CHANGED
|
@@ -21,7 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
const require_runtime = require("./runtime-
|
|
24
|
+
const require_runtime = require("./runtime-C5N7GLsG.cjs");
|
|
25
25
|
let node_fs_promises = require("node:fs/promises");
|
|
26
26
|
node_fs_promises = __toESM(node_fs_promises);
|
|
27
27
|
let node_path = require("node:path");
|
package/dist/node.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as BackendRuntime, g as BackendHostAdapter, h as BackendFileSystem, k as BackendRuntimeOptions, m as BackendFileStat, p as BackendFileHandle } from "./runtime-
|
|
1
|
+
import { O as BackendRuntime, g as BackendHostAdapter, h as BackendFileSystem, k as BackendRuntimeOptions, m as BackendFileStat, p as BackendFileHandle } from "./runtime-B6UjcyIt.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/node.d.ts
|
|
4
4
|
declare function createNodeBackendFileSystem(): BackendFileSystem;
|
package/dist/node.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as BackendRuntime, g as BackendHostAdapter, h as BackendFileSystem, k as BackendRuntimeOptions, m as BackendFileStat, p as BackendFileHandle } from "./runtime-
|
|
1
|
+
import { O as BackendRuntime, g as BackendHostAdapter, h as BackendFileSystem, k as BackendRuntimeOptions, m as BackendFileStat, p as BackendFileHandle } from "./runtime-BihiQW-H.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/node.d.ts
|
|
4
4
|
declare function createNodeBackendFileSystem(): BackendFileSystem;
|
package/dist/node.mjs
CHANGED
|
@@ -193,6 +193,7 @@ interface BackendSessionSnapshot {
|
|
|
193
193
|
revision: number;
|
|
194
194
|
lastSavedRevision: number;
|
|
195
195
|
dirty: boolean;
|
|
196
|
+
uamFidelity: 'full' | 'unsupported';
|
|
196
197
|
lockHeld: boolean;
|
|
197
198
|
capabilities: BackendCapabilities;
|
|
198
199
|
}
|
|
@@ -257,6 +258,12 @@ interface SavePartialFailureError {
|
|
|
257
258
|
failedPaths: string[];
|
|
258
259
|
diskMayBePartiallyUpdated: true;
|
|
259
260
|
}
|
|
261
|
+
interface UamFidelityUnsupportedError {
|
|
262
|
+
code: 'uam_fidelity_unsupported';
|
|
263
|
+
message: string;
|
|
264
|
+
sessionId: string;
|
|
265
|
+
canonicalPathKey: string;
|
|
266
|
+
}
|
|
260
267
|
interface MaterializeValidationFailedError {
|
|
261
268
|
code: 'materialize_validation_failed';
|
|
262
269
|
message: string;
|
|
@@ -409,7 +416,7 @@ interface RefreshCacheInput {
|
|
|
409
416
|
sessionId: string;
|
|
410
417
|
reason?: 'manual' | 'session_open' | 'after_save';
|
|
411
418
|
}
|
|
412
|
-
type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
|
|
419
|
+
type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
|
|
413
420
|
interface ApplySessionTransactionInput {
|
|
414
421
|
sessionId: string;
|
|
415
422
|
expectedRevision: number;
|
|
@@ -475,8 +482,8 @@ declare class BackendRuntime {
|
|
|
475
482
|
sessionId: string;
|
|
476
483
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
477
484
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
478
|
-
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
479
|
-
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
485
|
+
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
486
|
+
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
480
487
|
closeSession(input: {
|
|
481
488
|
sessionId: string;
|
|
482
489
|
}): Promise<BackendResult<{
|
|
@@ -491,4 +498,4 @@ declare class BackendRuntime {
|
|
|
491
498
|
refreshCache(input: RefreshCacheInput): BackendResult<BackendJobSnapshot, SessionNotFoundError>;
|
|
492
499
|
}
|
|
493
500
|
//#endregion
|
|
494
|
-
export {
|
|
501
|
+
export { BACKEND_COMPATIBILITY_POLICY as $, BackendSessionSnapshot as A, ListJobsInput as B, BackendJobProgress as C, BackendResult as D, BackendProjectSessionStorage as E, GetCacheSnapshotInput as F, OpenProjectSessionInput as G, MaterializeSessionSnapshot as H, GetEventsInput as I, SaveSessionInput as J, RefreshCacheInput as K, GetEventsSnapshot as L, CacheRefreshFailedError as M, CancelJobInput as N, BackendRuntime as O, EventCursorInvalidError as P, BACKEND_CAPABILITY_SCHEMA_VERSION as Q, GetJobInput as R, BackendJobNotFoundError as S, BackendJobStatus as T, MaterializeValidationFailedError as U, MaterializeSessionInput as V, MaterializeWriteFailedError as W, SessionStaleWriteError as X, SessionNotFoundError as Y, UamFidelityUnsupportedError as Z, BackendJobErrors as _, BackendCacheSnapshot as a, BackendJobListStatusFilter as b, BackendCapabilityUnavailableError as c, BackendEventKind as d, BACKEND_CONTRACT_VERSION as et, BackendFailure as f, BackendHostAdapter as g, BackendFileSystem as h, BackendCacheEntry as i, BackendStage as it, BackendSuccess as j, BackendRuntimeOptions as k, BackendError as l, BackendFileStat as m, ApplySessionTransactionInput as n, BackendMessage as nt, BackendCapabilities as o, BackendFileHandle as p, SavePartialFailureError as q, BackendArtifactBridgeCapability as r, BackendResponseMeta as rt, BackendCapabilityManifest as s, AdvisoryLockConflictError as t, BackendDiagnostic as tt, BackendEvent as u, BackendJobKind as v, BackendJobSnapshot as w, BackendJobNotCancellableError as x, BackendJobListSnapshot as y, InProcessLockConflictError as z };
|
|
@@ -193,6 +193,7 @@ interface BackendSessionSnapshot {
|
|
|
193
193
|
revision: number;
|
|
194
194
|
lastSavedRevision: number;
|
|
195
195
|
dirty: boolean;
|
|
196
|
+
uamFidelity: 'full' | 'unsupported';
|
|
196
197
|
lockHeld: boolean;
|
|
197
198
|
capabilities: BackendCapabilities;
|
|
198
199
|
}
|
|
@@ -257,6 +258,12 @@ interface SavePartialFailureError {
|
|
|
257
258
|
failedPaths: string[];
|
|
258
259
|
diskMayBePartiallyUpdated: true;
|
|
259
260
|
}
|
|
261
|
+
interface UamFidelityUnsupportedError {
|
|
262
|
+
code: 'uam_fidelity_unsupported';
|
|
263
|
+
message: string;
|
|
264
|
+
sessionId: string;
|
|
265
|
+
canonicalPathKey: string;
|
|
266
|
+
}
|
|
260
267
|
interface MaterializeValidationFailedError {
|
|
261
268
|
code: 'materialize_validation_failed';
|
|
262
269
|
message: string;
|
|
@@ -409,7 +416,7 @@ interface RefreshCacheInput {
|
|
|
409
416
|
sessionId: string;
|
|
410
417
|
reason?: 'manual' | 'session_open' | 'after_save';
|
|
411
418
|
}
|
|
412
|
-
type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
|
|
419
|
+
type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
|
|
413
420
|
interface ApplySessionTransactionInput {
|
|
414
421
|
sessionId: string;
|
|
415
422
|
expectedRevision: number;
|
|
@@ -475,8 +482,8 @@ declare class BackendRuntime {
|
|
|
475
482
|
sessionId: string;
|
|
476
483
|
}): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
|
|
477
484
|
applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
|
|
478
|
-
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
479
|
-
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
485
|
+
saveSession(input: SaveSessionInput): Promise<BackendResult<BackendSessionSnapshot | MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
486
|
+
materializeSession(input: MaterializeSessionInput): Promise<BackendResult<MaterializeSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | UamFidelityUnsupportedError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | InProcessLockConflictError | BackendCapabilityUnavailableError>>;
|
|
480
487
|
closeSession(input: {
|
|
481
488
|
sessionId: string;
|
|
482
489
|
}): Promise<BackendResult<{
|
|
@@ -491,4 +498,4 @@ declare class BackendRuntime {
|
|
|
491
498
|
refreshCache(input: RefreshCacheInput): BackendResult<BackendJobSnapshot, SessionNotFoundError>;
|
|
492
499
|
}
|
|
493
500
|
//#endregion
|
|
494
|
-
export {
|
|
501
|
+
export { BACKEND_COMPATIBILITY_POLICY as $, BackendSessionSnapshot as A, ListJobsInput as B, BackendJobProgress as C, BackendResult as D, BackendProjectSessionStorage as E, GetCacheSnapshotInput as F, OpenProjectSessionInput as G, MaterializeSessionSnapshot as H, GetEventsInput as I, SaveSessionInput as J, RefreshCacheInput as K, GetEventsSnapshot as L, CacheRefreshFailedError as M, CancelJobInput as N, BackendRuntime as O, EventCursorInvalidError as P, BACKEND_CAPABILITY_SCHEMA_VERSION as Q, GetJobInput as R, BackendJobNotFoundError as S, BackendJobStatus as T, MaterializeValidationFailedError as U, MaterializeSessionInput as V, MaterializeWriteFailedError as W, SessionStaleWriteError as X, SessionNotFoundError as Y, UamFidelityUnsupportedError as Z, BackendJobErrors as _, BackendCacheSnapshot as a, BackendJobListStatusFilter as b, BackendCapabilityUnavailableError as c, BackendEventKind as d, BACKEND_CONTRACT_VERSION as et, BackendFailure as f, BackendHostAdapter as g, BackendFileSystem as h, BackendCacheEntry as i, BackendStage as it, BackendSuccess as j, BackendRuntimeOptions as k, BackendError as l, BackendFileStat as m, ApplySessionTransactionInput as n, BackendMessage as nt, BackendCapabilities as o, BackendFileHandle as p, SavePartialFailureError as q, BackendArtifactBridgeCapability as r, BackendResponseMeta as rt, BackendCapabilityManifest as s, AdvisoryLockConflictError as t, BackendDiagnostic as tt, BackendEvent as u, BackendJobKind as v, BackendJobSnapshot as w, BackendJobNotCancellableError as x, BackendJobListSnapshot as y, InProcessLockConflictError as z };
|
|
@@ -180,6 +180,7 @@ function toSessionSnapshot(session, capabilities) {
|
|
|
180
180
|
revision: session.revision,
|
|
181
181
|
lastSavedRevision: session.lastSavedRevision,
|
|
182
182
|
dirty: session.dirty,
|
|
183
|
+
uamFidelity: session.uamFidelity,
|
|
183
184
|
lockHeld: session.lockHeld,
|
|
184
185
|
capabilities: cloneCapabilitiesSnapshot(capabilities)
|
|
185
186
|
};
|
|
@@ -252,9 +253,45 @@ function createWriterFileSystem(fileSystem, committedPaths, failedPaths) {
|
|
|
252
253
|
},
|
|
253
254
|
dirname(filePath) {
|
|
254
255
|
return fileSystem.dirname(filePath);
|
|
256
|
+
},
|
|
257
|
+
async unlink(filePath) {
|
|
258
|
+
await trackWrite(filePath, () => fileSystem.unlink(filePath));
|
|
255
259
|
}
|
|
256
260
|
};
|
|
257
261
|
}
|
|
262
|
+
function projectAssetSourceFiles(project) {
|
|
263
|
+
const result = /* @__PURE__ */ new Map();
|
|
264
|
+
for (const pkg of project.packages) for (const resource of pkg.resources) {
|
|
265
|
+
if (resource.kind === "component") continue;
|
|
266
|
+
const fileName = resource.fileName ?? resource.file ?? "";
|
|
267
|
+
if (!fileName) continue;
|
|
268
|
+
result.set(`${pkg.id}/${resource.id}`, {
|
|
269
|
+
packageName: pkg.name,
|
|
270
|
+
branch: resource.branch,
|
|
271
|
+
path: resource.path,
|
|
272
|
+
fileName
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
function sourceFileKey(source) {
|
|
278
|
+
return [
|
|
279
|
+
source.branch,
|
|
280
|
+
source.packageName,
|
|
281
|
+
source.path,
|
|
282
|
+
source.fileName
|
|
283
|
+
].join("\0");
|
|
284
|
+
}
|
|
285
|
+
function recordStaleResourceSources(session, previousProject, nextProject) {
|
|
286
|
+
if (!session.fileSystem) return;
|
|
287
|
+
const previousSources = projectAssetSourceFiles(previousProject);
|
|
288
|
+
const nextSourceKeys = new Set([...projectAssetSourceFiles(nextProject).values()].map(sourceFileKey));
|
|
289
|
+
for (const source of previousSources.values()) {
|
|
290
|
+
const key = sourceFileKey(source);
|
|
291
|
+
if (!nextSourceKeys.has(key)) session.pendingStaleSourceFiles.set(key, source);
|
|
292
|
+
}
|
|
293
|
+
for (const key of nextSourceKeys) session.pendingStaleSourceFiles.delete(key);
|
|
294
|
+
}
|
|
258
295
|
function toBackendDiagnostics(error) {
|
|
259
296
|
return error.diagnostics.length > 0 ? error.diagnostics.map((diagnostic) => ({ ...diagnostic })) : [{
|
|
260
297
|
code: error.code,
|
|
@@ -273,6 +310,14 @@ function createCapabilityUnavailableError$1(message) {
|
|
|
273
310
|
requiredAdapter: "BackendFileSystem"
|
|
274
311
|
};
|
|
275
312
|
}
|
|
313
|
+
function createUamFidelityUnsupportedError(session) {
|
|
314
|
+
return {
|
|
315
|
+
code: "uam_fidelity_unsupported",
|
|
316
|
+
message: "The source project contains formal properties that the current UAM cannot preserve.",
|
|
317
|
+
sessionId: session.sessionId,
|
|
318
|
+
canonicalPathKey: session.canonicalPathKey
|
|
319
|
+
};
|
|
320
|
+
}
|
|
276
321
|
function validationDiagnostics(sessionProject) {
|
|
277
322
|
return (0, _openfairygui_core_uam.validateUamProject)(sessionProject).map((issue) => ({
|
|
278
323
|
code: "materialize_validation_failed",
|
|
@@ -304,12 +349,32 @@ function storageCanonicalTarget(input) {
|
|
|
304
349
|
};
|
|
305
350
|
}
|
|
306
351
|
var AuthoringService = class {
|
|
352
|
+
sessionOperations = /* @__PURE__ */ new Map();
|
|
307
353
|
constructor(context, cacheService, eventService) {
|
|
308
354
|
this.context = context;
|
|
309
355
|
this.cacheService = cacheService;
|
|
310
356
|
this.eventService = eventService;
|
|
311
357
|
}
|
|
358
|
+
async runSessionExclusive(sessionId, operation) {
|
|
359
|
+
const previous = this.sessionOperations.get(sessionId) ?? Promise.resolve();
|
|
360
|
+
let release = () => void 0;
|
|
361
|
+
const current = new Promise((resolve) => {
|
|
362
|
+
release = resolve;
|
|
363
|
+
});
|
|
364
|
+
const tail = previous.then(() => current);
|
|
365
|
+
this.sessionOperations.set(sessionId, tail);
|
|
366
|
+
await previous;
|
|
367
|
+
try {
|
|
368
|
+
return await operation();
|
|
369
|
+
} finally {
|
|
370
|
+
release();
|
|
371
|
+
if (this.sessionOperations.get(sessionId) === tail) this.sessionOperations.delete(sessionId);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
312
374
|
async applyTransaction(input) {
|
|
375
|
+
return this.runSessionExclusive(input.sessionId, () => this.applyTransactionExclusive(input));
|
|
376
|
+
}
|
|
377
|
+
async applyTransactionExclusive(input) {
|
|
313
378
|
const startedAt = Date.now();
|
|
314
379
|
const session = this.context.sessions.get(input.sessionId);
|
|
315
380
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
@@ -344,6 +409,7 @@ var AuthoringService = class {
|
|
|
344
409
|
diagnostics
|
|
345
410
|
});
|
|
346
411
|
}
|
|
412
|
+
recordStaleResourceSources(session, session.project, result.project);
|
|
347
413
|
session.project = result.project;
|
|
348
414
|
session.revision += 1;
|
|
349
415
|
session.dirty = true;
|
|
@@ -375,10 +441,13 @@ var AuthoringService = class {
|
|
|
375
441
|
mode: "fullProject",
|
|
376
442
|
reason: "force_save"
|
|
377
443
|
});
|
|
444
|
+
return this.runSessionExclusive(input.sessionId, () => this.saveSessionExclusive(input));
|
|
445
|
+
}
|
|
446
|
+
async saveSessionExclusive(input) {
|
|
378
447
|
const startedAt = Date.now();
|
|
379
448
|
const session = this.context.sessions.get(input.sessionId);
|
|
380
449
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
381
|
-
const fileSystem =
|
|
450
|
+
const fileSystem = session.fileSystem ?? input.fileSystem ?? this.context.fileSystem;
|
|
382
451
|
if (!fileSystem) return failure("authoring", startedAt, createCapabilityUnavailableError$1("saveSession requires an injected BackendFileSystem adapter."), toSessionSnapshot(session, this.context.capabilities), {
|
|
383
452
|
sessionId: session.sessionId,
|
|
384
453
|
revision: session.revision
|
|
@@ -396,6 +465,10 @@ var AuthoringService = class {
|
|
|
396
465
|
sessionId: session.sessionId,
|
|
397
466
|
revision: session.revision
|
|
398
467
|
});
|
|
468
|
+
if (session.uamFidelity === "unsupported") return failure("authoring", startedAt, createUamFidelityUnsupportedError(session), toSessionSnapshot(session, this.context.capabilities), {
|
|
469
|
+
sessionId: session.sessionId,
|
|
470
|
+
revision: session.revision
|
|
471
|
+
});
|
|
399
472
|
const committedPaths = [];
|
|
400
473
|
const failedPaths = [];
|
|
401
474
|
this.eventService.emit({
|
|
@@ -405,7 +478,10 @@ var AuthoringService = class {
|
|
|
405
478
|
revision: session.revision
|
|
406
479
|
});
|
|
407
480
|
try {
|
|
408
|
-
await new _openfairygui_core_project_io.ProjectWriter(createWriterFileSystem(fileSystem, committedPaths, failedPaths)).write((0, _openfairygui_core_uam.materializeUamProject)(session.project), session.fairyPath);
|
|
481
|
+
await new _openfairygui_core_project_io.ProjectWriter(createWriterFileSystem(fileSystem, committedPaths, failedPaths)).write((0, _openfairygui_core_uam.materializeUamProject)(session.project), session.fairyPath, { staleSourceFiles: [...session.pendingStaleSourceFiles.values()] });
|
|
482
|
+
session.fileSystem ??= fileSystem;
|
|
483
|
+
session.pendingStaleSourceFiles.clear();
|
|
484
|
+
(0, _openfairygui_core_uam.commitUamProjectSourcePaths)(session.project);
|
|
409
485
|
session.lastSavedRevision = session.revision;
|
|
410
486
|
session.dirty = false;
|
|
411
487
|
const cacheEntry = this.cacheService.refreshSession(session);
|
|
@@ -451,6 +527,9 @@ var AuthoringService = class {
|
|
|
451
527
|
}
|
|
452
528
|
}
|
|
453
529
|
async materializeSession(input) {
|
|
530
|
+
return this.runSessionExclusive(input.sessionId, () => this.materializeSessionExclusive(input));
|
|
531
|
+
}
|
|
532
|
+
async materializeSessionExclusive(input) {
|
|
454
533
|
const startedAt = Date.now();
|
|
455
534
|
const session = this.context.sessions.get(input.sessionId);
|
|
456
535
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
@@ -483,6 +562,10 @@ var AuthoringService = class {
|
|
|
483
562
|
revision: session.revision
|
|
484
563
|
});
|
|
485
564
|
}
|
|
565
|
+
if (session.uamFidelity === "unsupported") return failure("authoring", startedAt, createUamFidelityUnsupportedError(session), toSessionSnapshot(session, this.context.capabilities), {
|
|
566
|
+
sessionId: session.sessionId,
|
|
567
|
+
revision: session.revision
|
|
568
|
+
});
|
|
486
569
|
const diagnostics = validationDiagnostics(session.project);
|
|
487
570
|
if (diagnostics.length > 0) return failure("authoring", startedAt, {
|
|
488
571
|
code: "materialize_validation_failed",
|
|
@@ -529,7 +612,12 @@ var AuthoringService = class {
|
|
|
529
612
|
revision: session.revision
|
|
530
613
|
});
|
|
531
614
|
try {
|
|
532
|
-
|
|
615
|
+
const writer = new _openfairygui_core_project_io.ProjectWriter(createWriterFileSystem(fileSystem, writtenPaths, failedPaths));
|
|
616
|
+
const isSessionStorageTarget = fileSystem === session.fileSystem && fairyPath === session.fairyPath;
|
|
617
|
+
await writer.write(document, fairyPath, { staleSourceFiles: isSessionStorageTarget ? [...session.pendingStaleSourceFiles.values()] : [] });
|
|
618
|
+
if (isSessionStorageTarget) session.pendingStaleSourceFiles.clear();
|
|
619
|
+
if (storageTarget && !isSessionStorageTarget) session.pendingStaleSourceFiles.clear();
|
|
620
|
+
if (isSessionStorageTarget || storageTarget) (0, _openfairygui_core_uam.commitUamProjectSourcePaths)(session.project);
|
|
533
621
|
if (storageTarget) {
|
|
534
622
|
this.context.sessionsByPath.delete(session.canonicalPathKey);
|
|
535
623
|
session.fileSystem = storageTarget.fileSystem;
|
|
@@ -1056,6 +1144,68 @@ function createProjectReaderFileSystem(fileSystem) {
|
|
|
1056
1144
|
}
|
|
1057
1145
|
};
|
|
1058
1146
|
}
|
|
1147
|
+
function createCaptureFileSystem(files) {
|
|
1148
|
+
const normalize = (filePath) => filePath.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
1149
|
+
return {
|
|
1150
|
+
async readFile(filePath) {
|
|
1151
|
+
const value = files.get(normalize(filePath));
|
|
1152
|
+
if (typeof value !== "string") throw new Error(`Captured text file was not found: ${filePath}`);
|
|
1153
|
+
return value;
|
|
1154
|
+
},
|
|
1155
|
+
async readFileRaw(filePath) {
|
|
1156
|
+
const value = files.get(normalize(filePath));
|
|
1157
|
+
if (!(value instanceof Uint8Array)) throw new Error(`Captured binary file was not found: ${filePath}`);
|
|
1158
|
+
return value.slice();
|
|
1159
|
+
},
|
|
1160
|
+
async writeFile(filePath, content) {
|
|
1161
|
+
files.set(normalize(filePath), content);
|
|
1162
|
+
},
|
|
1163
|
+
async writeFileRaw(filePath, data) {
|
|
1164
|
+
files.set(normalize(filePath), data.slice());
|
|
1165
|
+
},
|
|
1166
|
+
async mkdir() {},
|
|
1167
|
+
async readdir() {
|
|
1168
|
+
return [];
|
|
1169
|
+
},
|
|
1170
|
+
async exists(filePath) {
|
|
1171
|
+
return files.has(normalize(filePath));
|
|
1172
|
+
},
|
|
1173
|
+
join(...paths) {
|
|
1174
|
+
return normalize(paths.filter(Boolean).join("/"));
|
|
1175
|
+
},
|
|
1176
|
+
dirname(filePath) {
|
|
1177
|
+
const normalized = normalize(filePath);
|
|
1178
|
+
const separator = normalized.lastIndexOf("/");
|
|
1179
|
+
return separator < 0 ? "" : normalized.slice(0, separator);
|
|
1180
|
+
},
|
|
1181
|
+
async unlink(filePath) {
|
|
1182
|
+
files.delete(normalize(filePath));
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
function capturedFilesEqual(left, right) {
|
|
1187
|
+
if (left.size !== right.size) return false;
|
|
1188
|
+
for (const [filePath, leftValue] of left) {
|
|
1189
|
+
const rightValue = right.get(filePath);
|
|
1190
|
+
if (typeof leftValue === "string") {
|
|
1191
|
+
if (leftValue !== rightValue) return false;
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
if (!(rightValue instanceof Uint8Array) || leftValue.length !== rightValue.length) return false;
|
|
1195
|
+
for (let index = 0; index < leftValue.length; index += 1) if (leftValue[index] !== rightValue[index]) return false;
|
|
1196
|
+
}
|
|
1197
|
+
return true;
|
|
1198
|
+
}
|
|
1199
|
+
async function hasFullUamFidelity(document, project) {
|
|
1200
|
+
const sourceFiles = /* @__PURE__ */ new Map();
|
|
1201
|
+
const materializedFiles = /* @__PURE__ */ new Map();
|
|
1202
|
+
try {
|
|
1203
|
+
await Promise.all([new _openfairygui_core_project_io.ProjectWriter(createCaptureFileSystem(sourceFiles)).write(document, "Project.fairy"), new _openfairygui_core_project_io.ProjectWriter(createCaptureFileSystem(materializedFiles)).write((0, _openfairygui_core_uam.materializeUamProject)(project), "Project.fairy")]);
|
|
1204
|
+
} catch {
|
|
1205
|
+
return false;
|
|
1206
|
+
}
|
|
1207
|
+
return capturedFilesEqual(sourceFiles, materializedFiles);
|
|
1208
|
+
}
|
|
1059
1209
|
var RuntimeService = class {
|
|
1060
1210
|
constructor(context, cacheService, eventService, jobService) {
|
|
1061
1211
|
this.context = context;
|
|
@@ -1090,7 +1240,8 @@ var RuntimeService = class {
|
|
|
1090
1240
|
canonicalPathKey
|
|
1091
1241
|
}));
|
|
1092
1242
|
await advisoryLock.close();
|
|
1093
|
-
const
|
|
1243
|
+
const document = await new _openfairygui_core_project_io.ProjectReader(createProjectReaderFileSystem(fileSystem)).read(fairyPath, { hydrateResourceBytes: true });
|
|
1244
|
+
const project = (0, _openfairygui_core_uam.liftDocumentToUamProject)(document);
|
|
1094
1245
|
const sessionId = randomId();
|
|
1095
1246
|
const session = {
|
|
1096
1247
|
sessionId,
|
|
@@ -1100,8 +1251,10 @@ var RuntimeService = class {
|
|
|
1100
1251
|
lockFilePath,
|
|
1101
1252
|
fileSystem,
|
|
1102
1253
|
project,
|
|
1254
|
+
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1103
1255
|
revision: 0,
|
|
1104
1256
|
lastSavedRevision: 0,
|
|
1257
|
+
pendingStaleSourceFiles: /* @__PURE__ */ new Map(),
|
|
1105
1258
|
dirty: false,
|
|
1106
1259
|
lockHeld: true,
|
|
1107
1260
|
closed: false
|
|
@@ -1157,8 +1310,10 @@ var RuntimeService = class {
|
|
|
1157
1310
|
lockFilePath: "",
|
|
1158
1311
|
fileSystem: storage?.fileSystem,
|
|
1159
1312
|
project: (0, _openfairygui_core_uam.normalizeUamProject)(input.project),
|
|
1313
|
+
uamFidelity: "full",
|
|
1160
1314
|
revision: 0,
|
|
1161
1315
|
lastSavedRevision: 0,
|
|
1316
|
+
pendingStaleSourceFiles: /* @__PURE__ */ new Map(),
|
|
1162
1317
|
dirty: false,
|
|
1163
1318
|
lockHeld: false,
|
|
1164
1319
|
closed: false
|