@openfairygui/backend 0.2.0-alpha.1 → 0.2.0-alpha.13

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.
@@ -1,5 +1,5 @@
1
- import { UamProject, UamTransactionOperation } from "@openfairygui/core";
2
- import { ApplyUamTransactionAppError } from "@openfairygui/functions";
1
+ import { UamProject, UamTransactionOperation } from "@openfairygui/core/uam";
2
+ import { ApplyUamTransactionAppError } from "@openfairygui/functions/uam";
3
3
 
4
4
  //#region src/contracts.d.ts
5
5
  declare const BACKEND_CONTRACT_VERSION: "1.1.0-p2";
@@ -18,6 +18,14 @@ interface BackendDiagnostic {
18
18
  code: string;
19
19
  message: string;
20
20
  severity: 'info' | 'warning' | 'error';
21
+ path?: string;
22
+ nodeKind?: string;
23
+ resourceKind?: string;
24
+ gearKind?: string;
25
+ field?: string;
26
+ operationKind?: string;
27
+ opIndex?: number;
28
+ opId?: string;
21
29
  }
22
30
  interface BackendResponseMeta {
23
31
  requestId: string;
@@ -87,7 +95,13 @@ interface BackendCapabilityManifest {
87
95
  adapters: {
88
96
  fileSystem: {
89
97
  injected: true;
90
- requiredFor: readonly ['openSession', 'saveSession'];
98
+ requiredFor: readonly ['openSession', 'saveSession', 'materializeSession'];
99
+ };
100
+ projectStorage: {
101
+ injected: true;
102
+ browserSafe: true;
103
+ requiredFor: readonly ['openProjectSession.writeback', 'saveSession', 'materializeSession'];
104
+ adapterFactory: 'createBackendStorageFileSystem';
91
105
  };
92
106
  host: {
93
107
  injected: true;
@@ -111,7 +125,7 @@ interface BackendCapabilities {
111
125
  transactionKernelOwner: '@openfairygui/core';
112
126
  appSeamOwner: '@openfairygui/functions';
113
127
  runtimeOwner: '@openfairygui/backend';
114
- methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
128
+ methods: readonly ['getCapabilities', 'openSession', 'openProjectSession', 'getSession', 'applyTransaction', 'saveSession', 'materializeSession', 'closeSession', 'getEvents', 'getJob', 'listJobs', 'cancelJob', 'getCacheSnapshot', 'refreshCache'];
115
129
  read: {
116
130
  capabilitySnapshot: true;
117
131
  sessionSnapshot: true;
@@ -122,6 +136,11 @@ interface BackendCapabilities {
122
136
  resourceKinds: readonly string[];
123
137
  nodeKinds: readonly string[];
124
138
  gearKinds: readonly string[];
139
+ transactionScope: {
140
+ resourceKinds: readonly string[];
141
+ nodeKinds: readonly string[];
142
+ gearKinds: readonly string[];
143
+ };
125
144
  unsupported: readonly ['artifact.publish', 'artifact.restore'];
126
145
  };
127
146
  artifact: {
@@ -177,6 +196,15 @@ interface BackendSessionSnapshot {
177
196
  lockHeld: boolean;
178
197
  capabilities: BackendCapabilities;
179
198
  }
199
+ interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
200
+ mode: 'fullProject';
201
+ reason?: string;
202
+ materializeRevision: number;
203
+ saveRevision: number;
204
+ writtenPaths: string[];
205
+ skippedPaths: string[];
206
+ diagnostics: BackendDiagnostic[];
207
+ }
180
208
  interface BackendSuccess<T> {
181
209
  ok: true;
182
210
  meta: BackendResponseMeta;
@@ -229,6 +257,27 @@ interface SavePartialFailureError {
229
257
  failedPaths: string[];
230
258
  diskMayBePartiallyUpdated: true;
231
259
  }
260
+ interface MaterializeValidationFailedError {
261
+ code: 'materialize_validation_failed';
262
+ message: string;
263
+ sessionId: string;
264
+ canonicalPathKey: string;
265
+ issueCount: number;
266
+ diagnostics: BackendDiagnostic[];
267
+ }
268
+ interface MaterializeWriteFailedError {
269
+ code: 'write_failed';
270
+ message: string;
271
+ sessionId: string;
272
+ canonicalPathKey: string;
273
+ attemptedRevision: number;
274
+ lastSavedRevision: number;
275
+ writtenPaths: string[];
276
+ failedPaths: string[];
277
+ skippedPaths: string[];
278
+ diagnostics: BackendDiagnostic[];
279
+ diskMayBePartiallyUpdated: true;
280
+ }
232
281
  type BackendEventKind = 'session.opened' | 'transaction.applied' | 'transaction.rejected' | 'save.started' | 'save.completed' | 'save.failed' | 'session.closeRequested' | 'session.closed' | 'cache.invalidated' | 'cache.updated' | 'job.created' | 'job.started' | 'job.progress' | 'job.cancelRequested' | 'job.cancelled' | 'job.completed' | 'job.failed';
233
282
  interface BackendEvent {
234
283
  sequence: number;
@@ -360,7 +409,7 @@ interface RefreshCacheInput {
360
409
  sessionId: string;
361
410
  reason?: 'manual' | 'session_open' | 'after_save';
362
411
  }
363
- type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
412
+ type BackendError = SessionNotFoundError | SessionStaleWriteError | InProcessLockConflictError | AdvisoryLockConflictError | SavePartialFailureError | MaterializeValidationFailedError | MaterializeWriteFailedError | PathPolicyViolationError | EventCursorInvalidError | BackendJobNotFoundError | BackendJobNotCancellableError | BackendJobCancelledError | CacheRefreshFailedError | BackendCapabilityUnavailableError | ApplyUamTransactionAppError;
364
413
  interface ApplySessionTransactionInput {
365
414
  sessionId: string;
366
415
  expectedRevision: number;
@@ -371,6 +420,30 @@ interface OpenProjectSessionInput {
371
420
  sessionId?: string;
372
421
  canonicalProjectPath?: string;
373
422
  canonicalPathKey?: string;
423
+ storage?: BackendProjectSessionStorage;
424
+ }
425
+ interface BackendProjectSessionStorage {
426
+ fileSystem: BackendFileSystem;
427
+ fairyPath: string;
428
+ canonicalProjectPath?: string;
429
+ canonicalPathKey?: string;
430
+ }
431
+ interface SaveSessionInput {
432
+ sessionId: string;
433
+ expectedRevision?: number;
434
+ targetPath?: string;
435
+ fileSystem?: BackendFileSystem;
436
+ force?: boolean;
437
+ mode?: 'materializeCleanSession';
438
+ }
439
+ interface MaterializeSessionInput {
440
+ sessionId: string;
441
+ expectedRevision?: number;
442
+ storage?: BackendProjectSessionStorage;
443
+ targetPath?: string;
444
+ fileSystem?: BackendFileSystem;
445
+ mode?: 'fullProject';
446
+ reason?: string;
374
447
  }
375
448
  interface BackendRuntimeOptions {
376
449
  fileSystem?: BackendFileSystem;
@@ -402,11 +475,8 @@ declare class BackendRuntime {
402
475
  sessionId: string;
403
476
  }): BackendResult<BackendSessionSnapshot, SessionNotFoundError>;
404
477
  applyTransaction(input: ApplySessionTransactionInput): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>>;
405
- saveSession(input: {
406
- sessionId: string;
407
- expectedRevision?: number;
408
- targetPath?: string;
409
- }): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | PathPolicyViolationError | BackendCapabilityUnavailableError>>;
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>>;
410
480
  closeSession(input: {
411
481
  sessionId: string;
412
482
  }): Promise<BackendResult<{
@@ -421,4 +491,4 @@ declare class BackendRuntime {
421
491
  refreshCache(input: RefreshCacheInput): BackendResult<BackendJobSnapshot, SessionNotFoundError>;
422
492
  }
423
493
  //#endregion
424
- export { BackendSuccess as A, OpenProjectSessionInput as B, BackendJobProgress as C, BackendRuntime as D, BackendResult as E, GetEventsInput as F, BACKEND_CAPABILITY_SCHEMA_VERSION as G, SavePartialFailureError as H, GetEventsSnapshot as I, BackendDiagnostic as J, BACKEND_COMPATIBILITY_POLICY as K, GetJobInput as L, CancelJobInput as M, EventCursorInvalidError as N, BackendRuntimeOptions as O, GetCacheSnapshotInput as P, InProcessLockConflictError as R, BackendJobNotFoundError as S, BackendJobStatus as T, SessionNotFoundError as U, RefreshCacheInput as V, SessionStaleWriteError as W, BackendResponseMeta as X, BackendMessage as Y, BackendStage as Z, BackendJobErrors as _, BackendCacheSnapshot as a, BackendJobListStatusFilter as b, BackendCapabilityUnavailableError as c, BackendEventKind as d, BackendFailure as f, BackendHostAdapter as g, BackendFileSystem as h, BackendCacheEntry as i, CacheRefreshFailedError as j, BackendSessionSnapshot as k, BackendError as l, BackendFileStat as m, ApplySessionTransactionInput as n, BackendCapabilities as o, BackendFileHandle as p, BACKEND_CONTRACT_VERSION as q, BackendArtifactBridgeCapability as r, BackendCapabilityManifest as s, AdvisoryLockConflictError as t, BackendEvent as u, BackendJobKind as v, BackendJobSnapshot as w, BackendJobNotCancellableError as x, BackendJobListSnapshot as y, ListJobsInput as z };
494
+ export { BACKEND_CONTRACT_VERSION 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_COMPATIBILITY_POLICY 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, BACKEND_CAPABILITY_SCHEMA_VERSION as Z, BackendJobErrors as _, BackendCacheSnapshot as a, BackendJobListStatusFilter as b, BackendCapabilityUnavailableError as c, BackendEventKind as d, BackendDiagnostic as et, BackendFailure as f, BackendHostAdapter as g, BackendFileSystem as h, BackendCacheEntry as i, BackendSuccess as j, BackendRuntimeOptions as k, BackendError as l, BackendFileStat as m, ApplySessionTransactionInput as n, BackendResponseMeta as nt, BackendCapabilities as o, BackendFileHandle as p, SavePartialFailureError as q, BackendArtifactBridgeCapability as r, BackendStage as rt, BackendCapabilityManifest as s, AdvisoryLockConflictError as t, BackendMessage as tt, BackendEvent as u, BackendJobKind as v, BackendJobSnapshot as w, BackendJobNotCancellableError as x, BackendJobListSnapshot as y, InProcessLockConflictError as z };
package/package.json CHANGED
@@ -1,66 +1,66 @@
1
1
  {
2
- "name": "@openfairygui/backend",
3
- "version": "0.2.0-alpha.1",
4
- "description": "FairyGUI Headless Authoring SDK — stateful backend runtime and session services.",
5
- "author": "OpenFairyGUI Contributors",
6
- "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/OpenFairyGUI/OpenFairyGUI.git",
10
- "directory": "packages/backend"
11
- },
12
- "homepage": "https://github.com/OpenFairyGUI/OpenFairyGUI#readme",
13
- "bugs": {
14
- "url": "https://github.com/OpenFairyGUI/OpenFairYGUI/issues"
15
- },
16
- "type": "module",
17
- "sideEffects": false,
18
- "main": "./dist/index.cjs",
19
- "module": "./dist/index.mjs",
20
- "types": "./dist/index.d.mts",
21
- "exports": {
22
- ".": {
23
- "require": {
24
- "types": "./dist/index.d.cts",
25
- "default": "./dist/index.cjs"
26
- },
27
- "default": {
28
- "types": "./dist/index.d.mts",
29
- "default": "./dist/index.mjs"
30
- }
31
- },
32
- "./node": {
33
- "require": {
34
- "types": "./dist/node.d.cts",
35
- "default": "./dist/node.cjs"
36
- },
37
- "default": {
38
- "types": "./dist/node.d.mts",
39
- "default": "./dist/node.mjs"
40
- }
41
- }
42
- },
43
- "scripts": {
44
- "build": "tsdown src/index.ts src/node.ts --format esm,cjs --platform node --external node:fs --external node:fs/promises --external node:path --env.PACKAGE_VERSION=$npm_package_version",
45
- "build:watch": "tsdown src/index.ts src/node.ts --watch --format esm,cjs --platform node --external node:fs --external node:fs/promises --external node:path --env.PACKAGE_VERSION=$npm_package_version"
46
- },
47
- "files": [
48
- "dist/",
49
- "src/"
50
- ],
51
- "keywords": [
52
- "fairygui",
53
- "backend",
54
- "session",
55
- "authoring",
56
- "runtime"
57
- ],
58
- "dependencies": {
59
- "@openfairygui/core": "workspace:*",
60
- "@openfairygui/functions": "workspace:*"
61
- },
62
- "devDependencies": {
63
- "ava": "^7.0.0",
64
- "tsx": "^4.0.0"
65
- }
66
- }
2
+ "name": "@openfairygui/backend",
3
+ "version": "0.2.0-alpha.13",
4
+ "description": "FairyGUI Headless Authoring SDK — stateful backend runtime and session services.",
5
+ "author": "OpenFairyGUI Contributors",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/OpenFairyGUI/OpenFairyGUI.git",
10
+ "directory": "packages/backend"
11
+ },
12
+ "homepage": "https://github.com/OpenFairyGUI/OpenFairyGUI#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/OpenFairyGUI/OpenFairYGUI/issues"
15
+ },
16
+ "type": "module",
17
+ "sideEffects": false,
18
+ "main": "./dist/index.cjs",
19
+ "module": "./dist/index.mjs",
20
+ "types": "./dist/index.d.mts",
21
+ "exports": {
22
+ ".": {
23
+ "require": {
24
+ "types": "./dist/index.d.cts",
25
+ "default": "./dist/index.cjs"
26
+ },
27
+ "default": {
28
+ "types": "./dist/index.d.mts",
29
+ "default": "./dist/index.mjs"
30
+ }
31
+ },
32
+ "./node": {
33
+ "require": {
34
+ "types": "./dist/node.d.cts",
35
+ "default": "./dist/node.cjs"
36
+ },
37
+ "default": {
38
+ "types": "./dist/node.d.mts",
39
+ "default": "./dist/node.mjs"
40
+ }
41
+ }
42
+ },
43
+ "files": [
44
+ "dist/",
45
+ "src/"
46
+ ],
47
+ "keywords": [
48
+ "fairygui",
49
+ "backend",
50
+ "session",
51
+ "authoring",
52
+ "runtime"
53
+ ],
54
+ "dependencies": {
55
+ "@openfairygui/core": "0.2.0-alpha.13",
56
+ "@openfairygui/functions": "0.2.0-alpha.13"
57
+ },
58
+ "devDependencies": {
59
+ "ava": "^7.0.0",
60
+ "tsx": "^4.0.0"
61
+ },
62
+ "scripts": {
63
+ "build": "tsdown src/index.ts src/node.ts --format esm,cjs --platform node --external node:fs --external node:fs/promises --external node:path --env.PACKAGE_VERSION=$npm_package_version",
64
+ "build:watch": "tsdown src/index.ts src/node.ts --watch --format esm,cjs --platform node --external node:fs --external node:fs/promises --external node:path --env.PACKAGE_VERSION=$npm_package_version"
65
+ }
66
+ }
package/src/contracts.ts CHANGED
@@ -17,6 +17,14 @@ export interface BackendDiagnostic {
17
17
  code: string;
18
18
  message: string;
19
19
  severity: 'info' | 'warning' | 'error';
20
+ path?: string;
21
+ nodeKind?: string;
22
+ resourceKind?: string;
23
+ gearKind?: string;
24
+ field?: string;
25
+ operationKind?: string;
26
+ opIndex?: number;
27
+ opId?: string;
20
28
  }
21
29
 
22
30
  export interface BackendResponseMeta {
package/src/index.ts CHANGED
@@ -38,12 +38,24 @@ export {
38
38
  type GetJobInput,
39
39
  type InProcessLockConflictError,
40
40
  type ListJobsInput,
41
+ type MaterializeSessionInput,
42
+ type MaterializeSessionSnapshot,
43
+ type MaterializeValidationFailedError,
44
+ type MaterializeWriteFailedError,
41
45
  type OpenProjectSessionInput,
46
+ type BackendProjectSessionStorage,
42
47
  type RefreshCacheInput,
48
+ type SaveSessionInput,
43
49
  type SavePartialFailureError,
44
50
  type SessionNotFoundError,
45
51
  type SessionStaleWriteError,
46
52
  } from './runtime.js';
53
+ export {
54
+ createBackendStorageFileSystem,
55
+ type BackendAsyncStorageAdapter,
56
+ type BackendStorageFileSystem,
57
+ type BackendStorageStatLike,
58
+ } from './storage.js';
47
59
  export {
48
60
  type BackendDiagnostic,
49
61
  type BackendMessage,
package/src/runtime.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  UAM_SUPPORTED_MATERIALIZATION_SCOPE,
3
+ UAM_SUPPORTED_TRANSACTION_SCOPE,
3
4
  type UamProject,
4
5
  type UamTransactionOperation,
5
- } from '@openfairygui/core';
6
- import type { ApplyUamTransactionAppError } from '@openfairygui/functions';
6
+ } from '@openfairygui/core/uam';
7
+ import type { ApplyUamTransactionAppError } from '@openfairygui/functions/uam';
7
8
  import {
8
9
  BACKEND_CAPABILITY_SCHEMA_VERSION,
9
10
  BACKEND_COMPATIBILITY_POLICY,
@@ -47,11 +48,7 @@ export interface BackendFileSystem {
47
48
  }
48
49
 
49
50
  export interface BackendHostAdapter {
50
- lockMetadata?(input: {
51
- canonicalPathKey: string;
52
- canonicalProjectPath: string;
53
- lockFilePath: string;
54
- }): unknown;
51
+ lockMetadata?(input: { canonicalPathKey: string; canonicalProjectPath: string; lockFilePath: string }): unknown;
55
52
  }
56
53
 
57
54
  export interface BackendArtifactBridgeCapability {
@@ -69,7 +66,13 @@ export interface BackendCapabilityManifest {
69
66
  adapters: {
70
67
  fileSystem: {
71
68
  injected: true;
72
- requiredFor: readonly ['openSession', 'saveSession'];
69
+ requiredFor: readonly ['openSession', 'saveSession', 'materializeSession'];
70
+ };
71
+ projectStorage: {
72
+ injected: true;
73
+ browserSafe: true;
74
+ requiredFor: readonly ['openProjectSession.writeback', 'saveSession', 'materializeSession'];
75
+ adapterFactory: 'createBackendStorageFileSystem';
73
76
  };
74
77
  host: {
75
78
  injected: true;
@@ -101,6 +104,7 @@ export interface BackendCapabilities {
101
104
  'getSession',
102
105
  'applyTransaction',
103
106
  'saveSession',
107
+ 'materializeSession',
104
108
  'closeSession',
105
109
  'getEvents',
106
110
  'getJob',
@@ -119,6 +123,11 @@ export interface BackendCapabilities {
119
123
  resourceKinds: readonly string[];
120
124
  nodeKinds: readonly string[];
121
125
  gearKinds: readonly string[];
126
+ transactionScope: {
127
+ resourceKinds: readonly string[];
128
+ nodeKinds: readonly string[];
129
+ gearKinds: readonly string[];
130
+ };
122
131
  unsupported: readonly ['artifact.publish', 'artifact.restore'];
123
132
  };
124
133
  artifact: {
@@ -176,6 +185,16 @@ export interface BackendSessionSnapshot {
176
185
  capabilities: BackendCapabilities;
177
186
  }
178
187
 
188
+ export interface MaterializeSessionSnapshot extends BackendSessionSnapshot {
189
+ mode: 'fullProject';
190
+ reason?: string;
191
+ materializeRevision: number;
192
+ saveRevision: number;
193
+ writtenPaths: string[];
194
+ skippedPaths: string[];
195
+ diagnostics: import('./contracts.js').BackendDiagnostic[];
196
+ }
197
+
179
198
  export interface BackendSuccess<T> {
180
199
  ok: true;
181
200
  meta: BackendResponseMeta;
@@ -189,9 +208,7 @@ export interface BackendFailure<E extends BackendError = BackendError> {
189
208
  session?: BackendSessionSnapshot;
190
209
  }
191
210
 
192
- export type BackendResult<T, E extends BackendError = BackendError> =
193
- | BackendSuccess<T>
194
- | BackendFailure<E>;
211
+ export type BackendResult<T, E extends BackendError = BackendError> = BackendSuccess<T> | BackendFailure<E>;
195
212
 
196
213
  export interface SessionNotFoundError {
197
214
  code: 'session_not_found';
@@ -238,6 +255,29 @@ export interface SavePartialFailureError {
238
255
  diskMayBePartiallyUpdated: true;
239
256
  }
240
257
 
258
+ export interface MaterializeValidationFailedError {
259
+ code: 'materialize_validation_failed';
260
+ message: string;
261
+ sessionId: string;
262
+ canonicalPathKey: string;
263
+ issueCount: number;
264
+ diagnostics: import('./contracts.js').BackendDiagnostic[];
265
+ }
266
+
267
+ export interface MaterializeWriteFailedError {
268
+ code: 'write_failed';
269
+ message: string;
270
+ sessionId: string;
271
+ canonicalPathKey: string;
272
+ attemptedRevision: number;
273
+ lastSavedRevision: number;
274
+ writtenPaths: string[];
275
+ failedPaths: string[];
276
+ skippedPaths: string[];
277
+ diagnostics: import('./contracts.js').BackendDiagnostic[];
278
+ diskMayBePartiallyUpdated: true;
279
+ }
280
+
241
281
  export type BackendEventKind =
242
282
  | 'session.opened'
243
283
  | 'transaction.applied'
@@ -418,6 +458,8 @@ export type BackendError =
418
458
  | InProcessLockConflictError
419
459
  | AdvisoryLockConflictError
420
460
  | SavePartialFailureError
461
+ | MaterializeValidationFailedError
462
+ | MaterializeWriteFailedError
421
463
  | PathPolicyViolationError
422
464
  | EventCursorInvalidError
423
465
  | BackendJobNotFoundError
@@ -438,6 +480,33 @@ export interface OpenProjectSessionInput {
438
480
  sessionId?: string;
439
481
  canonicalProjectPath?: string;
440
482
  canonicalPathKey?: string;
483
+ storage?: BackendProjectSessionStorage;
484
+ }
485
+
486
+ export interface BackendProjectSessionStorage {
487
+ fileSystem: BackendFileSystem;
488
+ fairyPath: string;
489
+ canonicalProjectPath?: string;
490
+ canonicalPathKey?: string;
491
+ }
492
+
493
+ export interface SaveSessionInput {
494
+ sessionId: string;
495
+ expectedRevision?: number;
496
+ targetPath?: string;
497
+ fileSystem?: BackendFileSystem;
498
+ force?: boolean;
499
+ mode?: 'materializeCleanSession';
500
+ }
501
+
502
+ export interface MaterializeSessionInput {
503
+ sessionId: string;
504
+ expectedRevision?: number;
505
+ storage?: BackendProjectSessionStorage;
506
+ targetPath?: string;
507
+ fileSystem?: BackendFileSystem;
508
+ mode?: 'fullProject';
509
+ reason?: string;
441
510
  }
442
511
 
443
512
  export interface BackendRuntimeOptions {
@@ -446,19 +515,20 @@ export interface BackendRuntimeOptions {
446
515
  }
447
516
 
448
517
  const BACKEND_METHODS = [
449
- 'getCapabilities',
450
- 'openSession',
451
- 'openProjectSession',
452
- 'getSession',
518
+ 'getCapabilities',
519
+ 'openSession',
520
+ 'openProjectSession',
521
+ 'getSession',
453
522
  'applyTransaction',
454
523
  'saveSession',
524
+ 'materializeSession',
455
525
  'closeSession',
456
526
  'getEvents',
457
527
  'getJob',
458
528
  'listJobs',
459
529
  'cancelJob',
460
- 'getCacheSnapshot',
461
- 'refreshCache',
530
+ 'getCacheSnapshot',
531
+ 'refreshCache',
462
532
  ] as const;
463
533
 
464
534
  const ARTIFACT_BRIDGE_CAPABILITY = {
@@ -487,6 +557,11 @@ function createCapabilities(): BackendCapabilities {
487
557
  resourceKinds: [...UAM_SUPPORTED_MATERIALIZATION_SCOPE.resourceKinds],
488
558
  nodeKinds: [...UAM_SUPPORTED_MATERIALIZATION_SCOPE.nodeKinds],
489
559
  gearKinds: [...UAM_SUPPORTED_MATERIALIZATION_SCOPE.gearKinds],
560
+ transactionScope: {
561
+ resourceKinds: [...UAM_SUPPORTED_TRANSACTION_SCOPE.resourceKinds],
562
+ nodeKinds: [...UAM_SUPPORTED_TRANSACTION_SCOPE.nodeKinds],
563
+ gearKinds: [...UAM_SUPPORTED_TRANSACTION_SCOPE.gearKinds],
564
+ },
490
565
  unsupported: ['artifact.publish', 'artifact.restore'],
491
566
  },
492
567
  artifact: createArtifactCapabilities(),
@@ -497,7 +572,13 @@ function createCapabilities(): BackendCapabilities {
497
572
  adapters: {
498
573
  fileSystem: {
499
574
  injected: true,
500
- requiredFor: ['openSession', 'saveSession'],
575
+ requiredFor: ['openSession', 'saveSession', 'materializeSession'],
576
+ },
577
+ projectStorage: {
578
+ injected: true,
579
+ browserSafe: true,
580
+ requiredFor: ['openProjectSession.writeback', 'saveSession', 'materializeSession'],
581
+ adapterFactory: 'createBackendStorageFileSystem',
501
582
  },
502
583
  host: {
503
584
  injected: true,
@@ -593,7 +674,14 @@ export class BackendRuntime {
593
674
  return this.readService.getCapabilities() as BackendSuccess<BackendCapabilities>;
594
675
  }
595
676
 
596
- public async openSession(input: { projectPath: string }): Promise<BackendResult<BackendSessionSnapshot, InProcessLockConflictError | AdvisoryLockConflictError | BackendCapabilityUnavailableError>> {
677
+ public async openSession(input: {
678
+ projectPath: string;
679
+ }): Promise<
680
+ BackendResult<
681
+ BackendSessionSnapshot,
682
+ InProcessLockConflictError | AdvisoryLockConflictError | BackendCapabilityUnavailableError
683
+ >
684
+ > {
597
685
  return this.runtimeService.openSession(input);
598
686
  }
599
687
 
@@ -607,27 +695,61 @@ export class BackendRuntime {
607
695
 
608
696
  public async applyTransaction(
609
697
  input: ApplySessionTransactionInput,
610
- ): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError>> {
698
+ ): Promise<
699
+ BackendResult<
700
+ BackendSessionSnapshot,
701
+ SessionNotFoundError | SessionStaleWriteError | ApplyUamTransactionAppError
702
+ >
703
+ > {
611
704
  return this.authoringService.applyTransaction(input);
612
705
  }
613
706
 
614
- public async saveSession(
615
- input: { sessionId: string; expectedRevision?: number; targetPath?: string },
616
- ): Promise<BackendResult<BackendSessionSnapshot, SessionNotFoundError | SessionStaleWriteError | SavePartialFailureError | PathPolicyViolationError | BackendCapabilityUnavailableError>> {
707
+ public async saveSession(input: SaveSessionInput): Promise<
708
+ BackendResult<
709
+ BackendSessionSnapshot | MaterializeSessionSnapshot,
710
+ | SessionNotFoundError
711
+ | SessionStaleWriteError
712
+ | SavePartialFailureError
713
+ | MaterializeValidationFailedError
714
+ | MaterializeWriteFailedError
715
+ | PathPolicyViolationError
716
+ | InProcessLockConflictError
717
+ | BackendCapabilityUnavailableError
718
+ >
719
+ > {
617
720
  return this.authoringService.saveSession(input);
618
721
  }
619
722
 
620
- public async closeSession(
621
- input: { sessionId: string },
622
- ): Promise<BackendResult<{ sessionId: string; closed: true }, SessionNotFoundError>> {
723
+ public async materializeSession(input: MaterializeSessionInput): Promise<
724
+ BackendResult<
725
+ MaterializeSessionSnapshot,
726
+ | SessionNotFoundError
727
+ | SessionStaleWriteError
728
+ | MaterializeValidationFailedError
729
+ | MaterializeWriteFailedError
730
+ | PathPolicyViolationError
731
+ | InProcessLockConflictError
732
+ | BackendCapabilityUnavailableError
733
+ >
734
+ > {
735
+ return this.authoringService.materializeSession(input);
736
+ }
737
+
738
+ public async closeSession(input: {
739
+ sessionId: string;
740
+ }): Promise<BackendResult<{ sessionId: string; closed: true }, SessionNotFoundError>> {
623
741
  return this.runtimeService.closeSession(input);
624
742
  }
625
743
 
626
- public getEvents(input: GetEventsInput): BackendResult<GetEventsSnapshot, SessionNotFoundError | EventCursorInvalidError> {
744
+ public getEvents(
745
+ input: GetEventsInput,
746
+ ): BackendResult<GetEventsSnapshot, SessionNotFoundError | EventCursorInvalidError> {
627
747
  return this.eventService.getEvents(input);
628
748
  }
629
749
 
630
- public getJob(input: GetJobInput): BackendResult<BackendJobSnapshot, SessionNotFoundError | BackendJobNotFoundError> {
750
+ public getJob(
751
+ input: GetJobInput,
752
+ ): BackendResult<BackendJobSnapshot, SessionNotFoundError | BackendJobNotFoundError> {
631
753
  return this.jobService.getJob(input);
632
754
  }
633
755
 
@@ -635,7 +757,12 @@ export class BackendRuntime {
635
757
  return this.jobService.listJobs(input);
636
758
  }
637
759
 
638
- public cancelJob(input: CancelJobInput): BackendResult<BackendJobSnapshot, SessionNotFoundError | BackendJobNotFoundError | BackendJobNotCancellableError> {
760
+ public cancelJob(
761
+ input: CancelJobInput,
762
+ ): BackendResult<
763
+ BackendJobSnapshot,
764
+ SessionNotFoundError | BackendJobNotFoundError | BackendJobNotCancellableError
765
+ > {
639
766
  return this.jobService.cancelJob(input);
640
767
  }
641
768