@hamak/ui-store 0.5.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/README.md +143 -0
- package/dist/api/api/index.d.ts +7 -0
- package/dist/api/api/index.d.ts.map +1 -0
- package/dist/api/api/index.js +6 -0
- package/dist/api/api/middleware-registry.d.ts +33 -0
- package/dist/api/api/middleware-registry.d.ts.map +1 -0
- package/dist/api/api/middleware-registry.js +5 -0
- package/dist/api/api/reducer-registry.d.ts +41 -0
- package/dist/api/api/reducer-registry.d.ts.map +1 -0
- package/dist/api/api/reducer-registry.js +5 -0
- package/dist/api/api/store-manager.d.ts +55 -0
- package/dist/api/api/store-manager.d.ts.map +1 -0
- package/dist/api/api/store-manager.js +5 -0
- package/dist/api/autosave/autosave-action-factory.d.ts +69 -0
- package/dist/api/autosave/autosave-action-factory.d.ts.map +1 -0
- package/dist/api/autosave/autosave-action-factory.js +135 -0
- package/dist/api/autosave/autosave-action-types.d.ts +134 -0
- package/dist/api/autosave/autosave-action-types.d.ts.map +1 -0
- package/dist/api/autosave/autosave-action-types.js +44 -0
- package/dist/api/autosave/autosave-types.d.ts +86 -0
- package/dist/api/autosave/autosave-types.d.ts.map +1 -0
- package/dist/api/autosave/autosave-types.js +35 -0
- package/dist/api/autosave/index.d.ts +9 -0
- package/dist/api/autosave/index.d.ts.map +1 -0
- package/dist/api/autosave/index.js +8 -0
- package/dist/api/fs/contracts/filesystem-facade.contract.d.ts +57 -0
- package/dist/api/fs/contracts/filesystem-facade.contract.d.ts.map +1 -0
- package/dist/api/fs/contracts/filesystem-facade.contract.js +1 -0
- package/dist/api/fs/contracts/filesystem-manager.contract.d.ts +42 -0
- package/dist/api/fs/contracts/filesystem-manager.contract.d.ts.map +1 -0
- package/dist/api/fs/contracts/filesystem-manager.contract.js +1 -0
- package/dist/api/fs/index.d.ts +5 -0
- package/dist/api/fs/index.d.ts.map +1 -0
- package/dist/api/fs/index.js +4 -0
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +9 -0
- package/dist/api/tokens/index.d.ts +5 -0
- package/dist/api/tokens/index.d.ts.map +1 -0
- package/dist/api/tokens/index.js +4 -0
- package/dist/api/tokens/service-tokens.d.ts +10 -0
- package/dist/api/tokens/service-tokens.d.ts.map +1 -0
- package/dist/api/tokens/service-tokens.js +10 -0
- package/dist/api/types/extension-types.d.ts +32 -0
- package/dist/api/types/extension-types.d.ts.map +1 -0
- package/dist/api/types/extension-types.js +4 -0
- package/dist/api/types/index.d.ts +8 -0
- package/dist/api/types/index.d.ts.map +1 -0
- package/dist/api/types/index.js +7 -0
- package/dist/api/types/middleware-types.d.ts +31 -0
- package/dist/api/types/middleware-types.d.ts.map +1 -0
- package/dist/api/types/middleware-types.js +4 -0
- package/dist/api/types/reducer-types.d.ts +22 -0
- package/dist/api/types/reducer-types.d.ts.map +1 -0
- package/dist/api/types/reducer-types.js +4 -0
- package/dist/api/types/store-types.d.ts +49 -0
- package/dist/api/types/store-types.d.ts.map +1 -0
- package/dist/api/types/store-types.js +4 -0
- package/dist/impl/autosave/autosave-config-resolver.d.ts +45 -0
- package/dist/impl/autosave/autosave-config-resolver.d.ts.map +1 -0
- package/dist/impl/autosave/autosave-config-resolver.js +107 -0
- package/dist/impl/autosave/autosave-middleware.d.ts +37 -0
- package/dist/impl/autosave/autosave-middleware.d.ts.map +1 -0
- package/dist/impl/autosave/autosave-middleware.js +297 -0
- package/dist/impl/autosave/autosave-registry.d.ts +15 -0
- package/dist/impl/autosave/autosave-registry.d.ts.map +1 -0
- package/dist/impl/autosave/autosave-registry.js +38 -0
- package/dist/impl/autosave/autosave-sync-middleware.d.ts +24 -0
- package/dist/impl/autosave/autosave-sync-middleware.d.ts.map +1 -0
- package/dist/impl/autosave/autosave-sync-middleware.js +98 -0
- package/dist/impl/autosave/index.d.ts +8 -0
- package/dist/impl/autosave/index.d.ts.map +1 -0
- package/dist/impl/autosave/index.js +7 -0
- package/dist/impl/core/index.d.ts +4 -0
- package/dist/impl/core/index.d.ts.map +1 -0
- package/dist/impl/core/index.js +3 -0
- package/dist/impl/core/middleware-registry.d.ts +21 -0
- package/dist/impl/core/middleware-registry.d.ts.map +1 -0
- package/dist/impl/core/middleware-registry.js +60 -0
- package/dist/impl/core/reducer-registry.d.ts +18 -0
- package/dist/impl/core/reducer-registry.d.ts.map +1 -0
- package/dist/impl/core/reducer-registry.js +65 -0
- package/dist/impl/core/store-manager.d.ts +28 -0
- package/dist/impl/core/store-manager.d.ts.map +1 -0
- package/dist/impl/core/store-manager.js +129 -0
- package/dist/impl/extensions/store-extensions.d.ts +23 -0
- package/dist/impl/extensions/store-extensions.d.ts.map +1 -0
- package/dist/impl/extensions/store-extensions.js +66 -0
- package/dist/impl/fs/commands/fs-commands.d.ts +100 -0
- package/dist/impl/fs/commands/fs-commands.d.ts.map +1 -0
- package/dist/impl/fs/commands/fs-commands.js +338 -0
- package/dist/impl/fs/commands/structure-commands.d.ts +76 -0
- package/dist/impl/fs/commands/structure-commands.d.ts.map +1 -0
- package/dist/impl/fs/commands/structure-commands.js +21 -0
- package/dist/impl/fs/core/fs-adapter.d.ts +54 -0
- package/dist/impl/fs/core/fs-adapter.d.ts.map +1 -0
- package/dist/impl/fs/core/fs-adapter.js +204 -0
- package/dist/impl/fs/core/fs-facade.d.ts +37 -0
- package/dist/impl/fs/core/fs-facade.d.ts.map +1 -0
- package/dist/impl/fs/core/fs-facade.js +98 -0
- package/dist/impl/fs/index.d.ts +8 -0
- package/dist/impl/fs/index.d.ts.map +1 -0
- package/dist/impl/fs/index.js +11 -0
- package/dist/impl/fs/utils/data-updater.d.ts +36 -0
- package/dist/impl/fs/utils/data-updater.d.ts.map +1 -0
- package/dist/impl/fs/utils/data-updater.js +248 -0
- package/dist/impl/fs/utils/deep-equal.d.ts +5 -0
- package/dist/impl/fs/utils/deep-equal.d.ts.map +1 -0
- package/dist/impl/fs/utils/deep-equal.js +28 -0
- package/dist/impl/index.d.ts +12 -0
- package/dist/impl/index.d.ts.map +1 -0
- package/dist/impl/index.js +12 -0
- package/dist/impl/middleware/event-bridge-middleware.d.ts +7 -0
- package/dist/impl/middleware/event-bridge-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/event-bridge-middleware.js +19 -0
- package/dist/impl/middleware/index.d.ts +6 -0
- package/dist/impl/middleware/index.d.ts.map +1 -0
- package/dist/impl/middleware/index.js +5 -0
- package/dist/impl/middleware/logger-middleware.d.ts +7 -0
- package/dist/impl/middleware/logger-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/logger-middleware.js +18 -0
- package/dist/impl/plugin/index.d.ts +5 -0
- package/dist/impl/plugin/index.d.ts.map +1 -0
- package/dist/impl/plugin/index.js +4 -0
- package/dist/impl/plugin/store-plugin-factory.d.ts +15 -0
- package/dist/impl/plugin/store-plugin-factory.d.ts.map +1 -0
- package/dist/impl/plugin/store-plugin-factory.js +121 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/spi/autosave/i-autosave-provider.d.ts +98 -0
- package/dist/spi/autosave/i-autosave-provider.d.ts.map +1 -0
- package/dist/spi/autosave/i-autosave-provider.js +8 -0
- package/dist/spi/autosave/i-autosave-registry.d.ts +59 -0
- package/dist/spi/autosave/i-autosave-registry.d.ts.map +1 -0
- package/dist/spi/autosave/i-autosave-registry.js +8 -0
- package/dist/spi/autosave/index.d.ts +8 -0
- package/dist/spi/autosave/index.d.ts.map +1 -0
- package/dist/spi/autosave/index.js +7 -0
- package/dist/spi/index.d.ts +9 -0
- package/dist/spi/index.d.ts.map +1 -0
- package/dist/spi/index.js +9 -0
- package/dist/spi/middleware/index.d.ts +2 -0
- package/dist/spi/middleware/index.d.ts.map +1 -0
- package/dist/spi/middleware/index.js +1 -0
- package/dist/spi/middleware/middleware-provider.d.ts +9 -0
- package/dist/spi/middleware/middleware-provider.d.ts.map +1 -0
- package/dist/spi/middleware/middleware-provider.js +1 -0
- package/dist/spi/persistence/index.d.ts +2 -0
- package/dist/spi/persistence/index.d.ts.map +1 -0
- package/dist/spi/persistence/index.js +1 -0
- package/dist/spi/persistence/persistence-provider.d.ts +8 -0
- package/dist/spi/persistence/persistence-provider.d.ts.map +1 -0
- package/dist/spi/persistence/persistence-provider.js +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { fileSystemNodeInitialState } from '../../../api';
|
|
2
|
+
import { pathSteps } from '@hamak/shared-utils';
|
|
3
|
+
import { DataUpdater } from '../utils/data-updater';
|
|
4
|
+
import { produce, current, isDraft, original } from 'immer';
|
|
5
|
+
import { deepEqual } from '../utils/deep-equal';
|
|
6
|
+
// Re-export path utilities from shared-utils for internal use
|
|
7
|
+
export { pathSteps, parentPathSteps } from '@hamak/shared-utils';
|
|
8
|
+
/**
|
|
9
|
+
* Get filesystem node at path
|
|
10
|
+
*/
|
|
11
|
+
export function getFileSystemNode(fsNode, path) {
|
|
12
|
+
const steps = pathSteps(path);
|
|
13
|
+
let result = fsNode;
|
|
14
|
+
for (let i = 0; i < steps.length; i++) {
|
|
15
|
+
const step = steps[i];
|
|
16
|
+
if (result === undefined) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
else if (result.type === 'directory') {
|
|
20
|
+
result = result.children[step];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a directory node
|
|
30
|
+
*/
|
|
31
|
+
function createDirectoryNode(step, extensionStates) {
|
|
32
|
+
const state = fileSystemNodeInitialState();
|
|
33
|
+
if (extensionStates) {
|
|
34
|
+
state.extensionStates = { ...state.extensionStates, ...extensionStates };
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
type: 'directory',
|
|
38
|
+
state,
|
|
39
|
+
name: step,
|
|
40
|
+
children: {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a file node
|
|
45
|
+
*/
|
|
46
|
+
function createFileNode(name, content, schema, state, extensionStates) {
|
|
47
|
+
if (extensionStates) {
|
|
48
|
+
state.extensionStates = { ...state.extensionStates, ...extensionStates };
|
|
49
|
+
}
|
|
50
|
+
return { type: 'file', name, content, schema, state };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* FileSystem command handler - executes filesystem operations
|
|
54
|
+
*/
|
|
55
|
+
export class FileSystemCommandHandler {
|
|
56
|
+
constructor() {
|
|
57
|
+
Object.defineProperty(this, "contentCommandHandler", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: new FileContentCommandHandler()
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
execute(state, command) {
|
|
65
|
+
switch (command.name) {
|
|
66
|
+
case 'mkdir': return this.executeMkdir(state, command);
|
|
67
|
+
case 'set-file': return this.executeSetFile(state, command);
|
|
68
|
+
case 'update-file-content': return this.executeContentCommand(state, command);
|
|
69
|
+
case 'set-file-content': return this.executeSetContentCommand(state, command);
|
|
70
|
+
case 'remove': return this.executeRemove(state, command);
|
|
71
|
+
case 'set-extension-state': return this.executeSetExtensionState(state, command);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
executeMkdir(state, command) {
|
|
75
|
+
const { path, parents, extensionStates } = command;
|
|
76
|
+
const steps = pathSteps(path);
|
|
77
|
+
return produce(state, draft => {
|
|
78
|
+
const { root } = draft;
|
|
79
|
+
let dir = root;
|
|
80
|
+
for (let i = 0; i < steps.length; i++) {
|
|
81
|
+
const step = steps[i];
|
|
82
|
+
if (i + 1 === steps.length) {
|
|
83
|
+
// Last step is the element to create
|
|
84
|
+
if (dir.children[step] === undefined) {
|
|
85
|
+
dir.children[step] = createDirectoryNode(step, extensionStates);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
let child = dir.children[step];
|
|
90
|
+
if (child === undefined) {
|
|
91
|
+
if (parents === true) {
|
|
92
|
+
child = createDirectoryNode(step);
|
|
93
|
+
dir.children[step] = child;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (child.type === 'directory') {
|
|
100
|
+
dir = child;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
dir = child;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
executeRemove(state, command) {
|
|
111
|
+
const { path, recursive } = command;
|
|
112
|
+
const steps = pathSteps(path);
|
|
113
|
+
return produce(state, draft => {
|
|
114
|
+
const { root } = draft;
|
|
115
|
+
const parentDir = getFileSystemNode(root, steps.slice(0, steps.length - 1));
|
|
116
|
+
if (parentDir === undefined) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (parentDir.type === 'directory') {
|
|
120
|
+
const last = steps[steps.length - 1];
|
|
121
|
+
const child = parentDir.children[last];
|
|
122
|
+
if (child?.type === 'directory'
|
|
123
|
+
&& Object.keys(child.children).length > 0
|
|
124
|
+
&& !(recursive === true)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
delete parentDir.children[last];
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
executeSetFile(state, command) {
|
|
132
|
+
const { path, content, schema, override, contentIsPresent, extensionStates } = command;
|
|
133
|
+
const steps = pathSteps(path);
|
|
134
|
+
return produce(state, draft => {
|
|
135
|
+
const { root } = draft;
|
|
136
|
+
const parentPath = steps.slice(0, steps.length - 1);
|
|
137
|
+
const parentDir = getFileSystemNode(root, parentPath);
|
|
138
|
+
if (parentDir === undefined) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (parentDir.type === 'directory') {
|
|
142
|
+
const last = steps[steps.length - 1];
|
|
143
|
+
const child = parentDir.children[last];
|
|
144
|
+
if (child === undefined || override === true) {
|
|
145
|
+
parentDir.children[last] = createFileNode(last, content, schema, fileSystemNodeInitialState(contentIsPresent), extensionStates);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.warn(`File already exists at location`, path);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.warn(`Parent file is not directory`, parentPath);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
executeContentCommand(state, command) {
|
|
157
|
+
const { path, contentCommand } = command;
|
|
158
|
+
return produce(state, draft => {
|
|
159
|
+
const { root } = draft;
|
|
160
|
+
const fileNode = getFileSystemNode(root, path);
|
|
161
|
+
if (fileNode !== undefined) {
|
|
162
|
+
if (fileNode.type === 'file') {
|
|
163
|
+
this.contentCommandHandler.execute(fileNode, contentCommand);
|
|
164
|
+
this.contentMayChange(fileNode);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.warn(`Not a file at location`, path);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
console.warn(`No file found at location`, path);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
contentMayChange(fileNode) {
|
|
176
|
+
const changed = !deepEqual(this.original(fileNode.content), this.current(fileNode.content));
|
|
177
|
+
if (changed) {
|
|
178
|
+
if (fileNode.state === undefined) {
|
|
179
|
+
fileNode.state = fileSystemNodeInitialState();
|
|
180
|
+
}
|
|
181
|
+
fileNode.state.contentHistory.push(this.original(fileNode.content));
|
|
182
|
+
// check compared to memo modification status
|
|
183
|
+
if (fileNode.state.memo !== undefined) {
|
|
184
|
+
const memo = fileNode.state.memo;
|
|
185
|
+
memo.modified = !deepEqual(this.current(memo.originalContent), this.current(fileNode.content));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
executeSetContentCommand(state, command) {
|
|
190
|
+
const { path, content, fromRemote } = command;
|
|
191
|
+
return produce(state, draft => {
|
|
192
|
+
const { root } = draft;
|
|
193
|
+
const fileNode = getFileSystemNode(root, path);
|
|
194
|
+
if (fileNode !== undefined) {
|
|
195
|
+
if (fileNode.type === 'file') {
|
|
196
|
+
fileNode.content = content;
|
|
197
|
+
if (fileNode.state === undefined) {
|
|
198
|
+
fileNode.state = fileSystemNodeInitialState(true);
|
|
199
|
+
}
|
|
200
|
+
if (fromRemote) {
|
|
201
|
+
fileNode.state.contentLoaded = true;
|
|
202
|
+
if (fileNode.state.memo === undefined) {
|
|
203
|
+
fileNode.state.memo = { originalContent: { value: content }, modified: false };
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const memo = fileNode.state.memo;
|
|
207
|
+
memo.originalContent = { value: content };
|
|
208
|
+
memo.modified = false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
this.contentMayChange(fileNode);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.warn(`Not a file at location`, path);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
console.warn(`No file found at location`, path);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
executeSetExtensionState(state, command) {
|
|
225
|
+
const { path, key, state: extensionState } = command;
|
|
226
|
+
return produce(state, draft => {
|
|
227
|
+
const { root } = draft;
|
|
228
|
+
const node = getFileSystemNode(root, path);
|
|
229
|
+
if (node !== undefined) {
|
|
230
|
+
if (node.state === undefined) {
|
|
231
|
+
node.state = fileSystemNodeInitialState();
|
|
232
|
+
}
|
|
233
|
+
if (node.state.extensionStates === undefined) {
|
|
234
|
+
node.state.extensionStates = {};
|
|
235
|
+
}
|
|
236
|
+
// Merge the new state with existing state for this key
|
|
237
|
+
const existing = node.state.extensionStates[key];
|
|
238
|
+
node.state.extensionStates[key] = {
|
|
239
|
+
...existing,
|
|
240
|
+
...extensionState
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
console.warn(`No node found at location`, path);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
current(o) {
|
|
249
|
+
if (o === null || o === undefined) {
|
|
250
|
+
return o;
|
|
251
|
+
}
|
|
252
|
+
return isDraft(o) ? current(o) : o;
|
|
253
|
+
}
|
|
254
|
+
original(o) {
|
|
255
|
+
if (o === null || o === undefined) {
|
|
256
|
+
return o;
|
|
257
|
+
}
|
|
258
|
+
return isDraft(o) ? original(o) : o;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* File content command handler - handles structure commands on file content
|
|
263
|
+
*/
|
|
264
|
+
export class FileContentCommandHandler {
|
|
265
|
+
constructor() {
|
|
266
|
+
Object.defineProperty(this, "updater", {
|
|
267
|
+
enumerable: true,
|
|
268
|
+
configurable: true,
|
|
269
|
+
writable: true,
|
|
270
|
+
value: new DataUpdater()
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
execute(file, command) {
|
|
274
|
+
switch (command.name) {
|
|
275
|
+
case 'add-at':
|
|
276
|
+
{
|
|
277
|
+
this.executeAdd(file, command);
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
case 'insert-at':
|
|
281
|
+
{
|
|
282
|
+
this.executeInsert(file, command);
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
case 'set-at':
|
|
286
|
+
{
|
|
287
|
+
this.executeSet(file, command);
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
case 'delete-at':
|
|
291
|
+
{
|
|
292
|
+
this.executeDelete(file, command);
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
case 'batch-update':
|
|
296
|
+
{
|
|
297
|
+
this.executeBatch(file, command);
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
executeDelete(file, command) {
|
|
303
|
+
const { itinerary } = command;
|
|
304
|
+
if (itinerary === undefined) {
|
|
305
|
+
file.content = undefined;
|
|
306
|
+
}
|
|
307
|
+
const { content } = file;
|
|
308
|
+
this.updater.executeDelete(content, itinerary);
|
|
309
|
+
}
|
|
310
|
+
executeSet(file, command) {
|
|
311
|
+
const { itinerary, value } = command;
|
|
312
|
+
if (itinerary === undefined) {
|
|
313
|
+
file.content = value;
|
|
314
|
+
}
|
|
315
|
+
const { content } = file;
|
|
316
|
+
this.updater.executeSet(content, itinerary, value);
|
|
317
|
+
}
|
|
318
|
+
executeAdd(file, command) {
|
|
319
|
+
const { itinerary, value } = command;
|
|
320
|
+
const { content } = file;
|
|
321
|
+
this.updater.executeAdd(content, itinerary, value);
|
|
322
|
+
}
|
|
323
|
+
executeInsert(file, command) {
|
|
324
|
+
const { itinerary, value } = command;
|
|
325
|
+
if (itinerary === undefined) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const { content } = file;
|
|
329
|
+
this.updater.executeInsert(content, itinerary, value);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Executes a batch of commands, rebasing each on previous mutations.
|
|
333
|
+
*/
|
|
334
|
+
executeBatch(file, command) {
|
|
335
|
+
const { content } = file;
|
|
336
|
+
this.updater.executeBatch(content, command);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Itinerary, StackElement } from '@hamak/shared-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Base interface for structure node commands
|
|
4
|
+
*/
|
|
5
|
+
export interface StructureNodeCommandBase {
|
|
6
|
+
name: "add-at" | "set-at" | "delete-at" | 'insert-at' | "batch-update";
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Base interface for unitary (single operation) commands
|
|
10
|
+
*/
|
|
11
|
+
export interface UnitaryStructureNodeCommandBase extends StructureNodeCommandBase {
|
|
12
|
+
name: "add-at" | "set-at" | "delete-at" | 'insert-at';
|
|
13
|
+
itinerary: Itinerary;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Base interface for commands that insert/update values
|
|
17
|
+
*/
|
|
18
|
+
export interface StructureNodeUpsertCommandBase extends UnitaryStructureNodeCommandBase {
|
|
19
|
+
name: "add-at" | "set-at" | 'insert-at';
|
|
20
|
+
prototypes?: StackElement<any>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add a value at the specified itinerary
|
|
24
|
+
*/
|
|
25
|
+
export interface AddStructureNodeCommand extends StructureNodeUpsertCommandBase {
|
|
26
|
+
name: "add-at";
|
|
27
|
+
value: any;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Insert a value at the specified position
|
|
31
|
+
*/
|
|
32
|
+
export interface InsertStructureNodeCommand extends StructureNodeUpsertCommandBase {
|
|
33
|
+
name: "insert-at";
|
|
34
|
+
value: any;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set a value at the specified itinerary
|
|
38
|
+
*/
|
|
39
|
+
export interface SetStructureNodeCommand extends StructureNodeUpsertCommandBase {
|
|
40
|
+
name: "set-at";
|
|
41
|
+
value: any;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Delete a value at the specified itinerary
|
|
45
|
+
*/
|
|
46
|
+
export interface DeleteStructureNodeCommand extends UnitaryStructureNodeCommandBase {
|
|
47
|
+
name: "delete-at";
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Batch update multiple operations
|
|
51
|
+
*/
|
|
52
|
+
export interface BatchUpdateStructureNodeCommand extends StructureNodeCommandBase {
|
|
53
|
+
name: "batch-update";
|
|
54
|
+
autoRebase?: boolean;
|
|
55
|
+
commands: UnitaryStructureNodeCommand[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Union type for unitary structure node commands
|
|
59
|
+
*/
|
|
60
|
+
export type UnitaryStructureNodeCommand = AddStructureNodeCommand | InsertStructureNodeCommand | SetStructureNodeCommand | DeleteStructureNodeCommand;
|
|
61
|
+
/**
|
|
62
|
+
* Union type for all structure node commands
|
|
63
|
+
*/
|
|
64
|
+
export type StructureNodeCommand = UnitaryStructureNodeCommand | BatchUpdateStructureNodeCommand;
|
|
65
|
+
/**
|
|
66
|
+
* Helper class for creating structure node commands
|
|
67
|
+
*/
|
|
68
|
+
export declare class StructureNodeCommandHelper {
|
|
69
|
+
addNode(itinerary: Itinerary, value: any, prototypes?: StackElement<any>): AddStructureNodeCommand;
|
|
70
|
+
insertNode(itinerary: Itinerary, value: any, prototypes?: StackElement<any>): InsertStructureNodeCommand;
|
|
71
|
+
setNode(itinerary: Itinerary, value: any, prototypes?: StackElement<any>): SetStructureNodeCommand;
|
|
72
|
+
deleteNode(itinerary: Itinerary): DeleteStructureNodeCommand;
|
|
73
|
+
batchUpdate(commands: UnitaryStructureNodeCommand[], autoRebase?: boolean): BatchUpdateStructureNodeCommand;
|
|
74
|
+
}
|
|
75
|
+
export declare const structs: StructureNodeCommandHelper;
|
|
76
|
+
//# sourceMappingURL=structure-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure-commands.d.ts","sourceRoot":"","sources":["../../../../src/impl/fs/commands/structure-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,CAAA;CACvE;AAED;;GAEG;AACH,MAAM,WAAW,+BAAgC,SAAQ,wBAAwB;IAC/E,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAA;IACrD,SAAS,EAAE,SAAS,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,8BAA+B,SAAQ,+BAA+B;IACrF,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;IACvC,UAAU,CAAC,EAAG,YAAY,CAAC,GAAG,CAAC,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,8BAA8B;IAC7E,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,GAAG,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,8BAA8B;IAChF,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,GAAG,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,8BAA8B;IAC7E,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,GAAG,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,+BAA+B;IACjF,IAAI,EAAE,WAAW,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,+BAAgC,SAAQ,wBAAwB;IAC/E,IAAI,EAAE,cAAc,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,2BAA2B,EAAE,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,uBAAuB,GACvB,0BAA0B,GAC1B,uBAAuB,GACvB,0BAA0B,CAAA;AAE9B;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,2BAA2B,GAAG,+BAA+B,CAAA;AAEhG;;GAEG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,SAAS,EAAG,SAAS,EAAE,KAAK,EAAG,GAAG,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,GAAI,uBAAuB;IAIrG,UAAU,CAAC,SAAS,EAAG,SAAS,EAAE,KAAK,EAAG,GAAG,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,GAAI,0BAA0B;IAI3G,OAAO,CAAC,SAAS,EAAG,SAAS,EAAE,KAAK,EAAG,GAAG,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,GAAI,uBAAuB;IAIrG,UAAU,CAAC,SAAS,EAAG,SAAS,GAAI,0BAA0B;IAI9D,WAAW,CAAC,QAAQ,EAAG,2BAA2B,EAAE,EAAE,UAAU,UAAQ,GAAI,+BAA+B;CAG5G;AAED,eAAO,MAAM,OAAO,4BAAmC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper class for creating structure node commands
|
|
3
|
+
*/
|
|
4
|
+
export class StructureNodeCommandHelper {
|
|
5
|
+
addNode(itinerary, value, prototypes) {
|
|
6
|
+
return { name: 'add-at', itinerary, value, prototypes };
|
|
7
|
+
}
|
|
8
|
+
insertNode(itinerary, value, prototypes) {
|
|
9
|
+
return { name: 'insert-at', itinerary, value, prototypes };
|
|
10
|
+
}
|
|
11
|
+
setNode(itinerary, value, prototypes) {
|
|
12
|
+
return { name: 'set-at', itinerary, value, prototypes };
|
|
13
|
+
}
|
|
14
|
+
deleteNode(itinerary) {
|
|
15
|
+
return { name: 'delete-at', itinerary };
|
|
16
|
+
}
|
|
17
|
+
batchUpdate(commands, autoRebase = false) {
|
|
18
|
+
return { name: 'batch-update', commands, autoRebase };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const structs = new StructureNodeCommandHelper();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Action } from '@reduxjs/toolkit';
|
|
2
|
+
import { FileSystemCommandHandler } from '../commands/fs-commands';
|
|
3
|
+
import { FileSystemNode, FileSystemState, FileContentSchema, FileSystemNodeActionParams, FileSystemNodeAction, Selector } from '../../../api';
|
|
4
|
+
import { StructureNodeCommand } from '../commands/structure-commands';
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create a FileSystemAdapter
|
|
7
|
+
*/
|
|
8
|
+
export declare function createFileSystemAdapter(sliceName: string): FileSystemAdapter;
|
|
9
|
+
/**
|
|
10
|
+
* Filesystem reducer function type
|
|
11
|
+
*/
|
|
12
|
+
export type FileSystemNodeReducerFn = (state: FileSystemState, action: Action) => FileSystemState;
|
|
13
|
+
/**
|
|
14
|
+
* FileSystemAdapter - Manages Redux state for virtual filesystem
|
|
15
|
+
*/
|
|
16
|
+
export declare class FileSystemAdapter {
|
|
17
|
+
readonly sliceName: string;
|
|
18
|
+
readonly actions: FileSystemNodeActions;
|
|
19
|
+
readonly commandHandler: FileSystemCommandHandler;
|
|
20
|
+
readonly reducer: FileSystemNodeReducerFn;
|
|
21
|
+
constructor(sliceName: string);
|
|
22
|
+
getInitialState(): FileSystemState;
|
|
23
|
+
getActions(): FileSystemNodeActions;
|
|
24
|
+
getReducer(extraReducers?: FileSystemNodeReducerFn): FileSystemNodeReducerFn;
|
|
25
|
+
createSelector<S>(fileSystemSelector: Selector<S, FileSystemState | undefined>, path: string | string[]): Selector<S, FileSystemNode | undefined>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* FileSystemNodeActions - Action creators for filesystem operations
|
|
29
|
+
*/
|
|
30
|
+
export declare class FileSystemNodeActions {
|
|
31
|
+
sliceName: string;
|
|
32
|
+
private readonly _mkdirType;
|
|
33
|
+
private readonly _setFileType;
|
|
34
|
+
private readonly _removeType;
|
|
35
|
+
private readonly _updateFileContentType;
|
|
36
|
+
private readonly _setFileContentType;
|
|
37
|
+
private readonly _setExtensionStateType;
|
|
38
|
+
private actionTypeSet;
|
|
39
|
+
constructor(sliceName: string);
|
|
40
|
+
get mkdirType(): string;
|
|
41
|
+
get setFileType(): string;
|
|
42
|
+
get removeType(): string;
|
|
43
|
+
get updateFileContentType(): string;
|
|
44
|
+
get setFileContentType(): string;
|
|
45
|
+
get setExtensionStateType(): string;
|
|
46
|
+
isFileSystemNodeAction(action: Action): action is FileSystemNodeAction;
|
|
47
|
+
mkdir(path: string | string[], parents?: boolean, extensionStates?: Record<string, unknown>): FileSystemNodeAction;
|
|
48
|
+
setFile(path: string | string[], content: any, schema: FileContentSchema, params?: FileSystemNodeActionParams): FileSystemNodeAction;
|
|
49
|
+
updateFileContent(path: string | string[], contentCommand: StructureNodeCommand): FileSystemNodeAction;
|
|
50
|
+
setFileContent(path: string | string[], content: any, fromRemote?: boolean): FileSystemNodeAction;
|
|
51
|
+
removeNode(path: string | string[], recursive?: boolean): FileSystemNodeAction;
|
|
52
|
+
setExtensionState(path: string | string[], key: string, state: Record<string, unknown>): FileSystemNodeAction;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=fs-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-adapter.d.ts","sourceRoot":"","sources":["../../../../src/impl/fs/core/fs-adapter.ts"],"names":[],"mappings":"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"}
|