@ultrst-armada/kloks 1.7.0 → 1.7.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.
- package/.krusbl-release-attestation.json +3 -3
- package/package.json +1 -1
- package/packages/backend/dist/{BaseStorageAdapter-tosOoSUg.d.ts → BaseStorageAdapter-6x_BQiB3.d.ts} +6 -1
- package/packages/backend/dist/{chunk-BI5RDDB4.js → chunk-3IUA66RS.js} +9 -2
- package/packages/backend/dist/{chunk-6QTNNZSE.js → chunk-6W7OAGNV.js} +52 -70
- package/packages/backend/dist/{chunk-Y3X3H2XX.js → chunk-7ZT2ZPPH.js} +3 -3
- package/packages/backend/dist/{chunk-KSZ67VZJ.js → chunk-F6IDQLC2.js} +1 -1
- package/packages/backend/dist/chunk-JUPWFW7V.js +134 -0
- package/packages/backend/dist/{chunk-J2J24JVC.js → chunk-R45CEV46.js} +210 -153
- package/packages/backend/dist/{chunk-N4Z57FVR.js → chunk-XHADDA75.js} +9 -3
- package/packages/backend/dist/index.d.ts +3 -3
- package/packages/backend/dist/index.js +22 -13
- package/packages/backend/dist/krnl-services.js +4 -4
- package/packages/backend/dist/services/index.js +2 -2
- package/packages/backend/dist/srkl/index.d.ts +7 -1
- package/packages/backend/dist/srkl/index.js +2 -2
- package/packages/backend/dist/storage/index.d.ts +35 -3
- package/packages/backend/dist/storage/index.js +12 -3
- package/packages/backend/dist/workspace/index.d.ts +27 -33
- package/packages/backend/dist/workspace/index.js +1 -1
- package/packages/client/dist/index.d.ts +34 -1
- package/packages/client/dist/index.js +116 -0
- package/packages/backend/dist/chunk-LS3HWJBX.js +0 -0
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-RBF2OGMC.js";
|
|
15
15
|
import {
|
|
16
16
|
workspaceGraphService
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-F6IDQLC2.js";
|
|
18
|
+
import "../chunk-R45CEV46.js";
|
|
19
19
|
import "../chunk-6K75XXFD.js";
|
|
20
20
|
import "../chunk-VAFCR2MS.js";
|
|
21
21
|
import "../chunk-TY32TUNI.js";
|
|
@@ -80,7 +80,7 @@ interface AppServiceDeclaration {
|
|
|
80
80
|
}
|
|
81
81
|
interface AdaptedStorageConnection {
|
|
82
82
|
id: string;
|
|
83
|
-
provider: 'backblaze_b2' | 'aws_s3' | 'local_fs';
|
|
83
|
+
provider: 'backblaze_b2' | 'aws_s3' | 'google_drive' | 'local_fs';
|
|
84
84
|
label: string;
|
|
85
85
|
role?: 'primary' | 'redundant_clone';
|
|
86
86
|
enabled?: boolean;
|
|
@@ -95,6 +95,12 @@ interface AdaptedStorageConnection {
|
|
|
95
95
|
s3BucketName?: string;
|
|
96
96
|
s3Region?: string;
|
|
97
97
|
s3Endpoint?: string;
|
|
98
|
+
googleEmail?: string;
|
|
99
|
+
googleRootFolderId?: string;
|
|
100
|
+
googleRootFolderName?: string;
|
|
101
|
+
googleAccessToken?: string;
|
|
102
|
+
googleAccessTokenExpiresAt?: number;
|
|
103
|
+
googleRefreshToken?: string;
|
|
98
104
|
}
|
|
99
105
|
interface KeyMaterial {
|
|
100
106
|
secretHex: string;
|
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
srklService,
|
|
11
11
|
syncSrklAccounts,
|
|
12
12
|
useSrklServices
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-3IUA66RS.js";
|
|
14
14
|
import {
|
|
15
15
|
getPrimarySrklDeploymentUrl,
|
|
16
16
|
getSrklAccounts,
|
|
17
17
|
srklListBackblazeBuckets
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-XHADDA75.js";
|
|
19
19
|
import "../chunk-4QEMALXF.js";
|
|
20
20
|
import "../chunk-VAFCR2MS.js";
|
|
21
21
|
export {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseStorageAdapter, S as StorageConfig, F as FileInfo, D as DeleteFolderResult, R as RenameFolderResult, C as ConnectionTestResult } from '../BaseStorageAdapter-
|
|
2
|
-
export { a as StorageMode, b as StorageProviderType, U as UploadResult } from '../BaseStorageAdapter-
|
|
1
|
+
import { B as BaseStorageAdapter, S as StorageConfig, F as FileInfo, D as DeleteFolderResult, R as RenameFolderResult, C as ConnectionTestResult } from '../BaseStorageAdapter-6x_BQiB3.js';
|
|
2
|
+
export { a as StorageMode, b as StorageProviderType, U as UploadResult } from '../BaseStorageAdapter-6x_BQiB3.js';
|
|
3
3
|
import '@ultrst-armada/kloks/functions';
|
|
4
4
|
|
|
5
5
|
declare class LocalFSAdapter extends BaseStorageAdapter {
|
|
@@ -59,6 +59,22 @@ declare class BackblazeB2Adapter extends BaseStorageAdapter {
|
|
|
59
59
|
testConnection(): Promise<ConnectionTestResult>;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
declare class GoogleDriveAdapter extends BaseStorageAdapter {
|
|
63
|
+
private token;
|
|
64
|
+
private request;
|
|
65
|
+
private findChild;
|
|
66
|
+
private resolveParent;
|
|
67
|
+
private split;
|
|
68
|
+
read(pathStr: string): Promise<Uint8Array>;
|
|
69
|
+
write(pathStr: string, data: Uint8Array | string, contentType?: string): Promise<void>;
|
|
70
|
+
delete(pathStr: string): Promise<void>;
|
|
71
|
+
exists(pathStr: string): Promise<boolean>;
|
|
72
|
+
list(pathStr?: string): Promise<FileInfo[]>;
|
|
73
|
+
stat(pathStr: string): Promise<FileInfo>;
|
|
74
|
+
mkdir(pathStr: string): Promise<void>;
|
|
75
|
+
testConnection(): Promise<ConnectionTestResult>;
|
|
76
|
+
}
|
|
77
|
+
|
|
62
78
|
/**
|
|
63
79
|
* Backblaze B2 Endpoint & Credential Normalizer
|
|
64
80
|
*/
|
|
@@ -121,4 +137,20 @@ declare function b2ListFileNames(keyId: string, applicationKey: string, bucketNa
|
|
|
121
137
|
declare function b2UploadFile(keyId: string, applicationKey: string, bucketName: string, fileName: string, content: Uint8Array | string, contentType?: string): Promise<any>;
|
|
122
138
|
declare function b2DownloadFile(keyId: string, applicationKey: string, bucketName: string, fileName: string): Promise<Uint8Array | null>;
|
|
123
139
|
|
|
124
|
-
|
|
140
|
+
interface GoogleDriveOAuthConfig {
|
|
141
|
+
clientId: string;
|
|
142
|
+
clientSecret?: string;
|
|
143
|
+
redirectUri: string;
|
|
144
|
+
scopes?: string[];
|
|
145
|
+
}
|
|
146
|
+
interface GoogleDriveTokenSet {
|
|
147
|
+
accessToken: string;
|
|
148
|
+
refreshToken?: string;
|
|
149
|
+
expiresAt?: number;
|
|
150
|
+
tokenType?: string;
|
|
151
|
+
}
|
|
152
|
+
declare function createGoogleDriveAuthorizationUrl(config: GoogleDriveOAuthConfig, state: string, codeChallenge?: string): string;
|
|
153
|
+
declare function exchangeGoogleDriveCode(config: GoogleDriveOAuthConfig, code: string, codeVerifier?: string): Promise<GoogleDriveTokenSet>;
|
|
154
|
+
declare function refreshGoogleDriveAccessToken(clientId: string, refreshToken: string): Promise<GoogleDriveTokenSet>;
|
|
155
|
+
|
|
156
|
+
export { type B2AuthToken, BackblazeB2Adapter, BaseStorageAdapter, ConnectionTestResult, DeleteFolderResult, FileInfo, GoogleDriveAdapter, type GoogleDriveOAuthConfig, type GoogleDriveTokenSet, LocalFSAdapter, RenameFolderResult, S3Adapter, StorageAdapterFactory, StorageConfig, SupabaseStorageAdapter, authorizeB2, b2DownloadFile, b2ListBuckets, b2ListFileNames, b2UploadFile, createGoogleDriveAuthorizationUrl, ensureS3DirectoryMarker, exchangeGoogleDriveCode, isSecretMasked, normalizeBackblazeCredentials, permanentDeleteS3Folder, permanentDeleteS3Object, refreshGoogleDriveAccessToken, renameS3Folder, resolveBackblazeEndpoint };
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
S3Adapter
|
|
3
|
+
} from "../chunk-JUPWFW7V.js";
|
|
2
4
|
import {
|
|
3
5
|
BackblazeB2Adapter,
|
|
4
6
|
BaseStorageAdapter,
|
|
7
|
+
GoogleDriveAdapter,
|
|
5
8
|
LocalFSAdapter,
|
|
6
|
-
S3Adapter,
|
|
7
9
|
StorageAdapterFactory,
|
|
8
10
|
SupabaseStorageAdapter,
|
|
11
|
+
createGoogleDriveAuthorizationUrl,
|
|
9
12
|
ensureS3DirectoryMarker,
|
|
13
|
+
exchangeGoogleDriveCode,
|
|
10
14
|
isSecretMasked,
|
|
11
15
|
normalizeBackblazeCredentials,
|
|
12
16
|
permanentDeleteS3Folder,
|
|
13
17
|
permanentDeleteS3Object,
|
|
18
|
+
refreshGoogleDriveAccessToken,
|
|
14
19
|
renameS3Folder,
|
|
15
20
|
resolveBackblazeEndpoint
|
|
16
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-R45CEV46.js";
|
|
17
22
|
import {
|
|
18
23
|
authorizeB2,
|
|
19
24
|
b2DownloadFile,
|
|
@@ -24,6 +29,7 @@ import {
|
|
|
24
29
|
export {
|
|
25
30
|
BackblazeB2Adapter,
|
|
26
31
|
BaseStorageAdapter,
|
|
32
|
+
GoogleDriveAdapter,
|
|
27
33
|
LocalFSAdapter,
|
|
28
34
|
S3Adapter,
|
|
29
35
|
StorageAdapterFactory,
|
|
@@ -33,11 +39,14 @@ export {
|
|
|
33
39
|
b2ListBuckets,
|
|
34
40
|
b2ListFileNames,
|
|
35
41
|
b2UploadFile,
|
|
42
|
+
createGoogleDriveAuthorizationUrl,
|
|
36
43
|
ensureS3DirectoryMarker,
|
|
44
|
+
exchangeGoogleDriveCode,
|
|
37
45
|
isSecretMasked,
|
|
38
46
|
normalizeBackblazeCredentials,
|
|
39
47
|
permanentDeleteS3Folder,
|
|
40
48
|
permanentDeleteS3Object,
|
|
49
|
+
refreshGoogleDriveAccessToken,
|
|
41
50
|
renameS3Folder,
|
|
42
51
|
resolveBackblazeEndpoint
|
|
43
52
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BaseStorageAdapter, F as FileInfo } from '../BaseStorageAdapter-
|
|
1
|
+
import { B as BaseStorageAdapter, F as FileInfo } from '../BaseStorageAdapter-6x_BQiB3.js';
|
|
2
2
|
import { SkipoBase } from '@ultrst-armada/kloks/functions';
|
|
3
3
|
|
|
4
4
|
interface WorkspaceDescriptor {
|
|
@@ -139,7 +139,7 @@ interface WorkspaceMutationResult {
|
|
|
139
139
|
workspaces?: any[];
|
|
140
140
|
}
|
|
141
141
|
interface WorkspaceService {
|
|
142
|
-
readonly type: '
|
|
142
|
+
readonly type: 'working';
|
|
143
143
|
findWorkspace(workspaceId: string, env?: Record<string, unknown>): Promise<WorkspaceLookupResult>;
|
|
144
144
|
listWorkspaces(userId?: string, env?: Record<string, unknown>): Promise<WorkspaceListResult>;
|
|
145
145
|
createWorkspace(userId: string, data: any, env?: Record<string, unknown>): Promise<WorkspaceMutationResult>;
|
|
@@ -162,14 +162,18 @@ interface WorkspaceService {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
/**
|
|
165
|
-
* @file
|
|
166
|
-
* @description
|
|
167
|
-
*
|
|
168
|
-
*
|
|
165
|
+
* @file WorkingWorkspaceService.ts
|
|
166
|
+
* @description Local Working-Workspace implementation for Kloks.
|
|
167
|
+
* Operates on a local working directory for fast low-latency I/O and explicitly
|
|
168
|
+
* synchronizes with authoritative remote storage (Backblaze B2/S3/DB).
|
|
169
|
+
* Canonical choice for QWNSR. Conforms to Skipo Governance (< 200 lines).
|
|
169
170
|
*/
|
|
170
171
|
|
|
171
|
-
declare class
|
|
172
|
-
|
|
172
|
+
declare class WorkingWorkspaceService implements WorkspaceService {
|
|
173
|
+
private workingDirResolver?;
|
|
174
|
+
readonly type: "working";
|
|
175
|
+
constructor(workingDirResolver?: (workspaceId?: string) => string);
|
|
176
|
+
getWorkingDir(workspaceId?: string): string;
|
|
173
177
|
findWorkspace(workspaceId: string, env?: Record<string, unknown>): Promise<WorkspaceLookupResult>;
|
|
174
178
|
listWorkspaces(userId?: string, env?: Record<string, unknown>): Promise<WorkspaceListResult>;
|
|
175
179
|
createWorkspace(userId: string, data: any, env?: Record<string, unknown>): Promise<WorkspaceMutationResult>;
|
|
@@ -178,52 +182,42 @@ declare class RemoteWorkspaceService implements WorkspaceService {
|
|
|
178
182
|
success: boolean;
|
|
179
183
|
workspaces?: any[];
|
|
180
184
|
}>;
|
|
181
|
-
readFile(
|
|
182
|
-
writeFile(
|
|
185
|
+
readFile(_workspaceId: string, filePath: string): Promise<Uint8Array | string>;
|
|
186
|
+
writeFile(_workspaceId: string, filePath: string, content: Uint8Array | string): Promise<{
|
|
183
187
|
success: boolean;
|
|
184
188
|
path: string;
|
|
185
189
|
sizeBytes?: number;
|
|
186
190
|
}>;
|
|
187
|
-
deleteFile(
|
|
191
|
+
deleteFile(_workspaceId: string, filePath: string): Promise<{
|
|
188
192
|
success: boolean;
|
|
189
193
|
}>;
|
|
190
|
-
listFiles(
|
|
194
|
+
listFiles(_workspaceId: string, subfolder?: string): Promise<WorkspaceFileEntry[]>;
|
|
195
|
+
sync(workspaceId: string, _options?: any, _env?: Record<string, unknown>): Promise<WorkspaceSyncSummary>;
|
|
191
196
|
}
|
|
192
|
-
declare const
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* @file WorkingWorkspaceService.ts
|
|
196
|
-
* @description Local Working-Workspace implementation for Kloks.
|
|
197
|
-
* Operates on a local working directory for fast low-latency I/O and explicitly
|
|
198
|
-
* synchronizes with authoritative remote storage (Backblaze B2/S3/DB).
|
|
199
|
-
* Canonical choice for QWNSR. Conforms to Skipo Governance (< 200 lines).
|
|
200
|
-
*/
|
|
197
|
+
declare const workingWorkspaceService: WorkingWorkspaceService;
|
|
201
198
|
|
|
202
|
-
declare class
|
|
203
|
-
private workingDirResolver?;
|
|
199
|
+
declare class RemoteWorkspaceService implements WorkspaceService {
|
|
204
200
|
readonly type: "working";
|
|
205
|
-
|
|
206
|
-
getWorkingDir(): string;
|
|
207
|
-
findWorkspace(workspaceId: string, env?: Record<string, unknown>): Promise<WorkspaceLookupResult>;
|
|
201
|
+
findWorkspace(id: string, env?: Record<string, unknown>): Promise<WorkspaceLookupResult>;
|
|
208
202
|
listWorkspaces(userId?: string, env?: Record<string, unknown>): Promise<WorkspaceListResult>;
|
|
209
203
|
createWorkspace(userId: string, data: any, env?: Record<string, unknown>): Promise<WorkspaceMutationResult>;
|
|
210
204
|
updateWorkspace(userId: string, params: any, env?: Record<string, unknown>): Promise<WorkspaceMutationResult>;
|
|
211
|
-
deleteWorkspace(userId: string,
|
|
205
|
+
deleteWorkspace(userId: string, id: string, env?: Record<string, unknown>): Promise<{
|
|
212
206
|
success: boolean;
|
|
213
207
|
workspaces?: any[];
|
|
214
208
|
}>;
|
|
215
|
-
readFile(
|
|
216
|
-
writeFile(
|
|
209
|
+
readFile(id: string, path: string, env?: Record<string, unknown>): Promise<Uint8Array | string>;
|
|
210
|
+
writeFile(id: string, path: string, content: Uint8Array | string, env?: Record<string, unknown>): Promise<{
|
|
217
211
|
success: boolean;
|
|
218
212
|
path: string;
|
|
219
213
|
sizeBytes?: number;
|
|
220
214
|
}>;
|
|
221
|
-
deleteFile(
|
|
215
|
+
deleteFile(id: string, path: string, env?: Record<string, unknown>): Promise<{
|
|
222
216
|
success: boolean;
|
|
223
217
|
}>;
|
|
224
|
-
listFiles(
|
|
225
|
-
sync(
|
|
218
|
+
listFiles(id: string, subfolder?: string, env?: Record<string, unknown>): Promise<WorkspaceFileEntry[]>;
|
|
219
|
+
sync(id: string, options?: any, env?: Record<string, unknown>): Promise<WorkspaceSyncSummary>;
|
|
226
220
|
}
|
|
227
|
-
declare const
|
|
221
|
+
declare const remoteWorkspaceService: WorkingWorkspaceService;
|
|
228
222
|
|
|
229
223
|
export { type CloneReplicationResult, type ConflictPolicy, RemoteWorkspaceService, SyncEngine, type SyncState, WorkingWorkspaceService, WorkspaceCloneSyncEngine, type WorkspaceConfig, type WorkspaceDescriptor, WorkspaceFS, type WorkspaceFileEntry, type WorkspaceListResult, type WorkspaceLookupResult, type WorkspaceMutationResult, type WorkspaceSecondaryClone, type WorkspaceService, type WorkspaceSyncSummary, formatCanonicalWorkspaceFolderName, remoteWorkspaceService, sanitizeWorkspaceName, workingWorkspaceService };
|
|
@@ -151,4 +151,37 @@ declare class BrowserExecutionClient implements QueueGatewayContract {
|
|
|
151
151
|
}
|
|
152
152
|
declare function createBrowserExecutionClient(options?: QueueTransportOptions): BrowserExecutionClient;
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
interface WorkspaceAutosaveOptions {
|
|
155
|
+
intervalMs?: number;
|
|
156
|
+
enabled?: boolean;
|
|
157
|
+
save: () => Promise<void>;
|
|
158
|
+
}
|
|
159
|
+
declare class WorkspaceAutosaveController {
|
|
160
|
+
private readonly intervalMs;
|
|
161
|
+
private readonly save;
|
|
162
|
+
private timer?;
|
|
163
|
+
private saving;
|
|
164
|
+
private enabled;
|
|
165
|
+
constructor(options: WorkspaceAutosaveOptions);
|
|
166
|
+
start(): void;
|
|
167
|
+
stop(): void;
|
|
168
|
+
setEnabled(enabled: boolean): void;
|
|
169
|
+
saveNow(): Promise<void>;
|
|
170
|
+
private handleLifecycle;
|
|
171
|
+
private saveOnce;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
declare class OPFSWorkspaceStorage {
|
|
175
|
+
private readonly rootName;
|
|
176
|
+
constructor(rootName?: string);
|
|
177
|
+
private root;
|
|
178
|
+
private directory;
|
|
179
|
+
private parent;
|
|
180
|
+
read(workspaceId: string, filePath: string): Promise<Uint8Array>;
|
|
181
|
+
write(workspaceId: string, filePath: string, data: Uint8Array | string): Promise<void>;
|
|
182
|
+
delete(workspaceId: string, filePath: string): Promise<void>;
|
|
183
|
+
exists(workspaceId: string, filePath: string): Promise<boolean>;
|
|
184
|
+
list(workspaceId: string, folderPath?: string): Promise<string[]>;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export { type BackendCommand, BrowserExecutionClient, type CorrelationMetadata, type ExecutionJob, type JobPriority, type JobStatus, type NormalizedResult, OPFSWorkspaceStorage, type QueueGatewayContract, type QueueTransportOptions, type RetryPolicy, WorkspaceAutosaveController, type WorkspaceAutosaveOptions, type WorkspaceDescriptor, type WorkspaceFileEntry, type WorkspaceListResult, type WorkspaceLookupResult, type WorkspaceMutationResult, type WorkspaceServiceContract, type WorkspaceSyncSummary, createBrowserExecutionClient };
|
|
@@ -56,7 +56,123 @@ var BrowserExecutionClient = class {
|
|
|
56
56
|
function createBrowserExecutionClient(options) {
|
|
57
57
|
return new BrowserExecutionClient(options);
|
|
58
58
|
}
|
|
59
|
+
|
|
60
|
+
// src/WorkspaceAutosaveController.ts
|
|
61
|
+
var WorkspaceAutosaveController = class {
|
|
62
|
+
intervalMs;
|
|
63
|
+
save;
|
|
64
|
+
timer;
|
|
65
|
+
saving = false;
|
|
66
|
+
enabled;
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this.intervalMs = Math.max(options.intervalMs ?? 6e4, 5e3);
|
|
69
|
+
this.save = options.save;
|
|
70
|
+
this.enabled = options.enabled ?? true;
|
|
71
|
+
}
|
|
72
|
+
start() {
|
|
73
|
+
this.stop();
|
|
74
|
+
if (!this.enabled || typeof window === "undefined") return;
|
|
75
|
+
this.timer = setInterval(() => {
|
|
76
|
+
void this.saveOnce();
|
|
77
|
+
}, this.intervalMs);
|
|
78
|
+
window.addEventListener("visibilitychange", this.handleLifecycle);
|
|
79
|
+
window.addEventListener("pagehide", this.handleLifecycle);
|
|
80
|
+
window.addEventListener("blur", this.handleLifecycle);
|
|
81
|
+
}
|
|
82
|
+
stop() {
|
|
83
|
+
if (this.timer) clearInterval(this.timer);
|
|
84
|
+
this.timer = void 0;
|
|
85
|
+
if (typeof window !== "undefined") {
|
|
86
|
+
window.removeEventListener("visibilitychange", this.handleLifecycle);
|
|
87
|
+
window.removeEventListener("pagehide", this.handleLifecycle);
|
|
88
|
+
window.removeEventListener("blur", this.handleLifecycle);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
setEnabled(enabled) {
|
|
92
|
+
this.enabled = enabled;
|
|
93
|
+
if (enabled) this.start();
|
|
94
|
+
else this.stop();
|
|
95
|
+
}
|
|
96
|
+
async saveNow() {
|
|
97
|
+
if (!this.enabled) return;
|
|
98
|
+
await this.saveOnce();
|
|
99
|
+
}
|
|
100
|
+
handleLifecycle = () => {
|
|
101
|
+
if (typeof document !== "undefined" && document.visibilityState === "visible") return;
|
|
102
|
+
void this.saveOnce();
|
|
103
|
+
};
|
|
104
|
+
async saveOnce() {
|
|
105
|
+
if (!this.enabled || this.saving) return;
|
|
106
|
+
this.saving = true;
|
|
107
|
+
try {
|
|
108
|
+
await this.save();
|
|
109
|
+
} finally {
|
|
110
|
+
this.saving = false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// src/OPFSWorkspaceStorage.ts
|
|
116
|
+
var OPFSWorkspaceStorage = class {
|
|
117
|
+
rootName;
|
|
118
|
+
constructor(rootName = "skipo-workspaces") {
|
|
119
|
+
this.rootName = rootName;
|
|
120
|
+
}
|
|
121
|
+
async root() {
|
|
122
|
+
const storage = navigator.storage;
|
|
123
|
+
if (!storage?.getDirectory) throw new Error("OPFS is not available in this browser.");
|
|
124
|
+
const root = await storage.getDirectory();
|
|
125
|
+
return root.getDirectoryHandle(this.rootName, { create: true });
|
|
126
|
+
}
|
|
127
|
+
async directory(workspaceId, create = true) {
|
|
128
|
+
const root = await this.root();
|
|
129
|
+
return root.getDirectoryHandle(workspaceId, { create });
|
|
130
|
+
}
|
|
131
|
+
async parent(workspaceId, filePath, create = true) {
|
|
132
|
+
const parts = filePath.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
133
|
+
const name = parts.pop();
|
|
134
|
+
if (!name) throw new Error("Workspace file path is required.");
|
|
135
|
+
let dir = await this.directory(workspaceId, create);
|
|
136
|
+
for (const part of parts) dir = await dir.getDirectoryHandle(part, { create });
|
|
137
|
+
return { dir, name };
|
|
138
|
+
}
|
|
139
|
+
async read(workspaceId, filePath) {
|
|
140
|
+
const { dir, name } = await this.parent(workspaceId, filePath, false);
|
|
141
|
+
const handle = await dir.getFileHandle(name);
|
|
142
|
+
return new Uint8Array(await (await handle.getFile()).arrayBuffer());
|
|
143
|
+
}
|
|
144
|
+
async write(workspaceId, filePath, data) {
|
|
145
|
+
const { dir, name } = await this.parent(workspaceId, filePath, true);
|
|
146
|
+
const handle = await dir.getFileHandle(name, { create: true });
|
|
147
|
+
const writable = await handle.createWritable();
|
|
148
|
+
await writable.write(typeof data === "string" ? data : data);
|
|
149
|
+
await writable.close();
|
|
150
|
+
}
|
|
151
|
+
async delete(workspaceId, filePath) {
|
|
152
|
+
const { dir, name } = await this.parent(workspaceId, filePath, false);
|
|
153
|
+
await dir.removeEntry(name);
|
|
154
|
+
}
|
|
155
|
+
async exists(workspaceId, filePath) {
|
|
156
|
+
try {
|
|
157
|
+
await this.parent(workspaceId, filePath, false).then(async ({ dir, name }) => dir.getFileHandle(name));
|
|
158
|
+
return true;
|
|
159
|
+
} catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async list(workspaceId, folderPath = "") {
|
|
164
|
+
let dir = await this.directory(workspaceId, false);
|
|
165
|
+
for (const part of folderPath.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean)) {
|
|
166
|
+
dir = await dir.getDirectoryHandle(part);
|
|
167
|
+
}
|
|
168
|
+
const result = [];
|
|
169
|
+
for await (const [name, handle] of dir.entries()) result.push(handle.kind === "directory" ? `${name}/` : name);
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
59
173
|
export {
|
|
60
174
|
BrowserExecutionClient,
|
|
175
|
+
OPFSWorkspaceStorage,
|
|
176
|
+
WorkspaceAutosaveController,
|
|
61
177
|
createBrowserExecutionClient
|
|
62
178
|
};
|
|
File without changes
|