@hamak/ui-remote-fs-impl 0.4.3
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/actions/index.d.ts +5 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +4 -0
- package/dist/actions/remote-fs-actions.d.ts +189 -0
- package/dist/actions/remote-fs-actions.d.ts.map +1 -0
- package/dist/actions/remote-fs-actions.js +146 -0
- package/dist/es2015/actions/index.js +20 -0
- package/dist/es2015/actions/remote-fs-actions.js +147 -0
- package/dist/es2015/index.js +25 -0
- package/dist/es2015/middleware/index.js +21 -0
- package/dist/es2015/middleware/remote-fs-middleware.js +205 -0
- package/dist/es2015/middleware/store-sync-middleware.js +138 -0
- package/dist/es2015/plugin/index.js +20 -0
- package/dist/es2015/plugin/remote-fs-plugin-factory.js +169 -0
- package/dist/es2015/providers/http-workspace-client.js +199 -0
- package/dist/es2015/providers/index.js +20 -0
- package/dist/es2015/services/index.js +20 -0
- package/dist/es2015/services/remote-fs-service.js +16 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/middleware/index.d.ts +6 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/remote-fs-middleware.d.ts +50 -0
- package/dist/middleware/remote-fs-middleware.d.ts.map +1 -0
- package/dist/middleware/remote-fs-middleware.js +192 -0
- package/dist/middleware/store-sync-middleware.d.ts +35 -0
- package/dist/middleware/store-sync-middleware.d.ts.map +1 -0
- package/dist/middleware/store-sync-middleware.js +134 -0
- package/dist/plugin/index.d.ts +5 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +4 -0
- package/dist/plugin/remote-fs-plugin-factory.d.ts +84 -0
- package/dist/plugin/remote-fs-plugin-factory.d.ts.map +1 -0
- package/dist/plugin/remote-fs-plugin-factory.js +150 -0
- package/dist/providers/http-workspace-client.d.ts +99 -0
- package/dist/providers/http-workspace-client.d.ts.map +1 -0
- package/dist/providers/http-workspace-client.js +171 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +4 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +4 -0
- package/dist/services/remote-fs-service.d.ts +10 -0
- package/dist/services/remote-fs-service.d.ts.map +1 -0
- package/dist/services/remote-fs-service.js +12 -0
- package/package.json +56 -0
- package/project.json +24 -0
- package/src/actions/index.ts +5 -0
- package/src/actions/remote-fs-actions.ts +302 -0
- package/src/index.ts +10 -0
- package/src/middleware/index.ts +6 -0
- package/src/middleware/remote-fs-middleware.ts +244 -0
- package/src/middleware/store-sync-middleware.ts +175 -0
- package/src/plugin/index.ts +5 -0
- package/src/plugin/remote-fs-plugin-factory.ts +238 -0
- package/src/providers/http-workspace-client.ts +232 -0
- package/src/providers/index.ts +5 -0
- package/src/services/index.ts +5 -0
- package/src/services/remote-fs-service.ts +13 -0
- package/tsconfig.es2015.json +21 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP Workspace Client
|
|
4
|
+
*
|
|
5
|
+
* HTTP-based implementation of IWorkspaceClient using Axios.
|
|
6
|
+
* Migrated from amk/libs/server/ws/ws-client/src/lib/server-ws-ws-client.ts
|
|
7
|
+
*/
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.createHttpWorkspaceClient = exports.HttpWorkspaceClient = void 0;
|
|
22
|
+
const axios_1 = __importDefault(require("axios"));
|
|
23
|
+
/**
|
|
24
|
+
* HTTP-based implementation of IWorkspaceClient
|
|
25
|
+
*
|
|
26
|
+
* This implementation uses Axios to communicate with a REST API backend.
|
|
27
|
+
* Supports configurable base URL, timeout, and custom axios instances.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const client = new HttpWorkspaceClient({
|
|
32
|
+
* workspaceId: '0',
|
|
33
|
+
* baseUrl: 'http://localhost:3000/api'
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* const files = await client.listFiles(['folder', 'subfolder']);
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
class HttpWorkspaceClient {
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.workspaceId = config.workspaceId;
|
|
42
|
+
// Default base URL to current origin if not provided
|
|
43
|
+
this.baseUrl = config.baseUrl ||
|
|
44
|
+
(typeof globalThis !== 'undefined' && 'location' in globalThis
|
|
45
|
+
? `${globalThis.location.protocol}//${globalThis.location.host}/api`
|
|
46
|
+
: '/api');
|
|
47
|
+
// Use provided axios instance or create new one
|
|
48
|
+
this.axios = config.axiosInstance || axios_1.default.create({
|
|
49
|
+
baseURL: this.baseUrl,
|
|
50
|
+
timeout: config.timeout || 30000,
|
|
51
|
+
headers: {
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Format path segments to URL path string
|
|
58
|
+
*/
|
|
59
|
+
formatPath(path) {
|
|
60
|
+
return path.join('/');
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Handle axios errors and convert to ErrorObject
|
|
64
|
+
*/
|
|
65
|
+
handleError(error) {
|
|
66
|
+
var _a, _b, _c, _d;
|
|
67
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
68
|
+
const axiosError = error;
|
|
69
|
+
// Try to extract error from response
|
|
70
|
+
if ((_b = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) {
|
|
71
|
+
throw axiosError.response.data.error;
|
|
72
|
+
}
|
|
73
|
+
// Create error from axios error
|
|
74
|
+
const errorObj = {
|
|
75
|
+
code: axiosError.code || 'UNKNOWN',
|
|
76
|
+
message: axiosError.message || 'Unknown error occurred',
|
|
77
|
+
params: {
|
|
78
|
+
status: (_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.status,
|
|
79
|
+
statusText: (_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.statusText,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
throw errorObj;
|
|
83
|
+
}
|
|
84
|
+
// Handle non-axios errors
|
|
85
|
+
const errorObj = {
|
|
86
|
+
code: 'UNKNOWN',
|
|
87
|
+
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
88
|
+
};
|
|
89
|
+
throw errorObj;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Serialize content to string for transmission
|
|
93
|
+
*/
|
|
94
|
+
serializeContent(content) {
|
|
95
|
+
if (typeof content === 'string') {
|
|
96
|
+
return content;
|
|
97
|
+
}
|
|
98
|
+
return JSON.stringify(content);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* List files and directories at the specified path
|
|
102
|
+
*/
|
|
103
|
+
listFiles(path) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
try {
|
|
106
|
+
const formattedPath = this.formatPath(path);
|
|
107
|
+
const response = yield this.axios.get(`/workspaces/${this.workspaceId}/files/${formattedPath}`);
|
|
108
|
+
return response.data;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
this.handleError(error);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a directory at the specified path
|
|
117
|
+
*/
|
|
118
|
+
createDirectory(path) {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
try {
|
|
121
|
+
const formattedPath = this.formatPath(path);
|
|
122
|
+
const response = yield this.axios.post(`/workspaces/${this.workspaceId}/mkdir/${formattedPath}`);
|
|
123
|
+
return response.data;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
this.handleError(error);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Read a file's metadata and content
|
|
132
|
+
*/
|
|
133
|
+
readFile(path) {
|
|
134
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
try {
|
|
136
|
+
const formattedPath = this.formatPath(path);
|
|
137
|
+
const response = yield this.axios.get(`/workspaces/${this.workspaceId}/read/${formattedPath}`);
|
|
138
|
+
return response.data;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
this.handleError(error);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Write or update a file's content (uses PUT method)
|
|
147
|
+
*/
|
|
148
|
+
putFile(path, content) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
try {
|
|
151
|
+
const formattedPath = this.formatPath(path);
|
|
152
|
+
const serializedContent = this.serializeContent(content);
|
|
153
|
+
const response = yield this.axios.put(`/workspaces/${this.workspaceId}/put/${formattedPath}`, { content: serializedContent });
|
|
154
|
+
return response.data;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
this.handleError(error);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Delete a file or directory
|
|
163
|
+
*/
|
|
164
|
+
deleteFile(path) {
|
|
165
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
166
|
+
try {
|
|
167
|
+
const formattedPath = this.formatPath(path);
|
|
168
|
+
const response = yield this.axios.delete(`/workspaces/${this.workspaceId}/delete/${formattedPath}`);
|
|
169
|
+
return response.data;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
this.handleError(error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get the workspace ID
|
|
178
|
+
*/
|
|
179
|
+
getWorkspaceId() {
|
|
180
|
+
return this.workspaceId;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get the base URL
|
|
184
|
+
*/
|
|
185
|
+
getBaseUrl() {
|
|
186
|
+
return this.baseUrl;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.HttpWorkspaceClient = HttpWorkspaceClient;
|
|
190
|
+
/**
|
|
191
|
+
* Factory function to create HTTP workspace client with default configuration
|
|
192
|
+
*/
|
|
193
|
+
function createHttpWorkspaceClient(workspaceId, baseUrl) {
|
|
194
|
+
return new HttpWorkspaceClient({
|
|
195
|
+
workspaceId,
|
|
196
|
+
baseUrl,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
exports.createHttpWorkspaceClient = createHttpWorkspaceClient;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Remote FS Providers
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./http-workspace-client"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Remote FS Services
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./remote-fs-service"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Remote FS Service
|
|
4
|
+
*
|
|
5
|
+
* Service implementation for remote filesystem operations.
|
|
6
|
+
* Will be implemented in future phases.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RemoteFsService = void 0;
|
|
10
|
+
// Placeholder - will be implemented in future phases
|
|
11
|
+
class RemoteFsService {
|
|
12
|
+
constructor() {
|
|
13
|
+
throw new Error('Not yet implemented');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.RemoteFsService = RemoteFsService;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Remote FS Implementation
|
|
3
|
+
* HTTP-based remote filesystem implementation
|
|
4
|
+
*/
|
|
5
|
+
export * from './actions';
|
|
6
|
+
export * from './middleware';
|
|
7
|
+
export * from './providers';
|
|
8
|
+
export * from './plugin';
|
|
9
|
+
export * from './services';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote FS Middleware
|
|
3
|
+
*
|
|
4
|
+
* Redux middleware for handling remote filesystem operations via HTTP client.
|
|
5
|
+
* Migrated from amk/libs/ui/core/remote-fs/src/lib/remote-fs-middleware.ts
|
|
6
|
+
*/
|
|
7
|
+
import { AnyAction, Middleware } from '@reduxjs/toolkit';
|
|
8
|
+
import { IWorkspaceClient, IPathTranslator } from '@hamak/ui-remote-fs-spi';
|
|
9
|
+
import { ErrorObject } from '@hamak/ui-remote-fs-api';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for remote FS middleware
|
|
12
|
+
*/
|
|
13
|
+
export interface RemoteFsMiddlewareConfig {
|
|
14
|
+
/**
|
|
15
|
+
* Workspace client for remote operations
|
|
16
|
+
*/
|
|
17
|
+
client: IWorkspaceClient;
|
|
18
|
+
/**
|
|
19
|
+
* Path translator for mount point translation
|
|
20
|
+
*/
|
|
21
|
+
pathTranslator: IPathTranslator;
|
|
22
|
+
/**
|
|
23
|
+
* Optional error handler
|
|
24
|
+
*/
|
|
25
|
+
onError?: (error: ErrorObject, action: AnyAction) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Optional success handler
|
|
28
|
+
*/
|
|
29
|
+
onSuccess?: (result: any, action: AnyAction) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create remote filesystem middleware
|
|
33
|
+
*
|
|
34
|
+
* This middleware intercepts remote FS actions and executes them via the provided
|
|
35
|
+
* workspace client. It handles path translation from local mount point to remote paths.
|
|
36
|
+
*
|
|
37
|
+
* @param config Middleware configuration
|
|
38
|
+
* @returns Redux middleware
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const middleware = createRemoteFsMiddleware({
|
|
43
|
+
* client: new HttpWorkspaceClient({ workspaceId: '0' }),
|
|
44
|
+
* pathTranslator: new PathTranslator(Pathway.ofRoot().resolve('remote'))
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function createRemoteFsMiddleware<S = any>(config: RemoteFsMiddlewareConfig): Middleware<{}, S>;
|
|
49
|
+
export default createRemoteFsMiddleware;
|
|
50
|
+
//# sourceMappingURL=remote-fs-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-fs-middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/remote-fs-middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAuB,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAW3E;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;IAEzB;;OAEG;IACH,cAAc,EAAE,eAAe,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAE1D;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,GAAG,GAAG,EAC9C,MAAM,EAAE,wBAAwB,GAC/B,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAgLnB;AAED,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote FS Middleware
|
|
3
|
+
*
|
|
4
|
+
* Redux middleware for handling remote filesystem operations via HTTP client.
|
|
5
|
+
* Migrated from amk/libs/ui/core/remote-fs/src/lib/remote-fs-middleware.ts
|
|
6
|
+
*/
|
|
7
|
+
import { Pathway } from '@hamak/shared-utils';
|
|
8
|
+
import { RemoteFsActionTypes } from '@hamak/ui-remote-fs-api';
|
|
9
|
+
import { rfsActions, } from '../actions/remote-fs-actions';
|
|
10
|
+
/**
|
|
11
|
+
* Create remote filesystem middleware
|
|
12
|
+
*
|
|
13
|
+
* This middleware intercepts remote FS actions and executes them via the provided
|
|
14
|
+
* workspace client. It handles path translation from local mount point to remote paths.
|
|
15
|
+
*
|
|
16
|
+
* @param config Middleware configuration
|
|
17
|
+
* @returns Redux middleware
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const middleware = createRemoteFsMiddleware({
|
|
22
|
+
* client: new HttpWorkspaceClient({ workspaceId: '0' }),
|
|
23
|
+
* pathTranslator: new PathTranslator(Pathway.ofRoot().resolve('remote'))
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function createRemoteFsMiddleware(config) {
|
|
28
|
+
const { client, pathTranslator, onError, onSuccess } = config;
|
|
29
|
+
/**
|
|
30
|
+
* Translate local path to remote path
|
|
31
|
+
*/
|
|
32
|
+
const toRemotePath = (path) => {
|
|
33
|
+
const pathway = Array.isArray(path) ? Pathway.of(path) : Pathway.of([path]);
|
|
34
|
+
return pathTranslator.toRemotePath(pathway);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Handle errors and convert to ErrorObject
|
|
38
|
+
*/
|
|
39
|
+
const handleError = (error) => {
|
|
40
|
+
if (error && typeof error === 'object' && 'code' in error && 'message' in error) {
|
|
41
|
+
return error;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
code: error?.code || 'UNKNOWN',
|
|
45
|
+
message: error?.message || 'Unknown error',
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const remoteFsMiddleware = (store) => (next) => (action) => {
|
|
49
|
+
const result = next(action);
|
|
50
|
+
const dispatch = store.dispatch;
|
|
51
|
+
const anyAction = action;
|
|
52
|
+
switch (anyAction.type) {
|
|
53
|
+
case RemoteFsActionTypes.LS_REQUEST: {
|
|
54
|
+
const requestAction = anyAction;
|
|
55
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
56
|
+
if (remotePath === undefined) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
void (async () => {
|
|
60
|
+
try {
|
|
61
|
+
const data = await client.listFiles(remotePath.getSegments());
|
|
62
|
+
const completedAction = rfsActions.ofLsCompleted(data, requestAction);
|
|
63
|
+
dispatch(completedAction);
|
|
64
|
+
onSuccess?.(data, completedAction);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const errorObject = handleError(error);
|
|
68
|
+
const failedAction = rfsActions.ofLsFailed(errorObject, requestAction);
|
|
69
|
+
dispatch(failedAction);
|
|
70
|
+
onError?.(errorObject, failedAction);
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case RemoteFsActionTypes.MKDIR_REQUEST: {
|
|
76
|
+
const requestAction = anyAction;
|
|
77
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
78
|
+
if (remotePath === undefined) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
void (async () => {
|
|
82
|
+
try {
|
|
83
|
+
const data = await client.createDirectory(remotePath.getSegments());
|
|
84
|
+
const completedAction = rfsActions.ofMkdirCompleted(data, requestAction);
|
|
85
|
+
dispatch(completedAction);
|
|
86
|
+
onSuccess?.(data, completedAction);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const errorObject = handleError(error);
|
|
90
|
+
const failedAction = rfsActions.ofMkdirFailed(errorObject, requestAction);
|
|
91
|
+
dispatch(failedAction);
|
|
92
|
+
onError?.(errorObject, failedAction);
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case RemoteFsActionTypes.GET_REQUEST: {
|
|
98
|
+
const requestAction = anyAction;
|
|
99
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
100
|
+
if (remotePath === undefined) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
void (async () => {
|
|
104
|
+
try {
|
|
105
|
+
const data = await client.readFile(remotePath.getSegments());
|
|
106
|
+
const completedAction = rfsActions.ofGetCompleted(data, requestAction);
|
|
107
|
+
dispatch(completedAction);
|
|
108
|
+
onSuccess?.(data, completedAction);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const errorObject = handleError(error);
|
|
112
|
+
const failedAction = rfsActions.ofGetFailed(errorObject, requestAction);
|
|
113
|
+
dispatch(failedAction);
|
|
114
|
+
onError?.(errorObject, failedAction);
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case RemoteFsActionTypes.POST_REQUEST: {
|
|
120
|
+
const requestAction = anyAction;
|
|
121
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
122
|
+
if (remotePath === undefined) {
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
void (async () => {
|
|
126
|
+
try {
|
|
127
|
+
const data = await client.putFile(remotePath.getSegments(), requestAction.payload.content);
|
|
128
|
+
const completedAction = rfsActions.ofPostCompleted(data, requestAction);
|
|
129
|
+
dispatch(completedAction);
|
|
130
|
+
onSuccess?.(data, completedAction);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const errorObject = handleError(error);
|
|
134
|
+
const failedAction = rfsActions.ofPostFailed(errorObject, requestAction);
|
|
135
|
+
dispatch(failedAction);
|
|
136
|
+
onError?.(errorObject, failedAction);
|
|
137
|
+
}
|
|
138
|
+
})();
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case RemoteFsActionTypes.PUT_REQUEST: {
|
|
142
|
+
const requestAction = anyAction;
|
|
143
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
144
|
+
if (remotePath === undefined) {
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
void (async () => {
|
|
148
|
+
try {
|
|
149
|
+
const data = await client.putFile(remotePath.getSegments(), requestAction.payload.content);
|
|
150
|
+
const completedAction = rfsActions.ofPutCompleted(data, requestAction);
|
|
151
|
+
dispatch(completedAction);
|
|
152
|
+
onSuccess?.(data, completedAction);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
const errorObject = handleError(error);
|
|
156
|
+
const failedAction = rfsActions.ofPutFailed(errorObject, requestAction);
|
|
157
|
+
dispatch(failedAction);
|
|
158
|
+
onError?.(errorObject, failedAction);
|
|
159
|
+
}
|
|
160
|
+
})();
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case RemoteFsActionTypes.DELETE_REQUEST: {
|
|
164
|
+
const requestAction = anyAction;
|
|
165
|
+
const remotePath = toRemotePath(requestAction.payload.path);
|
|
166
|
+
if (remotePath === undefined) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
void (async () => {
|
|
170
|
+
try {
|
|
171
|
+
const data = await client.deleteFile(remotePath.getSegments());
|
|
172
|
+
const completedAction = rfsActions.ofDeleteCompleted(data, requestAction);
|
|
173
|
+
dispatch(completedAction);
|
|
174
|
+
onSuccess?.(data, completedAction);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
const errorObject = handleError(error);
|
|
178
|
+
const failedAction = rfsActions.ofDeleteFailed(errorObject, requestAction);
|
|
179
|
+
dispatch(failedAction);
|
|
180
|
+
onError?.(errorObject, failedAction);
|
|
181
|
+
}
|
|
182
|
+
})();
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
default:
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
};
|
|
190
|
+
return remoteFsMiddleware;
|
|
191
|
+
}
|
|
192
|
+
export default createRemoteFsMiddleware;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store Sync Middleware
|
|
3
|
+
*
|
|
4
|
+
* Redux middleware for synchronizing remote filesystem operations to Redux Store FS.
|
|
5
|
+
* This middleware listens to remote FS completion actions and updates the Store FS accordingly.
|
|
6
|
+
* Migrated from amk/libs/ui/core/remote-fs/src/lib/store-fs-adapter-middleware.ts
|
|
7
|
+
*/
|
|
8
|
+
import { Middleware } from '@reduxjs/toolkit';
|
|
9
|
+
import { StoreSyncMiddlewareConfig } from '@hamak/ui-remote-fs-spi';
|
|
10
|
+
/**
|
|
11
|
+
* Create store sync middleware
|
|
12
|
+
*
|
|
13
|
+
* This middleware intercepts remote FS completion actions and synchronizes them
|
|
14
|
+
* to the Redux Store FileSystem. It handles:
|
|
15
|
+
* - LS_COMPLETED: Creates directories and file entries in Store FS
|
|
16
|
+
* - MKDIR_COMPLETED: Creates directory in Store FS
|
|
17
|
+
* - GET_COMPLETED: Creates/updates file content in Store FS
|
|
18
|
+
* - POST/PUT_COMPLETED: Reloads file content from remote
|
|
19
|
+
* - DELETE_COMPLETED: Removes node from Store FS
|
|
20
|
+
*
|
|
21
|
+
* @param config Middleware configuration
|
|
22
|
+
* @returns Redux middleware
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const middleware = createStoreSyncMiddleware({
|
|
27
|
+
* fileSystemAdapter: storeFs,
|
|
28
|
+
* pathTranslator: new PathTranslator(Pathway.ofRoot().resolve('remote')),
|
|
29
|
+
* autoReload: true
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createStoreSyncMiddleware<S = any>(config: StoreSyncMiddlewareConfig): Middleware<{}, S>;
|
|
34
|
+
export default createStoreSyncMiddleware;
|
|
35
|
+
//# sourceMappingURL=store-sync-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-sync-middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/store-sync-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAa,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAWpE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,GAAG,GAAG,EAC/C,MAAM,EAAE,yBAAyB,GAChC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CA6HnB;AAED,eAAe,yBAAyB,CAAC"}
|