@openfairygui/backend 0.2.0-alpha.30 → 0.2.0-alpha.31
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/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{runtime-NiBgr7PF.mjs → runtime-BDkZmTFN.mjs} +14 -97
- package/dist/{runtime-CcBLI-J7.cjs → runtime-DtcaaVfy.cjs} +13 -96
- package/package.json +3 -3
- package/src/services/authoring-service.ts +10 -66
- package/src/services/cache-service.ts +1 -2
- package/src/services/event-service.ts +1 -2
- package/src/services/job-service.ts +4 -5
- package/src/services/read-service.ts +1 -2
- package/src/services/session-utils.ts +1 -2
- package/src/services/snapshot-utils.ts +0 -43
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-DtcaaVfy.cjs");
|
|
3
3
|
//#region src/storage.ts
|
|
4
4
|
var StorageFileStat = class {
|
|
5
5
|
constructor(kind) {
|
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-BDkZmTFN.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-DtcaaVfy.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.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UAM_SUPPORTED_MATERIALIZATION_SCOPE, UAM_SUPPORTED_TRANSACTION_SCOPE, commitUamProjectSourcePaths, liftDocumentToUamProject, materializeUamProject, normalizeUamProject, validateUamProject } from "@openfairygui/core/uam";
|
|
1
|
+
import { UAM_SUPPORTED_MATERIALIZATION_SCOPE, UAM_SUPPORTED_TRANSACTION_SCOPE, commitUamProjectSourcePaths, liftDocumentToUamProject, materializeUamProject, normalizeUamProject, staleResourceFolders, staleSourceFiles, validateUamProject } from "@openfairygui/core/uam";
|
|
2
2
|
import { applyUamTransactionApp } from "@openfairygui/functions/uam";
|
|
3
3
|
import { ProjectReader, ProjectWriter } from "@openfairygui/core/project-io";
|
|
4
4
|
//#region src/contracts.ts
|
|
@@ -165,40 +165,6 @@ async function writeSessionProject(input) {
|
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
//#endregion
|
|
168
|
-
//#region src/services/snapshot-utils.ts
|
|
169
|
-
function cloneJsonValue(value) {
|
|
170
|
-
if (value === void 0 || value === null) return value;
|
|
171
|
-
return JSON.parse(JSON.stringify(value));
|
|
172
|
-
}
|
|
173
|
-
function cloneEventSnapshot(event) {
|
|
174
|
-
return {
|
|
175
|
-
...event,
|
|
176
|
-
diagnostics: event.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
177
|
-
payload: cloneJsonValue(event.payload)
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
function cloneJobSnapshot(job) {
|
|
181
|
-
return {
|
|
182
|
-
...job,
|
|
183
|
-
diagnostics: job.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
184
|
-
progress: job.progress ? { ...job.progress } : void 0,
|
|
185
|
-
result: cloneJsonValue(job.result),
|
|
186
|
-
error: cloneJsonValue(job.error)
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
function cloneCacheEntrySnapshot(entry) {
|
|
190
|
-
return {
|
|
191
|
-
...entry,
|
|
192
|
-
summary: {
|
|
193
|
-
...entry.summary,
|
|
194
|
-
diagnostics: entry.summary.diagnostics.map((diagnostic) => ({ ...diagnostic }))
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
function cloneCapabilitiesSnapshot(capabilities) {
|
|
199
|
-
return cloneJsonValue(capabilities);
|
|
200
|
-
}
|
|
201
|
-
//#endregion
|
|
202
168
|
//#region src/services/session-utils.ts
|
|
203
169
|
function toSessionSnapshot(session, capabilities) {
|
|
204
170
|
return {
|
|
@@ -209,7 +175,7 @@ function toSessionSnapshot(session, capabilities) {
|
|
|
209
175
|
dirty: session.dirty,
|
|
210
176
|
uamFidelity: session.uamFidelity,
|
|
211
177
|
lockHeld: session.lockHeld,
|
|
212
|
-
capabilities:
|
|
178
|
+
capabilities: structuredClone(capabilities)
|
|
213
179
|
};
|
|
214
180
|
}
|
|
215
181
|
function createSessionNotFoundError(sessionId) {
|
|
@@ -231,37 +197,6 @@ function createStaleWriteError(session, expectedRevision) {
|
|
|
231
197
|
}
|
|
232
198
|
//#endregion
|
|
233
199
|
//#region src/services/authoring-service.ts
|
|
234
|
-
function projectSourceFiles(project) {
|
|
235
|
-
const result = /* @__PURE__ */ new Map();
|
|
236
|
-
for (const pkg of project.packages) {
|
|
237
|
-
result.set(`${pkg.id}/package.xml`, {
|
|
238
|
-
packageName: pkg.name,
|
|
239
|
-
branch: "",
|
|
240
|
-
path: "",
|
|
241
|
-
fileName: "package.xml"
|
|
242
|
-
});
|
|
243
|
-
const branches = /* @__PURE__ */ new Set();
|
|
244
|
-
for (const folder of pkg.folders) if (folder.branch) branches.add(folder.branch);
|
|
245
|
-
for (const resource of pkg.resources) {
|
|
246
|
-
if (resource.branch) branches.add(resource.branch);
|
|
247
|
-
const fileName = resource.kind === "component" ? `${resource.name}.xml` : resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? "";
|
|
248
|
-
if (!fileName) continue;
|
|
249
|
-
result.set(`${pkg.id}/${resource.id}`, {
|
|
250
|
-
packageName: pkg.name,
|
|
251
|
-
branch: resource.branch,
|
|
252
|
-
path: resource.path,
|
|
253
|
-
fileName
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
for (const branch of branches) result.set(`${pkg.id}/branch/${branch}`, {
|
|
257
|
-
packageName: pkg.name,
|
|
258
|
-
branch,
|
|
259
|
-
path: "",
|
|
260
|
-
fileName: "package_branch.xml"
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
return result;
|
|
264
|
-
}
|
|
265
200
|
function sourceFileKey(source) {
|
|
266
201
|
return [
|
|
267
202
|
source.branch,
|
|
@@ -270,15 +205,6 @@ function sourceFileKey(source) {
|
|
|
270
205
|
source.fileName
|
|
271
206
|
].join("\0");
|
|
272
207
|
}
|
|
273
|
-
function projectResourceFolders(project) {
|
|
274
|
-
const result = /* @__PURE__ */ new Map();
|
|
275
|
-
for (const pkg of project.packages) for (const folder of pkg.folders) result.set(`${pkg.id}/${folder.branch}/${folder.path}`, {
|
|
276
|
-
packageName: pkg.name,
|
|
277
|
-
branch: folder.branch,
|
|
278
|
-
path: folder.path
|
|
279
|
-
});
|
|
280
|
-
return result;
|
|
281
|
-
}
|
|
282
208
|
function resourceFolderKey(folder) {
|
|
283
209
|
return [
|
|
284
210
|
folder.branch,
|
|
@@ -288,20 +214,10 @@ function resourceFolderKey(folder) {
|
|
|
288
214
|
}
|
|
289
215
|
function recordStaleProjectFiles(session, previousProject, nextProject) {
|
|
290
216
|
if (!session.fileSystem) return;
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
for (const
|
|
294
|
-
|
|
295
|
-
if (!nextSourceKeys.has(key)) session.pendingStaleSourceFiles.set(key, source);
|
|
296
|
-
}
|
|
297
|
-
for (const key of nextSourceKeys) session.pendingStaleSourceFiles.delete(key);
|
|
298
|
-
const previousFolders = projectResourceFolders(previousProject);
|
|
299
|
-
const nextFolderKeys = new Set([...projectResourceFolders(nextProject).values()].map(resourceFolderKey));
|
|
300
|
-
for (const folder of previousFolders.values()) {
|
|
301
|
-
const key = resourceFolderKey(folder);
|
|
302
|
-
if (!nextFolderKeys.has(key)) session.pendingStaleResourceFolders.set(key, folder);
|
|
303
|
-
}
|
|
304
|
-
for (const key of nextFolderKeys) session.pendingStaleResourceFolders.delete(key);
|
|
217
|
+
for (const source of staleSourceFiles(previousProject, nextProject)) session.pendingStaleSourceFiles.set(sourceFileKey(source), source);
|
|
218
|
+
for (const source of staleSourceFiles(nextProject, previousProject)) session.pendingStaleSourceFiles.delete(sourceFileKey(source));
|
|
219
|
+
for (const folder of staleResourceFolders(previousProject, nextProject)) session.pendingStaleResourceFolders.set(resourceFolderKey(folder), folder);
|
|
220
|
+
for (const folder of staleResourceFolders(nextProject, previousProject)) session.pendingStaleResourceFolders.delete(resourceFolderKey(folder));
|
|
305
221
|
}
|
|
306
222
|
function toBackendDiagnostics(error) {
|
|
307
223
|
return error.diagnostics.length > 0 ? error.diagnostics.map((diagnostic) => ({ ...diagnostic })) : [{
|
|
@@ -749,7 +665,7 @@ var CacheService = class {
|
|
|
749
665
|
const entry = this.context.cacheBySession.get(input.sessionId);
|
|
750
666
|
return success("read", startedAt, {
|
|
751
667
|
cacheRevision: entry?.revision ?? session.revision,
|
|
752
|
-
entries: entry ? [
|
|
668
|
+
entries: entry ? [structuredClone(entry)] : []
|
|
753
669
|
}, {
|
|
754
670
|
sessionId: session.sessionId,
|
|
755
671
|
revision: session.revision
|
|
@@ -820,7 +736,7 @@ var EventService = class {
|
|
|
820
736
|
const filtered = events.filter((event) => event.sequence > after);
|
|
821
737
|
const limit = input.limit === void 0 ? filtered.length : Math.max(0, input.limit);
|
|
822
738
|
return success("runtime", startedAt, {
|
|
823
|
-
events: filtered.slice(0, limit).map(
|
|
739
|
+
events: filtered.slice(0, limit).map((event) => structuredClone(event)),
|
|
824
740
|
oldestSequence,
|
|
825
741
|
currentSequence,
|
|
826
742
|
cursorExpired: false
|
|
@@ -895,7 +811,7 @@ var JobService = class {
|
|
|
895
811
|
jobId
|
|
896
812
|
});
|
|
897
813
|
this.scheduleRefreshJob(session.sessionId, jobId);
|
|
898
|
-
return success("runtime", startedAt,
|
|
814
|
+
return success("runtime", startedAt, structuredClone(job), {
|
|
899
815
|
sessionId: session.sessionId,
|
|
900
816
|
revision: session.revision
|
|
901
817
|
});
|
|
@@ -914,7 +830,7 @@ var JobService = class {
|
|
|
914
830
|
sessionId: session.sessionId,
|
|
915
831
|
revision: session.revision
|
|
916
832
|
});
|
|
917
|
-
return success("runtime", startedAt,
|
|
833
|
+
return success("runtime", startedAt, structuredClone(job), {
|
|
918
834
|
sessionId: session.sessionId,
|
|
919
835
|
revision: session.revision
|
|
920
836
|
});
|
|
@@ -929,7 +845,7 @@ var JobService = class {
|
|
|
929
845
|
else if (input.status === "terminal") jobs = jobs.filter((job) => isTerminal(job.status));
|
|
930
846
|
else jobs = jobs.filter((job) => job.status === input.status);
|
|
931
847
|
if (input.limit !== void 0) jobs = jobs.slice(0, Math.max(0, input.limit));
|
|
932
|
-
return success("runtime", startedAt, { jobs: jobs.map(
|
|
848
|
+
return success("runtime", startedAt, { jobs: jobs.map((job) => structuredClone(job)) }, {
|
|
933
849
|
sessionId: session.sessionId,
|
|
934
850
|
revision: session.revision
|
|
935
851
|
});
|
|
@@ -966,7 +882,8 @@ var JobService = class {
|
|
|
966
882
|
revision: session.revision,
|
|
967
883
|
jobId: job.jobId
|
|
968
884
|
});
|
|
969
|
-
|
|
885
|
+
const cancelled = this.cancelRefreshJob(session.sessionId, job);
|
|
886
|
+
return success("runtime", startedAt, structuredClone(cancelled), {
|
|
970
887
|
sessionId: session.sessionId,
|
|
971
888
|
revision: session.revision
|
|
972
889
|
});
|
|
@@ -1113,7 +1030,7 @@ var ReadService = class {
|
|
|
1113
1030
|
this.context = context;
|
|
1114
1031
|
}
|
|
1115
1032
|
getCapabilities() {
|
|
1116
|
-
return success("read", Date.now(),
|
|
1033
|
+
return success("read", Date.now(), structuredClone(this.context.capabilities));
|
|
1117
1034
|
}
|
|
1118
1035
|
getSession(input) {
|
|
1119
1036
|
const startedAt = Date.now();
|
|
@@ -166,40 +166,6 @@ async function writeSessionProject(input) {
|
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
168
|
//#endregion
|
|
169
|
-
//#region src/services/snapshot-utils.ts
|
|
170
|
-
function cloneJsonValue(value) {
|
|
171
|
-
if (value === void 0 || value === null) return value;
|
|
172
|
-
return JSON.parse(JSON.stringify(value));
|
|
173
|
-
}
|
|
174
|
-
function cloneEventSnapshot(event) {
|
|
175
|
-
return {
|
|
176
|
-
...event,
|
|
177
|
-
diagnostics: event.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
178
|
-
payload: cloneJsonValue(event.payload)
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
function cloneJobSnapshot(job) {
|
|
182
|
-
return {
|
|
183
|
-
...job,
|
|
184
|
-
diagnostics: job.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
185
|
-
progress: job.progress ? { ...job.progress } : void 0,
|
|
186
|
-
result: cloneJsonValue(job.result),
|
|
187
|
-
error: cloneJsonValue(job.error)
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
function cloneCacheEntrySnapshot(entry) {
|
|
191
|
-
return {
|
|
192
|
-
...entry,
|
|
193
|
-
summary: {
|
|
194
|
-
...entry.summary,
|
|
195
|
-
diagnostics: entry.summary.diagnostics.map((diagnostic) => ({ ...diagnostic }))
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
function cloneCapabilitiesSnapshot(capabilities) {
|
|
200
|
-
return cloneJsonValue(capabilities);
|
|
201
|
-
}
|
|
202
|
-
//#endregion
|
|
203
169
|
//#region src/services/session-utils.ts
|
|
204
170
|
function toSessionSnapshot(session, capabilities) {
|
|
205
171
|
return {
|
|
@@ -210,7 +176,7 @@ function toSessionSnapshot(session, capabilities) {
|
|
|
210
176
|
dirty: session.dirty,
|
|
211
177
|
uamFidelity: session.uamFidelity,
|
|
212
178
|
lockHeld: session.lockHeld,
|
|
213
|
-
capabilities:
|
|
179
|
+
capabilities: structuredClone(capabilities)
|
|
214
180
|
};
|
|
215
181
|
}
|
|
216
182
|
function createSessionNotFoundError(sessionId) {
|
|
@@ -232,37 +198,6 @@ function createStaleWriteError(session, expectedRevision) {
|
|
|
232
198
|
}
|
|
233
199
|
//#endregion
|
|
234
200
|
//#region src/services/authoring-service.ts
|
|
235
|
-
function projectSourceFiles(project) {
|
|
236
|
-
const result = /* @__PURE__ */ new Map();
|
|
237
|
-
for (const pkg of project.packages) {
|
|
238
|
-
result.set(`${pkg.id}/package.xml`, {
|
|
239
|
-
packageName: pkg.name,
|
|
240
|
-
branch: "",
|
|
241
|
-
path: "",
|
|
242
|
-
fileName: "package.xml"
|
|
243
|
-
});
|
|
244
|
-
const branches = /* @__PURE__ */ new Set();
|
|
245
|
-
for (const folder of pkg.folders) if (folder.branch) branches.add(folder.branch);
|
|
246
|
-
for (const resource of pkg.resources) {
|
|
247
|
-
if (resource.branch) branches.add(resource.branch);
|
|
248
|
-
const fileName = resource.kind === "component" ? `${resource.name}.xml` : resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? "";
|
|
249
|
-
if (!fileName) continue;
|
|
250
|
-
result.set(`${pkg.id}/${resource.id}`, {
|
|
251
|
-
packageName: pkg.name,
|
|
252
|
-
branch: resource.branch,
|
|
253
|
-
path: resource.path,
|
|
254
|
-
fileName
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
for (const branch of branches) result.set(`${pkg.id}/branch/${branch}`, {
|
|
258
|
-
packageName: pkg.name,
|
|
259
|
-
branch,
|
|
260
|
-
path: "",
|
|
261
|
-
fileName: "package_branch.xml"
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
201
|
function sourceFileKey(source) {
|
|
267
202
|
return [
|
|
268
203
|
source.branch,
|
|
@@ -271,15 +206,6 @@ function sourceFileKey(source) {
|
|
|
271
206
|
source.fileName
|
|
272
207
|
].join("\0");
|
|
273
208
|
}
|
|
274
|
-
function projectResourceFolders(project) {
|
|
275
|
-
const result = /* @__PURE__ */ new Map();
|
|
276
|
-
for (const pkg of project.packages) for (const folder of pkg.folders) result.set(`${pkg.id}/${folder.branch}/${folder.path}`, {
|
|
277
|
-
packageName: pkg.name,
|
|
278
|
-
branch: folder.branch,
|
|
279
|
-
path: folder.path
|
|
280
|
-
});
|
|
281
|
-
return result;
|
|
282
|
-
}
|
|
283
209
|
function resourceFolderKey(folder) {
|
|
284
210
|
return [
|
|
285
211
|
folder.branch,
|
|
@@ -289,20 +215,10 @@ function resourceFolderKey(folder) {
|
|
|
289
215
|
}
|
|
290
216
|
function recordStaleProjectFiles(session, previousProject, nextProject) {
|
|
291
217
|
if (!session.fileSystem) return;
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
for (const
|
|
295
|
-
|
|
296
|
-
if (!nextSourceKeys.has(key)) session.pendingStaleSourceFiles.set(key, source);
|
|
297
|
-
}
|
|
298
|
-
for (const key of nextSourceKeys) session.pendingStaleSourceFiles.delete(key);
|
|
299
|
-
const previousFolders = projectResourceFolders(previousProject);
|
|
300
|
-
const nextFolderKeys = new Set([...projectResourceFolders(nextProject).values()].map(resourceFolderKey));
|
|
301
|
-
for (const folder of previousFolders.values()) {
|
|
302
|
-
const key = resourceFolderKey(folder);
|
|
303
|
-
if (!nextFolderKeys.has(key)) session.pendingStaleResourceFolders.set(key, folder);
|
|
304
|
-
}
|
|
305
|
-
for (const key of nextFolderKeys) session.pendingStaleResourceFolders.delete(key);
|
|
218
|
+
for (const source of (0, _openfairygui_core_uam.staleSourceFiles)(previousProject, nextProject)) session.pendingStaleSourceFiles.set(sourceFileKey(source), source);
|
|
219
|
+
for (const source of (0, _openfairygui_core_uam.staleSourceFiles)(nextProject, previousProject)) session.pendingStaleSourceFiles.delete(sourceFileKey(source));
|
|
220
|
+
for (const folder of (0, _openfairygui_core_uam.staleResourceFolders)(previousProject, nextProject)) session.pendingStaleResourceFolders.set(resourceFolderKey(folder), folder);
|
|
221
|
+
for (const folder of (0, _openfairygui_core_uam.staleResourceFolders)(nextProject, previousProject)) session.pendingStaleResourceFolders.delete(resourceFolderKey(folder));
|
|
306
222
|
}
|
|
307
223
|
function toBackendDiagnostics(error) {
|
|
308
224
|
return error.diagnostics.length > 0 ? error.diagnostics.map((diagnostic) => ({ ...diagnostic })) : [{
|
|
@@ -750,7 +666,7 @@ var CacheService = class {
|
|
|
750
666
|
const entry = this.context.cacheBySession.get(input.sessionId);
|
|
751
667
|
return success("read", startedAt, {
|
|
752
668
|
cacheRevision: entry?.revision ?? session.revision,
|
|
753
|
-
entries: entry ? [
|
|
669
|
+
entries: entry ? [structuredClone(entry)] : []
|
|
754
670
|
}, {
|
|
755
671
|
sessionId: session.sessionId,
|
|
756
672
|
revision: session.revision
|
|
@@ -821,7 +737,7 @@ var EventService = class {
|
|
|
821
737
|
const filtered = events.filter((event) => event.sequence > after);
|
|
822
738
|
const limit = input.limit === void 0 ? filtered.length : Math.max(0, input.limit);
|
|
823
739
|
return success("runtime", startedAt, {
|
|
824
|
-
events: filtered.slice(0, limit).map(
|
|
740
|
+
events: filtered.slice(0, limit).map((event) => structuredClone(event)),
|
|
825
741
|
oldestSequence,
|
|
826
742
|
currentSequence,
|
|
827
743
|
cursorExpired: false
|
|
@@ -896,7 +812,7 @@ var JobService = class {
|
|
|
896
812
|
jobId
|
|
897
813
|
});
|
|
898
814
|
this.scheduleRefreshJob(session.sessionId, jobId);
|
|
899
|
-
return success("runtime", startedAt,
|
|
815
|
+
return success("runtime", startedAt, structuredClone(job), {
|
|
900
816
|
sessionId: session.sessionId,
|
|
901
817
|
revision: session.revision
|
|
902
818
|
});
|
|
@@ -915,7 +831,7 @@ var JobService = class {
|
|
|
915
831
|
sessionId: session.sessionId,
|
|
916
832
|
revision: session.revision
|
|
917
833
|
});
|
|
918
|
-
return success("runtime", startedAt,
|
|
834
|
+
return success("runtime", startedAt, structuredClone(job), {
|
|
919
835
|
sessionId: session.sessionId,
|
|
920
836
|
revision: session.revision
|
|
921
837
|
});
|
|
@@ -930,7 +846,7 @@ var JobService = class {
|
|
|
930
846
|
else if (input.status === "terminal") jobs = jobs.filter((job) => isTerminal(job.status));
|
|
931
847
|
else jobs = jobs.filter((job) => job.status === input.status);
|
|
932
848
|
if (input.limit !== void 0) jobs = jobs.slice(0, Math.max(0, input.limit));
|
|
933
|
-
return success("runtime", startedAt, { jobs: jobs.map(
|
|
849
|
+
return success("runtime", startedAt, { jobs: jobs.map((job) => structuredClone(job)) }, {
|
|
934
850
|
sessionId: session.sessionId,
|
|
935
851
|
revision: session.revision
|
|
936
852
|
});
|
|
@@ -967,7 +883,8 @@ var JobService = class {
|
|
|
967
883
|
revision: session.revision,
|
|
968
884
|
jobId: job.jobId
|
|
969
885
|
});
|
|
970
|
-
|
|
886
|
+
const cancelled = this.cancelRefreshJob(session.sessionId, job);
|
|
887
|
+
return success("runtime", startedAt, structuredClone(cancelled), {
|
|
971
888
|
sessionId: session.sessionId,
|
|
972
889
|
revision: session.revision
|
|
973
890
|
});
|
|
@@ -1114,7 +1031,7 @@ var ReadService = class {
|
|
|
1114
1031
|
this.context = context;
|
|
1115
1032
|
}
|
|
1116
1033
|
getCapabilities() {
|
|
1117
|
-
return success("read", Date.now(),
|
|
1034
|
+
return success("read", Date.now(), structuredClone(this.context.capabilities));
|
|
1118
1035
|
}
|
|
1119
1036
|
getSession(input) {
|
|
1120
1037
|
const startedAt = Date.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfairygui/backend",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.31",
|
|
4
4
|
"description": "FairyGUI Headless Authoring SDK — stateful backend runtime and session services.",
|
|
5
5
|
"author": "OpenFairyGUI Contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"runtime"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@openfairygui/core": "0.2.0-alpha.
|
|
56
|
-
"@openfairygui/functions": "0.2.0-alpha.
|
|
55
|
+
"@openfairygui/core": "0.2.0-alpha.31",
|
|
56
|
+
"@openfairygui/functions": "0.2.0-alpha.31"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"ava": "^7.0.0",
|
|
@@ -2,6 +2,8 @@ import type { ProjectResourceFolder, ProjectSourceFile } from '@openfairygui/cor
|
|
|
2
2
|
import {
|
|
3
3
|
commitUamProjectSourcePaths,
|
|
4
4
|
materializeUamProject,
|
|
5
|
+
staleResourceFolders,
|
|
6
|
+
staleSourceFiles,
|
|
5
7
|
type UamProject,
|
|
6
8
|
validateUamProject,
|
|
7
9
|
} from '@openfairygui/core/uam';
|
|
@@ -31,62 +33,10 @@ import type { EventService } from './event-service.js';
|
|
|
31
33
|
import { writeSessionProject } from './session-project-writer.js';
|
|
32
34
|
import { createSessionNotFoundError, createStaleWriteError, toSessionSnapshot } from './session-utils.js';
|
|
33
35
|
|
|
34
|
-
function projectSourceFiles(project: UamProject): Map<string, ProjectSourceFile> {
|
|
35
|
-
const result = new Map<string, ProjectSourceFile>();
|
|
36
|
-
for (const pkg of project.packages) {
|
|
37
|
-
result.set(`${pkg.id}/package.xml`, {
|
|
38
|
-
packageName: pkg.name,
|
|
39
|
-
branch: '',
|
|
40
|
-
path: '',
|
|
41
|
-
fileName: 'package.xml',
|
|
42
|
-
});
|
|
43
|
-
const branches = new Set<string>();
|
|
44
|
-
for (const folder of pkg.folders) {
|
|
45
|
-
if (folder.branch) branches.add(folder.branch);
|
|
46
|
-
}
|
|
47
|
-
for (const resource of pkg.resources) {
|
|
48
|
-
if (resource.branch) branches.add(resource.branch);
|
|
49
|
-
const fileName = resource.kind === 'component'
|
|
50
|
-
? `${resource.name}.xml`
|
|
51
|
-
: resource.fileName ?? (resource.kind === 'image' ? '' : resource.file) ?? '';
|
|
52
|
-
if (!fileName) continue;
|
|
53
|
-
result.set(`${pkg.id}/${resource.id}`, {
|
|
54
|
-
packageName: pkg.name,
|
|
55
|
-
branch: resource.branch,
|
|
56
|
-
path: resource.path,
|
|
57
|
-
fileName,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
for (const branch of branches) {
|
|
61
|
-
result.set(`${pkg.id}/branch/${branch}`, {
|
|
62
|
-
packageName: pkg.name,
|
|
63
|
-
branch,
|
|
64
|
-
path: '',
|
|
65
|
-
fileName: 'package_branch.xml',
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
36
|
function sourceFileKey(source: ProjectSourceFile): string {
|
|
73
37
|
return [source.branch, source.packageName, source.path, source.fileName].join('\0');
|
|
74
38
|
}
|
|
75
39
|
|
|
76
|
-
function projectResourceFolders(project: UamProject): Map<string, ProjectResourceFolder> {
|
|
77
|
-
const result = new Map<string, ProjectResourceFolder>();
|
|
78
|
-
for (const pkg of project.packages) {
|
|
79
|
-
for (const folder of pkg.folders) {
|
|
80
|
-
result.set(`${pkg.id}/${folder.branch}/${folder.path}`, {
|
|
81
|
-
packageName: pkg.name,
|
|
82
|
-
branch: folder.branch,
|
|
83
|
-
path: folder.path,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
40
|
function resourceFolderKey(folder: ProjectResourceFolder): string {
|
|
91
41
|
return [folder.branch, folder.packageName, folder.path].join('\0');
|
|
92
42
|
}
|
|
@@ -97,23 +47,17 @@ function recordStaleProjectFiles(
|
|
|
97
47
|
nextProject: UamProject,
|
|
98
48
|
): void {
|
|
99
49
|
if (!session.fileSystem) return;
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
for (const source of previousSources.values()) {
|
|
103
|
-
const key = sourceFileKey(source);
|
|
104
|
-
if (!nextSourceKeys.has(key)) session.pendingStaleSourceFiles.set(key, source);
|
|
50
|
+
for (const source of staleSourceFiles(previousProject, nextProject)) {
|
|
51
|
+
session.pendingStaleSourceFiles.set(sourceFileKey(source), source);
|
|
105
52
|
}
|
|
106
|
-
for (const
|
|
107
|
-
session.pendingStaleSourceFiles.delete(
|
|
53
|
+
for (const source of staleSourceFiles(nextProject, previousProject)) {
|
|
54
|
+
session.pendingStaleSourceFiles.delete(sourceFileKey(source));
|
|
108
55
|
}
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
for (const folder of previousFolders.values()) {
|
|
112
|
-
const key = resourceFolderKey(folder);
|
|
113
|
-
if (!nextFolderKeys.has(key)) session.pendingStaleResourceFolders.set(key, folder);
|
|
56
|
+
for (const folder of staleResourceFolders(previousProject, nextProject)) {
|
|
57
|
+
session.pendingStaleResourceFolders.set(resourceFolderKey(folder), folder);
|
|
114
58
|
}
|
|
115
|
-
for (const
|
|
116
|
-
session.pendingStaleResourceFolders.delete(
|
|
59
|
+
for (const folder of staleResourceFolders(nextProject, previousProject)) {
|
|
60
|
+
session.pendingStaleResourceFolders.delete(resourceFolderKey(folder));
|
|
117
61
|
}
|
|
118
62
|
}
|
|
119
63
|
|
|
@@ -7,7 +7,6 @@ import type {
|
|
|
7
7
|
GetCacheSnapshotInput,
|
|
8
8
|
SessionNotFoundError,
|
|
9
9
|
} from '../runtime.js';
|
|
10
|
-
import { cloneCacheEntrySnapshot } from './snapshot-utils.js';
|
|
11
10
|
|
|
12
11
|
function createCacheEntry(session: BackendSessionState, valid: boolean): BackendCacheEntry {
|
|
13
12
|
return {
|
|
@@ -38,7 +37,7 @@ export class CacheService {
|
|
|
38
37
|
const entry = this.context.cacheBySession.get(input.sessionId);
|
|
39
38
|
return success('read', startedAt, {
|
|
40
39
|
cacheRevision: entry?.revision ?? session.revision,
|
|
41
|
-
entries: entry ? [
|
|
40
|
+
entries: entry ? [structuredClone(entry)] : [],
|
|
42
41
|
}, { sessionId: session.sessionId, revision: session.revision });
|
|
43
42
|
}
|
|
44
43
|
|
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
GetEventsSnapshot,
|
|
9
9
|
SessionNotFoundError,
|
|
10
10
|
} from '../runtime.js';
|
|
11
|
-
import { cloneEventSnapshot } from './snapshot-utils.js';
|
|
12
11
|
|
|
13
12
|
const DEFAULT_EVENT_RETENTION_LIMIT = 1000;
|
|
14
13
|
|
|
@@ -71,7 +70,7 @@ export class EventService {
|
|
|
71
70
|
const filtered = events.filter((event) => event.sequence > after);
|
|
72
71
|
const limit = input.limit === undefined ? filtered.length : Math.max(0, input.limit);
|
|
73
72
|
return success('runtime', startedAt, {
|
|
74
|
-
events: filtered.slice(0, limit).map(
|
|
73
|
+
events: filtered.slice(0, limit).map((event) => structuredClone(event)),
|
|
75
74
|
oldestSequence,
|
|
76
75
|
currentSequence,
|
|
77
76
|
cursorExpired: false,
|
|
@@ -2,7 +2,6 @@ import { failure, success, type BackendContext } from './context.js';
|
|
|
2
2
|
import type { CacheService } from './cache-service.js';
|
|
3
3
|
import type { EventService } from './event-service.js';
|
|
4
4
|
import { createSessionNotFoundError } from './session-utils.js';
|
|
5
|
-
import { cloneJobSnapshot } from './snapshot-utils.js';
|
|
6
5
|
import type {
|
|
7
6
|
BackendJobListSnapshot,
|
|
8
7
|
BackendJobNotCancellableError,
|
|
@@ -76,7 +75,7 @@ export class JobService {
|
|
|
76
75
|
this.eventService.emit({ kind: 'job.created', sessionId: session.sessionId, canonicalPathKey: session.canonicalPathKey, revision: session.revision, jobId });
|
|
77
76
|
this.scheduleRefreshJob(session.sessionId, jobId);
|
|
78
77
|
|
|
79
|
-
return success('runtime', startedAt,
|
|
78
|
+
return success('runtime', startedAt, structuredClone(job), { sessionId: session.sessionId, revision: session.revision });
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
public getJob(input: GetJobInput): BackendResult<BackendJobSnapshot, SessionNotFoundError | BackendJobNotFoundError> {
|
|
@@ -92,7 +91,7 @@ export class JobService {
|
|
|
92
91
|
jobId: input.jobId,
|
|
93
92
|
}, undefined, { sessionId: session.sessionId, revision: session.revision });
|
|
94
93
|
}
|
|
95
|
-
return success('runtime', startedAt,
|
|
94
|
+
return success('runtime', startedAt, structuredClone(job), { sessionId: session.sessionId, revision: session.revision });
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
public listJobs(input: ListJobsInput): BackendResult<BackendJobListSnapshot, SessionNotFoundError> {
|
|
@@ -107,7 +106,7 @@ export class JobService {
|
|
|
107
106
|
else jobs = jobs.filter((job) => job.status === input.status);
|
|
108
107
|
}
|
|
109
108
|
if (input.limit !== undefined) jobs = jobs.slice(0, Math.max(0, input.limit));
|
|
110
|
-
return success('runtime', startedAt, { jobs: jobs.map(
|
|
109
|
+
return success('runtime', startedAt, { jobs: jobs.map((job) => structuredClone(job)) }, { sessionId: session.sessionId, revision: session.revision });
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
public cancelJob(input: CancelJobInput): BackendResult<BackendJobSnapshot, SessionNotFoundError | BackendJobNotFoundError | BackendJobNotCancellableError> {
|
|
@@ -135,7 +134,7 @@ export class JobService {
|
|
|
135
134
|
this.cancellationRequests.add(job.jobId);
|
|
136
135
|
this.eventService.emit({ kind: 'job.cancelRequested', sessionId: input.sessionId, canonicalPathKey: session.canonicalPathKey, revision: session.revision, jobId: job.jobId });
|
|
137
136
|
const cancelled = this.cancelRefreshJob(session.sessionId, job);
|
|
138
|
-
return success('runtime', startedAt,
|
|
137
|
+
return success('runtime', startedAt, structuredClone(cancelled), { sessionId: session.sessionId, revision: session.revision });
|
|
139
138
|
}
|
|
140
139
|
|
|
141
140
|
public removeSession(sessionId: string): void {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { failure, success, type BackendContext } from './context.js';
|
|
2
2
|
import type { BackendCapabilities, BackendResult, BackendSessionSnapshot, SessionNotFoundError } from '../runtime.js';
|
|
3
3
|
import { createSessionNotFoundError, toSessionSnapshot } from './session-utils.js';
|
|
4
|
-
import { cloneCapabilitiesSnapshot } from './snapshot-utils.js';
|
|
5
4
|
|
|
6
5
|
export class ReadService {
|
|
7
6
|
public constructor(private readonly context: BackendContext) {}
|
|
8
7
|
|
|
9
8
|
public getCapabilities(): BackendResult<BackendCapabilities> {
|
|
10
|
-
return success('read', Date.now(),
|
|
9
|
+
return success('read', Date.now(), structuredClone(this.context.capabilities));
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
public getSession(input: { sessionId: string }): BackendResult<BackendSessionSnapshot, SessionNotFoundError> {
|
|
@@ -5,7 +5,6 @@ import type {
|
|
|
5
5
|
SessionStaleWriteError,
|
|
6
6
|
} from '../runtime.js';
|
|
7
7
|
import type { BackendSessionState } from './context.js';
|
|
8
|
-
import { cloneCapabilitiesSnapshot } from './snapshot-utils.js';
|
|
9
8
|
|
|
10
9
|
export function toSessionSnapshot(
|
|
11
10
|
session: BackendSessionState,
|
|
@@ -19,7 +18,7 @@ export function toSessionSnapshot(
|
|
|
19
18
|
dirty: session.dirty,
|
|
20
19
|
uamFidelity: session.uamFidelity,
|
|
21
20
|
lockHeld: session.lockHeld,
|
|
22
|
-
capabilities:
|
|
21
|
+
capabilities: structuredClone(capabilities),
|
|
23
22
|
};
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
BackendCacheEntry,
|
|
3
|
-
BackendCapabilities,
|
|
4
|
-
BackendEvent,
|
|
5
|
-
BackendJobSnapshot,
|
|
6
|
-
} from '../runtime.js';
|
|
7
|
-
|
|
8
|
-
function cloneJsonValue<T>(value: T): T {
|
|
9
|
-
if (value === undefined || value === null) return value;
|
|
10
|
-
return JSON.parse(JSON.stringify(value)) as T;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function cloneEventSnapshot(event: BackendEvent): BackendEvent {
|
|
14
|
-
return {
|
|
15
|
-
...event,
|
|
16
|
-
diagnostics: event.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
17
|
-
payload: cloneJsonValue(event.payload),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function cloneJobSnapshot(job: BackendJobSnapshot): BackendJobSnapshot {
|
|
22
|
-
return {
|
|
23
|
-
...job,
|
|
24
|
-
diagnostics: job.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
25
|
-
progress: job.progress ? { ...job.progress } : undefined,
|
|
26
|
-
result: cloneJsonValue(job.result),
|
|
27
|
-
error: cloneJsonValue(job.error),
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function cloneCacheEntrySnapshot(entry: BackendCacheEntry): BackendCacheEntry {
|
|
32
|
-
return {
|
|
33
|
-
...entry,
|
|
34
|
-
summary: {
|
|
35
|
-
...entry.summary,
|
|
36
|
-
diagnostics: entry.summary.diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function cloneCapabilitiesSnapshot(capabilities: BackendCapabilities): BackendCapabilities {
|
|
42
|
-
return cloneJsonValue(capabilities);
|
|
43
|
-
}
|