@openfairygui/backend 0.2.0-alpha.14 → 0.2.0-alpha.16
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 +3 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- 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-B9z0n2yF.mjs → runtime-B017UgBl.mjs} +137 -14
- 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-DqApG30C.cjs → runtime-P0Nhxk2f.cjs} +137 -14
- package/package.json +3 -3
- package/src/index.ts +17 -16
- package/src/runtime.ts +17 -2
- package/src/services/authoring-service.ts +174 -49
- package/src/services/context.ts +10 -9
- package/src/services/runtime-service.ts +101 -15
- package/src/services/session-utils.ts +5 -1
package/README.md
CHANGED
|
@@ -39,6 +39,9 @@ can clean up stale source files. The default Node filesystem/runtime lives under
|
|
|
39
39
|
File-backed `openSession` hydrates primary resource bytes so browser-safe transactions can rename/move
|
|
40
40
|
assets or add/replace/remove binary resources. `saveSession` writes replacement bytes before it removes
|
|
41
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.
|
|
42
45
|
|
|
43
46
|
## Relationship to other packages
|
|
44
47
|
|
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-P0Nhxk2f.cjs");
|
|
3
3
|
//#region src/storage.ts
|
|
4
4
|
var StorageFileStat = class {
|
|
5
5
|
constructor(kind) {
|
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
|
|
@@ -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
|
|
@@ -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-B017UgBl.mjs";
|
|
2
2
|
//#region src/storage.ts
|
|
3
3
|
var StorageFileStat = class {
|
|
4
4
|
constructor(kind) {
|
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-P0Nhxk2f.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
|
@@ -179,6 +179,7 @@ function toSessionSnapshot(session, capabilities) {
|
|
|
179
179
|
revision: session.revision,
|
|
180
180
|
lastSavedRevision: session.lastSavedRevision,
|
|
181
181
|
dirty: session.dirty,
|
|
182
|
+
uamFidelity: session.uamFidelity,
|
|
182
183
|
lockHeld: session.lockHeld,
|
|
183
184
|
capabilities: cloneCapabilitiesSnapshot(capabilities)
|
|
184
185
|
};
|
|
@@ -257,17 +258,32 @@ function createWriterFileSystem(fileSystem, committedPaths, failedPaths) {
|
|
|
257
258
|
}
|
|
258
259
|
};
|
|
259
260
|
}
|
|
260
|
-
function
|
|
261
|
+
function projectSourceFiles(project) {
|
|
261
262
|
const result = /* @__PURE__ */ new Map();
|
|
262
|
-
for (const pkg of project.packages)
|
|
263
|
-
|
|
264
|
-
const fileName = resource.fileName ?? resource.file ?? "";
|
|
265
|
-
if (!fileName) continue;
|
|
266
|
-
result.set(`${pkg.id}/${resource.id}`, {
|
|
263
|
+
for (const pkg of project.packages) {
|
|
264
|
+
result.set(`${pkg.id}/package.xml`, {
|
|
267
265
|
packageName: pkg.name,
|
|
268
|
-
branch:
|
|
269
|
-
path:
|
|
270
|
-
fileName
|
|
266
|
+
branch: "",
|
|
267
|
+
path: "",
|
|
268
|
+
fileName: "package.xml"
|
|
269
|
+
});
|
|
270
|
+
const branches = /* @__PURE__ */ new Set();
|
|
271
|
+
for (const resource of pkg.resources) {
|
|
272
|
+
if (resource.branch) branches.add(resource.branch);
|
|
273
|
+
const fileName = resource.kind === "component" ? `${resource.name}.xml` : resource.fileName ?? resource.file ?? "";
|
|
274
|
+
if (!fileName) continue;
|
|
275
|
+
result.set(`${pkg.id}/${resource.id}`, {
|
|
276
|
+
packageName: pkg.name,
|
|
277
|
+
branch: resource.branch,
|
|
278
|
+
path: resource.path,
|
|
279
|
+
fileName
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
for (const branch of branches) result.set(`${pkg.id}/branch/${branch}`, {
|
|
283
|
+
packageName: pkg.name,
|
|
284
|
+
branch,
|
|
285
|
+
path: "",
|
|
286
|
+
fileName: "package_branch.xml"
|
|
271
287
|
});
|
|
272
288
|
}
|
|
273
289
|
return result;
|
|
@@ -280,10 +296,10 @@ function sourceFileKey(source) {
|
|
|
280
296
|
source.fileName
|
|
281
297
|
].join("\0");
|
|
282
298
|
}
|
|
283
|
-
function
|
|
299
|
+
function recordStaleProjectFiles(session, previousProject, nextProject) {
|
|
284
300
|
if (!session.fileSystem) return;
|
|
285
|
-
const previousSources =
|
|
286
|
-
const nextSourceKeys = new Set([...
|
|
301
|
+
const previousSources = projectSourceFiles(previousProject);
|
|
302
|
+
const nextSourceKeys = new Set([...projectSourceFiles(nextProject).values()].map(sourceFileKey));
|
|
287
303
|
for (const source of previousSources.values()) {
|
|
288
304
|
const key = sourceFileKey(source);
|
|
289
305
|
if (!nextSourceKeys.has(key)) session.pendingStaleSourceFiles.set(key, source);
|
|
@@ -308,6 +324,14 @@ function createCapabilityUnavailableError$1(message) {
|
|
|
308
324
|
requiredAdapter: "BackendFileSystem"
|
|
309
325
|
};
|
|
310
326
|
}
|
|
327
|
+
function createUamFidelityUnsupportedError(session) {
|
|
328
|
+
return {
|
|
329
|
+
code: "uam_fidelity_unsupported",
|
|
330
|
+
message: "The source project contains formal properties that the current UAM cannot preserve.",
|
|
331
|
+
sessionId: session.sessionId,
|
|
332
|
+
canonicalPathKey: session.canonicalPathKey
|
|
333
|
+
};
|
|
334
|
+
}
|
|
311
335
|
function validationDiagnostics(sessionProject) {
|
|
312
336
|
return validateUamProject(sessionProject).map((issue) => ({
|
|
313
337
|
code: "materialize_validation_failed",
|
|
@@ -339,12 +363,32 @@ function storageCanonicalTarget(input) {
|
|
|
339
363
|
};
|
|
340
364
|
}
|
|
341
365
|
var AuthoringService = class {
|
|
366
|
+
sessionOperations = /* @__PURE__ */ new Map();
|
|
342
367
|
constructor(context, cacheService, eventService) {
|
|
343
368
|
this.context = context;
|
|
344
369
|
this.cacheService = cacheService;
|
|
345
370
|
this.eventService = eventService;
|
|
346
371
|
}
|
|
372
|
+
async runSessionExclusive(sessionId, operation) {
|
|
373
|
+
const previous = this.sessionOperations.get(sessionId) ?? Promise.resolve();
|
|
374
|
+
let release = () => void 0;
|
|
375
|
+
const current = new Promise((resolve) => {
|
|
376
|
+
release = resolve;
|
|
377
|
+
});
|
|
378
|
+
const tail = previous.then(() => current);
|
|
379
|
+
this.sessionOperations.set(sessionId, tail);
|
|
380
|
+
await previous;
|
|
381
|
+
try {
|
|
382
|
+
return await operation();
|
|
383
|
+
} finally {
|
|
384
|
+
release();
|
|
385
|
+
if (this.sessionOperations.get(sessionId) === tail) this.sessionOperations.delete(sessionId);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
347
388
|
async applyTransaction(input) {
|
|
389
|
+
return this.runSessionExclusive(input.sessionId, () => this.applyTransactionExclusive(input));
|
|
390
|
+
}
|
|
391
|
+
async applyTransactionExclusive(input) {
|
|
348
392
|
const startedAt = Date.now();
|
|
349
393
|
const session = this.context.sessions.get(input.sessionId);
|
|
350
394
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
@@ -379,7 +423,7 @@ var AuthoringService = class {
|
|
|
379
423
|
diagnostics
|
|
380
424
|
});
|
|
381
425
|
}
|
|
382
|
-
|
|
426
|
+
recordStaleProjectFiles(session, session.project, result.project);
|
|
383
427
|
session.project = result.project;
|
|
384
428
|
session.revision += 1;
|
|
385
429
|
session.dirty = true;
|
|
@@ -411,6 +455,9 @@ var AuthoringService = class {
|
|
|
411
455
|
mode: "fullProject",
|
|
412
456
|
reason: "force_save"
|
|
413
457
|
});
|
|
458
|
+
return this.runSessionExclusive(input.sessionId, () => this.saveSessionExclusive(input));
|
|
459
|
+
}
|
|
460
|
+
async saveSessionExclusive(input) {
|
|
414
461
|
const startedAt = Date.now();
|
|
415
462
|
const session = this.context.sessions.get(input.sessionId);
|
|
416
463
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
@@ -432,6 +479,10 @@ var AuthoringService = class {
|
|
|
432
479
|
sessionId: session.sessionId,
|
|
433
480
|
revision: session.revision
|
|
434
481
|
});
|
|
482
|
+
if (session.uamFidelity === "unsupported") return failure("authoring", startedAt, createUamFidelityUnsupportedError(session), toSessionSnapshot(session, this.context.capabilities), {
|
|
483
|
+
sessionId: session.sessionId,
|
|
484
|
+
revision: session.revision
|
|
485
|
+
});
|
|
435
486
|
const committedPaths = [];
|
|
436
487
|
const failedPaths = [];
|
|
437
488
|
this.eventService.emit({
|
|
@@ -490,6 +541,9 @@ var AuthoringService = class {
|
|
|
490
541
|
}
|
|
491
542
|
}
|
|
492
543
|
async materializeSession(input) {
|
|
544
|
+
return this.runSessionExclusive(input.sessionId, () => this.materializeSessionExclusive(input));
|
|
545
|
+
}
|
|
546
|
+
async materializeSessionExclusive(input) {
|
|
493
547
|
const startedAt = Date.now();
|
|
494
548
|
const session = this.context.sessions.get(input.sessionId);
|
|
495
549
|
if (!session || session.closed) return failure("authoring", startedAt, createSessionNotFoundError(input.sessionId));
|
|
@@ -522,6 +576,10 @@ var AuthoringService = class {
|
|
|
522
576
|
revision: session.revision
|
|
523
577
|
});
|
|
524
578
|
}
|
|
579
|
+
if (session.uamFidelity === "unsupported") return failure("authoring", startedAt, createUamFidelityUnsupportedError(session), toSessionSnapshot(session, this.context.capabilities), {
|
|
580
|
+
sessionId: session.sessionId,
|
|
581
|
+
revision: session.revision
|
|
582
|
+
});
|
|
525
583
|
const diagnostics = validationDiagnostics(session.project);
|
|
526
584
|
if (diagnostics.length > 0) return failure("authoring", startedAt, {
|
|
527
585
|
code: "materialize_validation_failed",
|
|
@@ -1100,6 +1158,68 @@ function createProjectReaderFileSystem(fileSystem) {
|
|
|
1100
1158
|
}
|
|
1101
1159
|
};
|
|
1102
1160
|
}
|
|
1161
|
+
function createCaptureFileSystem(files) {
|
|
1162
|
+
const normalize = (filePath) => filePath.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
1163
|
+
return {
|
|
1164
|
+
async readFile(filePath) {
|
|
1165
|
+
const value = files.get(normalize(filePath));
|
|
1166
|
+
if (typeof value !== "string") throw new Error(`Captured text file was not found: ${filePath}`);
|
|
1167
|
+
return value;
|
|
1168
|
+
},
|
|
1169
|
+
async readFileRaw(filePath) {
|
|
1170
|
+
const value = files.get(normalize(filePath));
|
|
1171
|
+
if (!(value instanceof Uint8Array)) throw new Error(`Captured binary file was not found: ${filePath}`);
|
|
1172
|
+
return value.slice();
|
|
1173
|
+
},
|
|
1174
|
+
async writeFile(filePath, content) {
|
|
1175
|
+
files.set(normalize(filePath), content);
|
|
1176
|
+
},
|
|
1177
|
+
async writeFileRaw(filePath, data) {
|
|
1178
|
+
files.set(normalize(filePath), data.slice());
|
|
1179
|
+
},
|
|
1180
|
+
async mkdir() {},
|
|
1181
|
+
async readdir() {
|
|
1182
|
+
return [];
|
|
1183
|
+
},
|
|
1184
|
+
async exists(filePath) {
|
|
1185
|
+
return files.has(normalize(filePath));
|
|
1186
|
+
},
|
|
1187
|
+
join(...paths) {
|
|
1188
|
+
return normalize(paths.filter(Boolean).join("/"));
|
|
1189
|
+
},
|
|
1190
|
+
dirname(filePath) {
|
|
1191
|
+
const normalized = normalize(filePath);
|
|
1192
|
+
const separator = normalized.lastIndexOf("/");
|
|
1193
|
+
return separator < 0 ? "" : normalized.slice(0, separator);
|
|
1194
|
+
},
|
|
1195
|
+
async unlink(filePath) {
|
|
1196
|
+
files.delete(normalize(filePath));
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
function capturedFilesEqual(left, right) {
|
|
1201
|
+
if (left.size !== right.size) return false;
|
|
1202
|
+
for (const [filePath, leftValue] of left) {
|
|
1203
|
+
const rightValue = right.get(filePath);
|
|
1204
|
+
if (typeof leftValue === "string") {
|
|
1205
|
+
if (leftValue !== rightValue) return false;
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1208
|
+
if (!(rightValue instanceof Uint8Array) || leftValue.length !== rightValue.length) return false;
|
|
1209
|
+
for (let index = 0; index < leftValue.length; index += 1) if (leftValue[index] !== rightValue[index]) return false;
|
|
1210
|
+
}
|
|
1211
|
+
return true;
|
|
1212
|
+
}
|
|
1213
|
+
async function hasFullUamFidelity(document, project) {
|
|
1214
|
+
const sourceFiles = /* @__PURE__ */ new Map();
|
|
1215
|
+
const materializedFiles = /* @__PURE__ */ new Map();
|
|
1216
|
+
try {
|
|
1217
|
+
await Promise.all([new ProjectWriter(createCaptureFileSystem(sourceFiles)).write(document, "Project.fairy"), new ProjectWriter(createCaptureFileSystem(materializedFiles)).write(materializeUamProject(project), "Project.fairy")]);
|
|
1218
|
+
} catch {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
return capturedFilesEqual(sourceFiles, materializedFiles);
|
|
1222
|
+
}
|
|
1103
1223
|
var RuntimeService = class {
|
|
1104
1224
|
constructor(context, cacheService, eventService, jobService) {
|
|
1105
1225
|
this.context = context;
|
|
@@ -1134,7 +1254,8 @@ var RuntimeService = class {
|
|
|
1134
1254
|
canonicalPathKey
|
|
1135
1255
|
}));
|
|
1136
1256
|
await advisoryLock.close();
|
|
1137
|
-
const
|
|
1257
|
+
const document = await new ProjectReader(createProjectReaderFileSystem(fileSystem)).read(fairyPath, { hydrateResourceBytes: true });
|
|
1258
|
+
const project = liftDocumentToUamProject(document);
|
|
1138
1259
|
const sessionId = randomId();
|
|
1139
1260
|
const session = {
|
|
1140
1261
|
sessionId,
|
|
@@ -1144,6 +1265,7 @@ var RuntimeService = class {
|
|
|
1144
1265
|
lockFilePath,
|
|
1145
1266
|
fileSystem,
|
|
1146
1267
|
project,
|
|
1268
|
+
uamFidelity: await hasFullUamFidelity(document, project) ? "full" : "unsupported",
|
|
1147
1269
|
revision: 0,
|
|
1148
1270
|
lastSavedRevision: 0,
|
|
1149
1271
|
pendingStaleSourceFiles: /* @__PURE__ */ new Map(),
|
|
@@ -1202,6 +1324,7 @@ var RuntimeService = class {
|
|
|
1202
1324
|
lockFilePath: "",
|
|
1203
1325
|
fileSystem: storage?.fileSystem,
|
|
1204
1326
|
project: normalizeUamProject(input.project),
|
|
1327
|
+
uamFidelity: "full",
|
|
1205
1328
|
revision: 0,
|
|
1206
1329
|
lastSavedRevision: 0,
|
|
1207
1330
|
pendingStaleSourceFiles: /* @__PURE__ */ new Map(),
|
|
@@ -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 };
|