@caryhu/codemine-forge 0.0.1-alpha.0 → 0.0.1-alpha.1

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.
Files changed (41) hide show
  1. package/README.md +8 -4
  2. package/dist/build-pipeline/diagnostics.d.ts +1 -0
  3. package/dist/build-pipeline/diagnostics.js +10 -1
  4. package/dist/build-pipeline/index.d.ts +1 -1
  5. package/dist/build-pipeline/index.js +2 -1
  6. package/dist/build-pipeline/pipeline.d.ts +2 -0
  7. package/dist/build-pipeline/pipeline.js +131 -8
  8. package/dist/build-pipeline/types.d.ts +6 -2
  9. package/dist/dev-server-preview/server.js +4 -3
  10. package/dist/dev-server-preview/types.d.ts +2 -0
  11. package/dist/forge-controller.js +1 -0
  12. package/dist/index.d.ts +4 -3
  13. package/dist/index.js +15 -2
  14. package/dist/package-resolution/diagnostics.d.ts +1 -0
  15. package/dist/package-resolution/diagnostics.js +10 -1
  16. package/dist/package-resolution/errors.d.ts +2 -1
  17. package/dist/package-resolution/errors.js +2 -1
  18. package/dist/package-resolution/index.d.ts +2 -2
  19. package/dist/package-resolution/index.js +2 -1
  20. package/dist/package-resolution/resolver.d.ts +3 -0
  21. package/dist/package-resolution/resolver.js +123 -29
  22. package/dist/package-resolution/types.d.ts +7 -1
  23. package/dist/telemetry/index.d.ts +68 -0
  24. package/dist/telemetry/index.js +65 -0
  25. package/dist/terminal-commands/npm-build.js +3 -1
  26. package/dist/terminal-commands/npm-dev.js +3 -1
  27. package/dist/terminal-commands/npm-install.js +7 -2
  28. package/dist/terminal-commands/terminal.d.ts +1 -0
  29. package/dist/terminal-commands/terminal.js +1 -0
  30. package/dist/terminal-commands/types.d.ts +2 -0
  31. package/dist/virtual-file-system/diagnostics.d.ts +1 -0
  32. package/dist/virtual-file-system/diagnostics.js +9 -1
  33. package/dist/virtual-file-system/index.d.ts +4 -2
  34. package/dist/virtual-file-system/index.js +7 -1
  35. package/dist/virtual-file-system/snapshot-serialization.d.ts +3 -0
  36. package/dist/virtual-file-system/snapshot-serialization.js +242 -0
  37. package/dist/virtual-file-system/storage.d.ts +1 -1
  38. package/dist/virtual-file-system/storage.js +41 -18
  39. package/dist/virtual-file-system/types.d.ts +28 -1
  40. package/dist/virtual-file-system/types.js +2 -0
  41. package/package.json +1 -1
@@ -1,17 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createPackageCacheKey = exports.createPackageResolver = exports.DefaultPackageResolver = void 0;
4
+ const virtual_file_system_1 = require("../virtual-file-system");
5
+ const telemetry_1 = require("../telemetry");
4
6
  const manifest_1 = require("./manifest");
5
7
  const diagnostics_1 = require("./diagnostics");
6
8
  const errors_1 = require("./errors");
7
9
  const types_1 = require("./types");
8
10
  const DEFAULT_RESOLUTION_MODE = "bundle-alias";
11
+ const DEFAULT_CACHE_MODE = "prefer-cache";
9
12
  class DefaultPackageResolver {
10
13
  constructor(options) {
11
14
  this.options = options;
12
15
  this.capability = types_1.PACKAGE_RESOLUTION_CAPABILITY;
13
16
  this.sources = options.sources ?? [];
14
17
  this.resolutionMode = options.resolutionMode ?? DEFAULT_RESOLUTION_MODE;
18
+ this.cacheMode = options.cacheMode ?? DEFAULT_CACHE_MODE;
19
+ this.telemetry = options.telemetry;
15
20
  this.manifestPath = options.manifestPath ?? manifest_1.DEFAULT_FORGE_MANIFEST_PATH;
16
21
  this.now = options.now ?? (() => new Date().toISOString());
17
22
  }
@@ -19,38 +24,86 @@ class DefaultPackageResolver {
19
24
  return (0, manifest_1.readPackageManifest)(this.options.fileSystem, manifestPath);
20
25
  }
21
26
  async resolve(options = {}) {
22
- const manifest = await this.readManifest(options.manifestPath ?? this.manifestPath);
23
- const requests = (0, manifest_1.collectDependencyRequests)(manifest);
27
+ const telemetryStart = (0, telemetry_1.startForgeTelemetryTiming)(this.now());
28
+ const telemetry = options.telemetry ?? this.telemetry;
24
29
  const sources = options.sources ?? this.sources;
25
30
  const resolutionMode = options.resolutionMode ?? this.resolutionMode;
26
- const packages = [];
27
- for (const request of requests) {
28
- packages.push(await this.resolveRequest(request, sources));
29
- }
30
- packages.sort((left, right) => left.name.localeCompare(right.name));
31
- const lock = createLockMetadata(packages, resolutionMode);
32
- const resultBase = {
33
- manifest,
34
- requests,
35
- packages,
36
- lock,
37
- warnings: [],
38
- };
39
- if (resolutionMode === "import-map") {
40
- return {
41
- ...resultBase,
42
- importMap: createImportMap(packages),
31
+ const cacheMode = options.cacheMode ?? this.cacheMode;
32
+ let requests;
33
+ try {
34
+ const manifest = await this.readManifest(options.manifestPath ?? this.manifestPath);
35
+ requests = (0, manifest_1.collectDependencyRequests)(manifest);
36
+ const packages = [];
37
+ const warnings = [];
38
+ for (const request of requests) {
39
+ try {
40
+ const result = await this.resolveRequest(request, sources, cacheMode);
41
+ packages.push(result.packageRecord);
42
+ warnings.push(...result.warnings);
43
+ }
44
+ catch (error) {
45
+ if (error instanceof errors_1.ForgePackageResolutionError &&
46
+ (warnings.length > 0 || error.warnings.length > 0)) {
47
+ throw new errors_1.ForgePackageResolutionError(error.diagnostic, [
48
+ ...warnings,
49
+ ...error.warnings,
50
+ ]);
51
+ }
52
+ throw error;
53
+ }
54
+ }
55
+ packages.sort((left, right) => left.name.localeCompare(right.name));
56
+ const lock = createLockMetadata(packages, resolutionMode);
57
+ const resultBase = {
58
+ manifest,
59
+ requests,
60
+ packages,
61
+ lock,
62
+ warnings,
43
63
  };
64
+ const result = resolutionMode === "import-map"
65
+ ? {
66
+ ...resultBase,
67
+ importMap: createImportMap(packages),
68
+ }
69
+ : {
70
+ ...resultBase,
71
+ aliases: createBundleAliases(packages),
72
+ };
73
+ this.emitTelemetry(telemetry, telemetryStart, {
74
+ cacheMode,
75
+ dependencyCount: requests.length,
76
+ diagnostics: warnings,
77
+ outcome: "success",
78
+ packageCount: packages.length,
79
+ resolutionMode,
80
+ });
81
+ return result;
82
+ }
83
+ catch (error) {
84
+ if (error instanceof errors_1.ForgePackageResolutionError) {
85
+ this.emitTelemetry(telemetry, telemetryStart, {
86
+ cacheMode,
87
+ dependencyCount: requests?.length,
88
+ diagnostics: [error.diagnostic, ...error.warnings],
89
+ outcome: "failure",
90
+ packageCount: undefined,
91
+ resolutionMode,
92
+ });
93
+ }
94
+ throw error;
44
95
  }
45
- return {
46
- ...resultBase,
47
- aliases: createBundleAliases(packages),
48
- };
49
96
  }
50
- async resolveRequest(request, sources) {
97
+ async resolveRequest(request, sources, cacheMode) {
51
98
  const cachedPackage = await this.readCachedPackage(request);
52
99
  if (cachedPackage !== undefined) {
53
- return cachedPackage;
100
+ return {
101
+ packageRecord: cachedPackage,
102
+ warnings: [],
103
+ };
104
+ }
105
+ if (cacheMode === "cache-only") {
106
+ throw new errors_1.ForgePackageResolutionError((0, diagnostics_1.createOfflineCacheMissDiagnostic)(request.name, request.requestedRange));
54
107
  }
55
108
  for (const source of sources) {
56
109
  const packageRecord = await source.resolvePackage(request);
@@ -58,8 +111,11 @@ class DefaultPackageResolver {
58
111
  continue;
59
112
  }
60
113
  const normalizedRecord = normalizePackageRecord(request, source.id, packageRecord);
61
- await this.writeCachedPackage(request, normalizedRecord);
62
- return normalizedRecord;
114
+ const warnings = await this.writeCachedPackage(request, normalizedRecord);
115
+ return {
116
+ packageRecord: normalizedRecord,
117
+ warnings,
118
+ };
63
119
  }
64
120
  throw new errors_1.ForgePackageResolutionError((0, diagnostics_1.createUnresolvedPackageDiagnostic)(request.name, request.requestedRange));
65
121
  }
@@ -78,8 +134,9 @@ class DefaultPackageResolver {
78
134
  }
79
135
  async writeCachedPackage(request, packageRecord) {
80
136
  if (this.options.storage === undefined) {
81
- return;
137
+ return [];
82
138
  }
139
+ const warnings = [];
83
140
  const records = [
84
141
  createCacheRecord(createPackageCacheKey(request.name, request.requestedRange), packageRecord, this.now()),
85
142
  ];
@@ -87,8 +144,35 @@ class DefaultPackageResolver {
87
144
  records.push(createCacheRecord(createPackageCacheKey(request.name, packageRecord.version), packageRecord, this.now()));
88
145
  }
89
146
  for (const record of records) {
90
- await this.options.storage.putPackageCacheRecord(record);
147
+ try {
148
+ await this.options.storage.putPackageCacheRecord(record);
149
+ }
150
+ catch (error) {
151
+ if (isLimitExceededError(error)) {
152
+ warnings.push(toWarningDiagnostic(error.diagnostic));
153
+ continue;
154
+ }
155
+ throw error;
156
+ }
91
157
  }
158
+ return warnings;
159
+ }
160
+ emitTelemetry(telemetry, telemetryStart, input) {
161
+ const diagnosticSummaries = (0, telemetry_1.summarizeForgeTelemetryDiagnostics)(input.diagnostics);
162
+ const errorDiagnostic = input.diagnostics.find((diagnostic) => diagnostic.severity === "error");
163
+ (0, telemetry_1.emitForgeTelemetry)(telemetry, {
164
+ operation: "package-resolution",
165
+ outcome: input.outcome,
166
+ ...(0, telemetry_1.completeForgeTelemetryTiming)(telemetryStart, this.now()),
167
+ cacheMode: input.cacheMode,
168
+ resolutionMode: input.resolutionMode,
169
+ dependencyCount: input.dependencyCount,
170
+ packageCount: input.packageCount,
171
+ diagnostics: diagnosticSummaries,
172
+ unsupportedPackageReason: errorDiagnostic === undefined
173
+ ? undefined
174
+ : (0, telemetry_1.createForgeUnsupportedPackageReason)(errorDiagnostic),
175
+ });
92
176
  }
93
177
  }
94
178
  exports.DefaultPackageResolver = DefaultPackageResolver;
@@ -170,3 +254,13 @@ function isForgePackageRecord(value) {
170
254
  typeof record.files === "object" &&
171
255
  record.files !== null);
172
256
  }
257
+ function isLimitExceededError(error) {
258
+ return (error instanceof virtual_file_system_1.ForgeFileSystemError &&
259
+ error.diagnostic.code === "limit_exceeded");
260
+ }
261
+ function toWarningDiagnostic(diagnostic) {
262
+ return {
263
+ ...diagnostic,
264
+ severity: "warning",
265
+ };
266
+ }
@@ -1,8 +1,10 @@
1
1
  import type { ForgeDiagnostic, ForgeVirtualFileSystemStorage } from "../virtual-file-system";
2
2
  import type { ForgeVirtualFileSystem } from "../virtual-file-system";
3
+ import type { ForgeTelemetryReporter } from "../telemetry";
3
4
  export declare const PACKAGE_RESOLUTION_CAPABILITY: "package-resolution";
4
5
  export type ForgePackageResolutionMode = "import-map" | "bundle-alias";
5
- export type ForgePackageResolutionDiagnosticCode = "invalid_dependency" | "invalid_manifest" | "unresolved_package" | "unsupported_range";
6
+ export type ForgePackageCacheMode = "prefer-cache" | "cache-only";
7
+ export type ForgePackageResolutionDiagnosticCode = "invalid_dependency" | "invalid_manifest" | "offline_cache_miss" | "unresolved_package" | "unsupported_range";
6
8
  export interface ForgePackageResolutionDiagnostic {
7
9
  readonly code: ForgePackageResolutionDiagnosticCode;
8
10
  readonly severity: "error";
@@ -74,12 +76,16 @@ export interface ForgePackageResolverOptions {
74
76
  readonly storage?: ForgeVirtualFileSystemStorage;
75
77
  readonly sources?: readonly ForgePackageSource[];
76
78
  readonly resolutionMode?: ForgePackageResolutionMode;
79
+ readonly cacheMode?: ForgePackageCacheMode;
80
+ readonly telemetry?: ForgeTelemetryReporter;
77
81
  readonly manifestPath?: string;
78
82
  readonly now?: () => string;
79
83
  }
80
84
  export interface ForgeResolvePackagesOptions {
81
85
  readonly sources?: readonly ForgePackageSource[];
82
86
  readonly resolutionMode?: ForgePackageResolutionMode;
87
+ readonly cacheMode?: ForgePackageCacheMode;
88
+ readonly telemetry?: ForgeTelemetryReporter;
83
89
  readonly manifestPath?: string;
84
90
  }
85
91
  export interface ForgePackageResolutionResult {
@@ -0,0 +1,68 @@
1
+ export declare const TELEMETRY_CAPABILITY: "telemetry";
2
+ export type ForgeTelemetryOperation = "build" | "package-resolution";
3
+ export type ForgeTelemetryOutcome = "failure" | "success";
4
+ export interface ForgeTelemetryTiming {
5
+ readonly startedAt: string;
6
+ readonly endedAt: string;
7
+ readonly durationMs: number;
8
+ }
9
+ export interface ForgeTelemetryTimingStart {
10
+ readonly startedAt: string;
11
+ readonly startedMs: number;
12
+ }
13
+ export interface ForgeTelemetryDiagnosticSummary {
14
+ readonly code: string;
15
+ readonly severity: "error" | "info" | "warning";
16
+ readonly message: string;
17
+ readonly path?: string;
18
+ readonly dependencyName?: string;
19
+ readonly requestedRange?: string;
20
+ readonly importer?: string;
21
+ readonly importSpecifier?: string;
22
+ readonly limitName?: string;
23
+ }
24
+ export interface ForgeUnsupportedPackageReason {
25
+ readonly code: string;
26
+ readonly message: string;
27
+ readonly dependencyName?: string;
28
+ readonly requestedRange?: string;
29
+ }
30
+ export interface ForgePackageResolutionTelemetryEvent extends ForgeTelemetryTiming {
31
+ readonly operation: "package-resolution";
32
+ readonly outcome: ForgeTelemetryOutcome;
33
+ readonly cacheMode: string;
34
+ readonly resolutionMode: string;
35
+ readonly dependencyCount?: number;
36
+ readonly packageCount?: number;
37
+ readonly diagnostics: readonly ForgeTelemetryDiagnosticSummary[];
38
+ readonly unsupportedPackageReason?: ForgeUnsupportedPackageReason;
39
+ }
40
+ export interface ForgeBuildTelemetryEvent extends ForgeTelemetryTiming {
41
+ readonly operation: "build";
42
+ readonly outcome: ForgeTelemetryOutcome;
43
+ readonly mode: string;
44
+ readonly entry?: string;
45
+ readonly outputFileCount: number;
46
+ readonly packageCount?: number;
47
+ readonly diagnostics: readonly ForgeTelemetryDiagnosticSummary[];
48
+ }
49
+ export type ForgeTelemetryEvent = ForgeBuildTelemetryEvent | ForgePackageResolutionTelemetryEvent;
50
+ export type ForgeTelemetryReporter = (event: ForgeTelemetryEvent) => void;
51
+ export interface ForgeTelemetryDiagnosticLike {
52
+ readonly code: string;
53
+ readonly severity: "error" | "info" | "warning";
54
+ readonly message: string;
55
+ readonly path?: string;
56
+ readonly dependencyName?: string;
57
+ readonly requestedRange?: string;
58
+ readonly importer?: string;
59
+ readonly importSpecifier?: string;
60
+ readonly limit?: {
61
+ readonly name?: string;
62
+ };
63
+ }
64
+ export declare function startForgeTelemetryTiming(startedAt: string): ForgeTelemetryTimingStart;
65
+ export declare function completeForgeTelemetryTiming(start: ForgeTelemetryTimingStart, endedAt: string): ForgeTelemetryTiming;
66
+ export declare function summarizeForgeTelemetryDiagnostics(diagnostics: readonly ForgeTelemetryDiagnosticLike[]): readonly ForgeTelemetryDiagnosticSummary[];
67
+ export declare function createForgeUnsupportedPackageReason(diagnostic: ForgeTelemetryDiagnosticLike): ForgeUnsupportedPackageReason | undefined;
68
+ export declare function emitForgeTelemetry(reporter: ForgeTelemetryReporter | undefined, event: ForgeTelemetryEvent): void;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emitForgeTelemetry = exports.createForgeUnsupportedPackageReason = exports.summarizeForgeTelemetryDiagnostics = exports.completeForgeTelemetryTiming = exports.startForgeTelemetryTiming = exports.TELEMETRY_CAPABILITY = void 0;
4
+ exports.TELEMETRY_CAPABILITY = "telemetry";
5
+ function startForgeTelemetryTiming(startedAt) {
6
+ return {
7
+ startedAt,
8
+ startedMs: Date.now(),
9
+ };
10
+ }
11
+ exports.startForgeTelemetryTiming = startForgeTelemetryTiming;
12
+ function completeForgeTelemetryTiming(start, endedAt) {
13
+ return {
14
+ startedAt: start.startedAt,
15
+ endedAt,
16
+ durationMs: Math.max(0, Date.now() - start.startedMs),
17
+ };
18
+ }
19
+ exports.completeForgeTelemetryTiming = completeForgeTelemetryTiming;
20
+ function summarizeForgeTelemetryDiagnostics(diagnostics) {
21
+ return diagnostics.map((diagnostic) => ({
22
+ code: diagnostic.code,
23
+ severity: diagnostic.severity,
24
+ message: diagnostic.message,
25
+ path: diagnostic.path,
26
+ dependencyName: diagnostic.dependencyName,
27
+ requestedRange: diagnostic.requestedRange,
28
+ importer: diagnostic.importer,
29
+ importSpecifier: diagnostic.importSpecifier,
30
+ limitName: diagnostic.limit?.name,
31
+ }));
32
+ }
33
+ exports.summarizeForgeTelemetryDiagnostics = summarizeForgeTelemetryDiagnostics;
34
+ function createForgeUnsupportedPackageReason(diagnostic) {
35
+ if (!isUnsupportedPackageDiagnosticCode(diagnostic.code)) {
36
+ return undefined;
37
+ }
38
+ return {
39
+ code: diagnostic.code,
40
+ message: diagnostic.message,
41
+ dependencyName: diagnostic.dependencyName,
42
+ requestedRange: diagnostic.requestedRange,
43
+ };
44
+ }
45
+ exports.createForgeUnsupportedPackageReason = createForgeUnsupportedPackageReason;
46
+ function emitForgeTelemetry(reporter, event) {
47
+ if (reporter === undefined) {
48
+ return;
49
+ }
50
+ try {
51
+ reporter(event);
52
+ }
53
+ catch {
54
+ // Telemetry is observational and must not alter runtime behavior.
55
+ }
56
+ }
57
+ exports.emitForgeTelemetry = emitForgeTelemetry;
58
+ function isUnsupportedPackageDiagnosticCode(code) {
59
+ return [
60
+ "invalid_dependency",
61
+ "offline_cache_miss",
62
+ "unresolved_package",
63
+ "unsupported_range",
64
+ ].includes(code);
65
+ }
@@ -20,7 +20,9 @@ class NpmRunBuildCommandHandler {
20
20
  diagnostics: [],
21
21
  };
22
22
  }
23
- const buildResult = await context.buildPipeline.build();
23
+ const buildResult = await context.buildPipeline.build({
24
+ signal: context.signal,
25
+ });
24
26
  if (!buildResult.success) {
25
27
  const firstDiagnostic = buildResult.diagnostics[0];
26
28
  return {
@@ -20,7 +20,9 @@ class NpmRunDevCommandHandler {
20
20
  diagnostics: [],
21
21
  };
22
22
  }
23
- const startResult = await context.devServerPreview.start();
23
+ const startResult = await context.devServerPreview.start({
24
+ signal: context.signal,
25
+ });
24
26
  if (!startResult.success) {
25
27
  const firstDiagnostic = startResult.diagnostics[0];
26
28
  return {
@@ -25,8 +25,8 @@ class NpmInstallCommandHandler {
25
25
  return {
26
26
  command: context.command,
27
27
  exitCode: 0,
28
- output,
29
- diagnostics: [],
28
+ output: [...output, ...warningOutput(packageResolution.warnings)],
29
+ diagnostics: packageResolution.warnings,
30
30
  packageResolution,
31
31
  };
32
32
  }
@@ -54,3 +54,8 @@ function stdout(text) {
54
54
  function stderr(text) {
55
55
  return { kind: "stderr", text };
56
56
  }
57
+ function warningOutput(diagnostics) {
58
+ return diagnostics
59
+ .filter((diagnostic) => diagnostic.severity === "warning")
60
+ .map((diagnostic) => stderr(`Forge warning: ${diagnostic.message}`));
61
+ }
@@ -7,6 +7,7 @@ export declare class DefaultForgeTerminal implements ForgeTerminal {
7
7
  constructor(options: ForgeTerminalOptions);
8
8
  execute(commandText: string, executeOptions?: {
9
9
  readonly cwd?: string;
10
+ readonly signal?: AbortSignal;
10
11
  }): Promise<ForgeCommandResult>;
11
12
  }
12
13
  export declare function createForgeTerminal(options: ForgeTerminalOptions): ForgeTerminal;
@@ -42,6 +42,7 @@ class DefaultForgeTerminal {
42
42
  buildPipeline: this.options.buildPipeline,
43
43
  devServerPreview: this.options.devServerPreview,
44
44
  packageResolver: this.options.packageResolver,
45
+ signal: executeOptions.signal,
45
46
  });
46
47
  }
47
48
  }
@@ -35,6 +35,7 @@ export interface ForgeCommandContext {
35
35
  readonly buildPipeline?: ForgeBuildPipeline;
36
36
  readonly devServerPreview?: ForgeDevServerPreview;
37
37
  readonly packageResolver: ForgePackageResolver;
38
+ readonly signal?: AbortSignal;
38
39
  }
39
40
  export interface ForgeCommandHandler {
40
41
  readonly name: string;
@@ -44,6 +45,7 @@ export interface ForgeCommandHandler {
44
45
  }
45
46
  export interface ForgeTerminalExecuteOptions {
46
47
  readonly cwd?: string;
48
+ readonly signal?: AbortSignal;
47
49
  }
48
50
  export interface ForgeTerminalOptions {
49
51
  readonly buildPipeline?: ForgeBuildPipeline;
@@ -8,6 +8,7 @@ export interface ForgeDiagnosticInput {
8
8
  }
9
9
  export declare function createForgeDiagnostic(input: ForgeDiagnosticInput): ForgeDiagnostic;
10
10
  export declare function createInvalidPathDiagnostic(path: string, message?: string): ForgeDiagnostic;
11
+ export declare function createInvalidSnapshotDiagnostic(message?: string, cause?: unknown): ForgeDiagnostic;
11
12
  export declare function createPathTraversalDiagnostic(path: string): ForgeDiagnostic;
12
13
  export declare function createNotFoundDiagnostic(path: string): ForgeDiagnostic;
13
14
  export declare function createMissingParentDiagnostic(path: string): ForgeDiagnostic;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createNotImplementedDiagnostic = exports.createMissingParentDiagnostic = exports.createNotFoundDiagnostic = exports.createPathTraversalDiagnostic = exports.createInvalidPathDiagnostic = exports.createForgeDiagnostic = void 0;
3
+ exports.createNotImplementedDiagnostic = exports.createMissingParentDiagnostic = exports.createNotFoundDiagnostic = exports.createPathTraversalDiagnostic = exports.createInvalidSnapshotDiagnostic = exports.createInvalidPathDiagnostic = exports.createForgeDiagnostic = void 0;
4
4
  function createForgeDiagnostic(input) {
5
5
  return {
6
6
  code: input.code,
@@ -20,6 +20,14 @@ function createInvalidPathDiagnostic(path, message = "Path is invalid.") {
20
20
  });
21
21
  }
22
22
  exports.createInvalidPathDiagnostic = createInvalidPathDiagnostic;
23
+ function createInvalidSnapshotDiagnostic(message = "Workspace snapshot payload is invalid.", cause) {
24
+ return createForgeDiagnostic({
25
+ code: "invalid_snapshot",
26
+ message,
27
+ cause,
28
+ });
29
+ }
30
+ exports.createInvalidSnapshotDiagnostic = createInvalidSnapshotDiagnostic;
23
31
  function createPathTraversalDiagnostic(path) {
24
32
  return createForgeDiagnostic({
25
33
  code: "path_traversal",
@@ -1,11 +1,13 @@
1
1
  import type { ForgeDeleteOptions, ForgeDirEntry, ForgeFileStat, ForgeFileWatchListener, ForgeMkdirOptions, ForgeOpenVirtualFileSystemOptions, ForgeRestoreOptions, ForgeSnapshot, ForgeSnapshotOptions, ForgeUnsubscribe, ForgeVirtualFileSystemOptions, ForgeWriteFileOptions } from "./types";
2
2
  export { DEFAULT_FORGE_VFS_LIMITS, createLimitExceededDiagnostic, resolveForgeVirtualFileSystemLimits, } from "./limits";
3
- export { createForgeDiagnostic, createInvalidPathDiagnostic, createMissingParentDiagnostic, createNotFoundDiagnostic, createNotImplementedDiagnostic, createPathTraversalDiagnostic, type ForgeDiagnosticInput, } from "./diagnostics";
3
+ export { createForgeDiagnostic, createInvalidSnapshotDiagnostic, createInvalidPathDiagnostic, createMissingParentDiagnostic, createNotFoundDiagnostic, createNotImplementedDiagnostic, createPathTraversalDiagnostic, type ForgeDiagnosticInput, } from "./diagnostics";
4
4
  export { normalizeForgePath, type ForgePathNormalizationResult, } from "./path";
5
5
  export { ForgeFileSystemError } from "./errors";
6
6
  export { InMemoryVirtualFileSystem } from "./memory";
7
7
  export { createIndexedDbForgeStorage, FORGE_INDEXED_DB_NAME, FORGE_INDEXED_DB_STORES, FORGE_INDEXED_DB_VERSION, IndexedDbForgeStorage, type IndexedDbForgeStorageOptions, } from "./storage";
8
- export type { ForgeBuildCacheRecord, ForgeDeleteOptions, ForgeDiagnostic, ForgeDiagnosticCode, ForgeDiagnosticSeverity, ForgeDirEntry, ForgeFileCreatedEvent, ForgeFileDeletedEvent, ForgeFileEvent, ForgeFileKind, ForgeFileRecord, ForgeFileRenamedEvent, ForgeFileSource, ForgeFileStat, ForgeFileUpdatedEvent, ForgeFileWatchListener, ForgeLimitDiagnostic, ForgeMkdirOptions, ForgeOpenVirtualFileSystemOptions, ForgePackageCacheRecord, ForgePersistedWorkspace, ForgeVirtualFileSystemLimits, ResolvedForgeVirtualFileSystemLimits, ForgeRestoreOptions, ForgeSnapshot, ForgeSnapshotOptions, ForgeUnsubscribe, ForgeVirtualFileSystemOptions, ForgeVirtualFileSystemStorage, ForgeWorkspace, ForgeWorkspaceMetadata, ForgeWriteFileOptions, } from "./types";
8
+ export { exportWorkspaceSnapshot, importWorkspaceSnapshot, } from "./snapshot-serialization";
9
+ export { FORGE_WORKSPACE_SNAPSHOT_EXPORT_SCHEMA_VERSION } from "./types";
10
+ export type { ForgeBuildCacheRecord, ForgeDeleteOptions, ForgeDiagnostic, ForgeDiagnosticCode, ForgeDiagnosticSeverity, ForgeDirEntry, ForgeFileCreatedEvent, ForgeFileDeletedEvent, ForgeFileEvent, ForgeFileKind, ForgeFileRecord, ForgeFileRenamedEvent, ForgeFileSource, ForgeFileStat, ForgeFileUpdatedEvent, ForgeFileWatchListener, ForgeLimitDiagnostic, ForgeMkdirOptions, ForgeOpenVirtualFileSystemOptions, ForgePackageCacheRecord, ForgePersistedWorkspace, ForgeSerializedFileRecord, ForgeSerializedWorkspaceSnapshot, ForgeSerializedWorkspaceSnapshotPayload, ForgeVirtualFileSystemLimits, ResolvedForgeVirtualFileSystemLimits, ForgeRestoreOptions, ForgeSnapshot, ForgeSnapshotOptions, ForgeUnsubscribe, ForgeVirtualFileSystemOptions, ForgeVirtualFileSystemStorage, ForgeWorkspace, ForgeWorkspaceMetadata, ForgeWorkspaceSnapshotExportOptions, ForgeWriteFileOptions, } from "./types";
9
11
  export declare const VIRTUAL_FILE_SYSTEM_CAPABILITY: "virtual-file-system";
10
12
  export interface ForgeVirtualFileSystem {
11
13
  readonly capability: typeof VIRTUAL_FILE_SYSTEM_CAPABILITY;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openVirtualFileSystem = exports.createVirtualFileSystem = exports.VIRTUAL_FILE_SYSTEM_CAPABILITY = exports.IndexedDbForgeStorage = exports.FORGE_INDEXED_DB_VERSION = exports.FORGE_INDEXED_DB_STORES = exports.FORGE_INDEXED_DB_NAME = exports.createIndexedDbForgeStorage = exports.InMemoryVirtualFileSystem = exports.ForgeFileSystemError = exports.normalizeForgePath = exports.createPathTraversalDiagnostic = exports.createNotImplementedDiagnostic = exports.createNotFoundDiagnostic = exports.createMissingParentDiagnostic = exports.createInvalidPathDiagnostic = exports.createForgeDiagnostic = exports.resolveForgeVirtualFileSystemLimits = exports.createLimitExceededDiagnostic = exports.DEFAULT_FORGE_VFS_LIMITS = void 0;
3
+ exports.openVirtualFileSystem = exports.createVirtualFileSystem = exports.VIRTUAL_FILE_SYSTEM_CAPABILITY = exports.FORGE_WORKSPACE_SNAPSHOT_EXPORT_SCHEMA_VERSION = exports.importWorkspaceSnapshot = exports.exportWorkspaceSnapshot = exports.IndexedDbForgeStorage = exports.FORGE_INDEXED_DB_VERSION = exports.FORGE_INDEXED_DB_STORES = exports.FORGE_INDEXED_DB_NAME = exports.createIndexedDbForgeStorage = exports.InMemoryVirtualFileSystem = exports.ForgeFileSystemError = exports.normalizeForgePath = exports.createPathTraversalDiagnostic = exports.createNotImplementedDiagnostic = exports.createNotFoundDiagnostic = exports.createMissingParentDiagnostic = exports.createInvalidPathDiagnostic = exports.createInvalidSnapshotDiagnostic = exports.createForgeDiagnostic = exports.resolveForgeVirtualFileSystemLimits = exports.createLimitExceededDiagnostic = exports.DEFAULT_FORGE_VFS_LIMITS = void 0;
4
4
  const memory_1 = require("./memory");
5
5
  const storage_1 = require("./storage");
6
6
  var limits_1 = require("./limits");
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "createLimitExceededDiagnostic", { enumerable: tr
9
9
  Object.defineProperty(exports, "resolveForgeVirtualFileSystemLimits", { enumerable: true, get: function () { return limits_1.resolveForgeVirtualFileSystemLimits; } });
10
10
  var diagnostics_1 = require("./diagnostics");
11
11
  Object.defineProperty(exports, "createForgeDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createForgeDiagnostic; } });
12
+ Object.defineProperty(exports, "createInvalidSnapshotDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createInvalidSnapshotDiagnostic; } });
12
13
  Object.defineProperty(exports, "createInvalidPathDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createInvalidPathDiagnostic; } });
13
14
  Object.defineProperty(exports, "createMissingParentDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createMissingParentDiagnostic; } });
14
15
  Object.defineProperty(exports, "createNotFoundDiagnostic", { enumerable: true, get: function () { return diagnostics_1.createNotFoundDiagnostic; } });
@@ -26,6 +27,11 @@ Object.defineProperty(exports, "FORGE_INDEXED_DB_NAME", { enumerable: true, get:
26
27
  Object.defineProperty(exports, "FORGE_INDEXED_DB_STORES", { enumerable: true, get: function () { return storage_2.FORGE_INDEXED_DB_STORES; } });
27
28
  Object.defineProperty(exports, "FORGE_INDEXED_DB_VERSION", { enumerable: true, get: function () { return storage_2.FORGE_INDEXED_DB_VERSION; } });
28
29
  Object.defineProperty(exports, "IndexedDbForgeStorage", { enumerable: true, get: function () { return storage_2.IndexedDbForgeStorage; } });
30
+ var snapshot_serialization_1 = require("./snapshot-serialization");
31
+ Object.defineProperty(exports, "exportWorkspaceSnapshot", { enumerable: true, get: function () { return snapshot_serialization_1.exportWorkspaceSnapshot; } });
32
+ Object.defineProperty(exports, "importWorkspaceSnapshot", { enumerable: true, get: function () { return snapshot_serialization_1.importWorkspaceSnapshot; } });
33
+ var types_1 = require("./types");
34
+ Object.defineProperty(exports, "FORGE_WORKSPACE_SNAPSHOT_EXPORT_SCHEMA_VERSION", { enumerable: true, get: function () { return types_1.FORGE_WORKSPACE_SNAPSHOT_EXPORT_SCHEMA_VERSION; } });
29
35
  exports.VIRTUAL_FILE_SYSTEM_CAPABILITY = "virtual-file-system";
30
36
  function createVirtualFileSystem(options) {
31
37
  return new memory_1.InMemoryVirtualFileSystem(options);
@@ -0,0 +1,3 @@
1
+ import type { ForgeSerializedWorkspaceSnapshotPayload, ForgeSnapshot, ForgeWorkspaceSnapshotExportOptions } from "./types";
2
+ export declare function exportWorkspaceSnapshot(snapshot: ForgeSnapshot, options?: ForgeWorkspaceSnapshotExportOptions): string;
3
+ export declare function importWorkspaceSnapshot(payload: string | ForgeSerializedWorkspaceSnapshotPayload): ForgeSnapshot;