@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.
Files changed (155) hide show
  1. package/README.md +143 -0
  2. package/dist/api/api/index.d.ts +7 -0
  3. package/dist/api/api/index.d.ts.map +1 -0
  4. package/dist/api/api/index.js +6 -0
  5. package/dist/api/api/middleware-registry.d.ts +33 -0
  6. package/dist/api/api/middleware-registry.d.ts.map +1 -0
  7. package/dist/api/api/middleware-registry.js +5 -0
  8. package/dist/api/api/reducer-registry.d.ts +41 -0
  9. package/dist/api/api/reducer-registry.d.ts.map +1 -0
  10. package/dist/api/api/reducer-registry.js +5 -0
  11. package/dist/api/api/store-manager.d.ts +55 -0
  12. package/dist/api/api/store-manager.d.ts.map +1 -0
  13. package/dist/api/api/store-manager.js +5 -0
  14. package/dist/api/autosave/autosave-action-factory.d.ts +69 -0
  15. package/dist/api/autosave/autosave-action-factory.d.ts.map +1 -0
  16. package/dist/api/autosave/autosave-action-factory.js +135 -0
  17. package/dist/api/autosave/autosave-action-types.d.ts +134 -0
  18. package/dist/api/autosave/autosave-action-types.d.ts.map +1 -0
  19. package/dist/api/autosave/autosave-action-types.js +44 -0
  20. package/dist/api/autosave/autosave-types.d.ts +86 -0
  21. package/dist/api/autosave/autosave-types.d.ts.map +1 -0
  22. package/dist/api/autosave/autosave-types.js +35 -0
  23. package/dist/api/autosave/index.d.ts +9 -0
  24. package/dist/api/autosave/index.d.ts.map +1 -0
  25. package/dist/api/autosave/index.js +8 -0
  26. package/dist/api/fs/contracts/filesystem-facade.contract.d.ts +57 -0
  27. package/dist/api/fs/contracts/filesystem-facade.contract.d.ts.map +1 -0
  28. package/dist/api/fs/contracts/filesystem-facade.contract.js +1 -0
  29. package/dist/api/fs/contracts/filesystem-manager.contract.d.ts +42 -0
  30. package/dist/api/fs/contracts/filesystem-manager.contract.d.ts.map +1 -0
  31. package/dist/api/fs/contracts/filesystem-manager.contract.js +1 -0
  32. package/dist/api/fs/index.d.ts +5 -0
  33. package/dist/api/fs/index.d.ts.map +1 -0
  34. package/dist/api/fs/index.js +4 -0
  35. package/dist/api/index.d.ts +10 -0
  36. package/dist/api/index.d.ts.map +1 -0
  37. package/dist/api/index.js +9 -0
  38. package/dist/api/tokens/index.d.ts +5 -0
  39. package/dist/api/tokens/index.d.ts.map +1 -0
  40. package/dist/api/tokens/index.js +4 -0
  41. package/dist/api/tokens/service-tokens.d.ts +10 -0
  42. package/dist/api/tokens/service-tokens.d.ts.map +1 -0
  43. package/dist/api/tokens/service-tokens.js +10 -0
  44. package/dist/api/types/extension-types.d.ts +32 -0
  45. package/dist/api/types/extension-types.d.ts.map +1 -0
  46. package/dist/api/types/extension-types.js +4 -0
  47. package/dist/api/types/index.d.ts +8 -0
  48. package/dist/api/types/index.d.ts.map +1 -0
  49. package/dist/api/types/index.js +7 -0
  50. package/dist/api/types/middleware-types.d.ts +31 -0
  51. package/dist/api/types/middleware-types.d.ts.map +1 -0
  52. package/dist/api/types/middleware-types.js +4 -0
  53. package/dist/api/types/reducer-types.d.ts +22 -0
  54. package/dist/api/types/reducer-types.d.ts.map +1 -0
  55. package/dist/api/types/reducer-types.js +4 -0
  56. package/dist/api/types/store-types.d.ts +49 -0
  57. package/dist/api/types/store-types.d.ts.map +1 -0
  58. package/dist/api/types/store-types.js +4 -0
  59. package/dist/impl/autosave/autosave-config-resolver.d.ts +45 -0
  60. package/dist/impl/autosave/autosave-config-resolver.d.ts.map +1 -0
  61. package/dist/impl/autosave/autosave-config-resolver.js +107 -0
  62. package/dist/impl/autosave/autosave-middleware.d.ts +37 -0
  63. package/dist/impl/autosave/autosave-middleware.d.ts.map +1 -0
  64. package/dist/impl/autosave/autosave-middleware.js +297 -0
  65. package/dist/impl/autosave/autosave-registry.d.ts +15 -0
  66. package/dist/impl/autosave/autosave-registry.d.ts.map +1 -0
  67. package/dist/impl/autosave/autosave-registry.js +38 -0
  68. package/dist/impl/autosave/autosave-sync-middleware.d.ts +24 -0
  69. package/dist/impl/autosave/autosave-sync-middleware.d.ts.map +1 -0
  70. package/dist/impl/autosave/autosave-sync-middleware.js +98 -0
  71. package/dist/impl/autosave/index.d.ts +8 -0
  72. package/dist/impl/autosave/index.d.ts.map +1 -0
  73. package/dist/impl/autosave/index.js +7 -0
  74. package/dist/impl/core/index.d.ts +4 -0
  75. package/dist/impl/core/index.d.ts.map +1 -0
  76. package/dist/impl/core/index.js +3 -0
  77. package/dist/impl/core/middleware-registry.d.ts +21 -0
  78. package/dist/impl/core/middleware-registry.d.ts.map +1 -0
  79. package/dist/impl/core/middleware-registry.js +60 -0
  80. package/dist/impl/core/reducer-registry.d.ts +18 -0
  81. package/dist/impl/core/reducer-registry.d.ts.map +1 -0
  82. package/dist/impl/core/reducer-registry.js +65 -0
  83. package/dist/impl/core/store-manager.d.ts +28 -0
  84. package/dist/impl/core/store-manager.d.ts.map +1 -0
  85. package/dist/impl/core/store-manager.js +129 -0
  86. package/dist/impl/extensions/store-extensions.d.ts +23 -0
  87. package/dist/impl/extensions/store-extensions.d.ts.map +1 -0
  88. package/dist/impl/extensions/store-extensions.js +66 -0
  89. package/dist/impl/fs/commands/fs-commands.d.ts +100 -0
  90. package/dist/impl/fs/commands/fs-commands.d.ts.map +1 -0
  91. package/dist/impl/fs/commands/fs-commands.js +338 -0
  92. package/dist/impl/fs/commands/structure-commands.d.ts +76 -0
  93. package/dist/impl/fs/commands/structure-commands.d.ts.map +1 -0
  94. package/dist/impl/fs/commands/structure-commands.js +21 -0
  95. package/dist/impl/fs/core/fs-adapter.d.ts +54 -0
  96. package/dist/impl/fs/core/fs-adapter.d.ts.map +1 -0
  97. package/dist/impl/fs/core/fs-adapter.js +204 -0
  98. package/dist/impl/fs/core/fs-facade.d.ts +37 -0
  99. package/dist/impl/fs/core/fs-facade.d.ts.map +1 -0
  100. package/dist/impl/fs/core/fs-facade.js +98 -0
  101. package/dist/impl/fs/index.d.ts +8 -0
  102. package/dist/impl/fs/index.d.ts.map +1 -0
  103. package/dist/impl/fs/index.js +11 -0
  104. package/dist/impl/fs/utils/data-updater.d.ts +36 -0
  105. package/dist/impl/fs/utils/data-updater.d.ts.map +1 -0
  106. package/dist/impl/fs/utils/data-updater.js +248 -0
  107. package/dist/impl/fs/utils/deep-equal.d.ts +5 -0
  108. package/dist/impl/fs/utils/deep-equal.d.ts.map +1 -0
  109. package/dist/impl/fs/utils/deep-equal.js +28 -0
  110. package/dist/impl/index.d.ts +12 -0
  111. package/dist/impl/index.d.ts.map +1 -0
  112. package/dist/impl/index.js +12 -0
  113. package/dist/impl/middleware/event-bridge-middleware.d.ts +7 -0
  114. package/dist/impl/middleware/event-bridge-middleware.d.ts.map +1 -0
  115. package/dist/impl/middleware/event-bridge-middleware.js +19 -0
  116. package/dist/impl/middleware/index.d.ts +6 -0
  117. package/dist/impl/middleware/index.d.ts.map +1 -0
  118. package/dist/impl/middleware/index.js +5 -0
  119. package/dist/impl/middleware/logger-middleware.d.ts +7 -0
  120. package/dist/impl/middleware/logger-middleware.d.ts.map +1 -0
  121. package/dist/impl/middleware/logger-middleware.js +18 -0
  122. package/dist/impl/plugin/index.d.ts +5 -0
  123. package/dist/impl/plugin/index.d.ts.map +1 -0
  124. package/dist/impl/plugin/index.js +4 -0
  125. package/dist/impl/plugin/store-plugin-factory.d.ts +15 -0
  126. package/dist/impl/plugin/store-plugin-factory.d.ts.map +1 -0
  127. package/dist/impl/plugin/store-plugin-factory.js +121 -0
  128. package/dist/index.d.ts +16 -0
  129. package/dist/index.d.ts.map +1 -0
  130. package/dist/index.js +15 -0
  131. package/dist/spi/autosave/i-autosave-provider.d.ts +98 -0
  132. package/dist/spi/autosave/i-autosave-provider.d.ts.map +1 -0
  133. package/dist/spi/autosave/i-autosave-provider.js +8 -0
  134. package/dist/spi/autosave/i-autosave-registry.d.ts +59 -0
  135. package/dist/spi/autosave/i-autosave-registry.d.ts.map +1 -0
  136. package/dist/spi/autosave/i-autosave-registry.js +8 -0
  137. package/dist/spi/autosave/index.d.ts +8 -0
  138. package/dist/spi/autosave/index.d.ts.map +1 -0
  139. package/dist/spi/autosave/index.js +7 -0
  140. package/dist/spi/index.d.ts +9 -0
  141. package/dist/spi/index.d.ts.map +1 -0
  142. package/dist/spi/index.js +9 -0
  143. package/dist/spi/middleware/index.d.ts +2 -0
  144. package/dist/spi/middleware/index.d.ts.map +1 -0
  145. package/dist/spi/middleware/index.js +1 -0
  146. package/dist/spi/middleware/middleware-provider.d.ts +9 -0
  147. package/dist/spi/middleware/middleware-provider.d.ts.map +1 -0
  148. package/dist/spi/middleware/middleware-provider.js +1 -0
  149. package/dist/spi/persistence/index.d.ts +2 -0
  150. package/dist/spi/persistence/index.d.ts.map +1 -0
  151. package/dist/spi/persistence/index.js +1 -0
  152. package/dist/spi/persistence/persistence-provider.d.ts +8 -0
  153. package/dist/spi/persistence/persistence-provider.d.ts.map +1 -0
  154. package/dist/spi/persistence/persistence-provider.js +1 -0
  155. package/package.json +68 -0
@@ -0,0 +1,204 @@
1
+ import { createSelector } from '@reduxjs/toolkit';
2
+ import { FileSystemCommandHandler, pathSteps } from '../commands/fs-commands';
3
+ import { fileSystemNodeInitialState } from '../../../api';
4
+ /**
5
+ * Factory function to create a FileSystemAdapter
6
+ */
7
+ export function createFileSystemAdapter(sliceName) {
8
+ return new FileSystemAdapter(sliceName);
9
+ }
10
+ /**
11
+ * FileSystemAdapter - Manages Redux state for virtual filesystem
12
+ */
13
+ export class FileSystemAdapter {
14
+ constructor(sliceName) {
15
+ Object.defineProperty(this, "sliceName", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: sliceName
20
+ });
21
+ Object.defineProperty(this, "actions", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: void 0
26
+ });
27
+ Object.defineProperty(this, "commandHandler", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: void 0
32
+ });
33
+ Object.defineProperty(this, "reducer", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: void 0
38
+ });
39
+ this.actions = new FileSystemNodeActions(sliceName);
40
+ this.commandHandler = new FileSystemCommandHandler();
41
+ this.reducer = (state = this.getInitialState(), action) => {
42
+ if (this.actions.isFileSystemNodeAction(action)) {
43
+ return this.commandHandler.execute(state, action.command);
44
+ }
45
+ return state;
46
+ };
47
+ }
48
+ getInitialState() {
49
+ return { root: { type: 'directory', name: '', children: {}, state: fileSystemNodeInitialState() } };
50
+ }
51
+ getActions() {
52
+ return this.actions;
53
+ }
54
+ getReducer(extraReducers) {
55
+ if (extraReducers === undefined) {
56
+ return this.reducer;
57
+ }
58
+ return (state, action) => this.reducer(extraReducers(state, action), action);
59
+ }
60
+ createSelector(fileSystemSelector, path) {
61
+ const rootSelector = createSelector(fileSystemSelector, fs => fs?.root);
62
+ const steps = pathSteps(path);
63
+ if (steps === undefined || steps.length === 0) {
64
+ return rootSelector;
65
+ }
66
+ return steps.reduce((acc, step) => {
67
+ return createSelector(acc, o => {
68
+ if (o === undefined || o.type === 'file') {
69
+ return o;
70
+ }
71
+ else {
72
+ return o.children[step];
73
+ }
74
+ });
75
+ }, rootSelector);
76
+ }
77
+ }
78
+ /**
79
+ * FileSystemNodeActions - Action creators for filesystem operations
80
+ */
81
+ export class FileSystemNodeActions {
82
+ constructor(sliceName) {
83
+ Object.defineProperty(this, "sliceName", {
84
+ enumerable: true,
85
+ configurable: true,
86
+ writable: true,
87
+ value: sliceName
88
+ });
89
+ Object.defineProperty(this, "_mkdirType", {
90
+ enumerable: true,
91
+ configurable: true,
92
+ writable: true,
93
+ value: void 0
94
+ });
95
+ Object.defineProperty(this, "_setFileType", {
96
+ enumerable: true,
97
+ configurable: true,
98
+ writable: true,
99
+ value: void 0
100
+ });
101
+ Object.defineProperty(this, "_removeType", {
102
+ enumerable: true,
103
+ configurable: true,
104
+ writable: true,
105
+ value: void 0
106
+ });
107
+ Object.defineProperty(this, "_updateFileContentType", {
108
+ enumerable: true,
109
+ configurable: true,
110
+ writable: true,
111
+ value: void 0
112
+ });
113
+ Object.defineProperty(this, "_setFileContentType", {
114
+ enumerable: true,
115
+ configurable: true,
116
+ writable: true,
117
+ value: void 0
118
+ });
119
+ Object.defineProperty(this, "_setExtensionStateType", {
120
+ enumerable: true,
121
+ configurable: true,
122
+ writable: true,
123
+ value: void 0
124
+ });
125
+ Object.defineProperty(this, "actionTypeSet", {
126
+ enumerable: true,
127
+ configurable: true,
128
+ writable: true,
129
+ value: void 0
130
+ });
131
+ this._mkdirType = `${this.sliceName}/createDirectoryNode`;
132
+ this._setFileType = `${this.sliceName}/createFileNode`;
133
+ this._removeType = `${this.sliceName}/removeNode`;
134
+ this._updateFileContentType = `${this.sliceName}/updateFileContent`;
135
+ this._setFileContentType = `${this.sliceName}/setFileContent`;
136
+ this._setExtensionStateType = `${this.sliceName}/setExtensionState`;
137
+ this.actionTypeSet = new Set([
138
+ this._mkdirType,
139
+ this._setFileType,
140
+ this._removeType,
141
+ this._updateFileContentType,
142
+ this._setFileContentType,
143
+ this._setExtensionStateType
144
+ ]);
145
+ }
146
+ get mkdirType() {
147
+ return this._mkdirType;
148
+ }
149
+ get setFileType() {
150
+ return this._setFileType;
151
+ }
152
+ get removeType() {
153
+ return this._removeType;
154
+ }
155
+ get updateFileContentType() {
156
+ return this._updateFileContentType;
157
+ }
158
+ get setFileContentType() {
159
+ return this._setFileContentType;
160
+ }
161
+ get setExtensionStateType() {
162
+ return this._setExtensionStateType;
163
+ }
164
+ isFileSystemNodeAction(action) {
165
+ return this.actionTypeSet.has(action.type);
166
+ }
167
+ mkdir(path, parents, extensionStates) {
168
+ return {
169
+ type: this.mkdirType,
170
+ command: { name: 'mkdir', path, parents, extensionStates }
171
+ };
172
+ }
173
+ setFile(path, content, schema, params = { override: true, contentIsPresent: true }) {
174
+ const { override, contentIsPresent, extensionStates } = params;
175
+ return {
176
+ type: this.setFileType,
177
+ command: { name: 'set-file', path, content, schema, override, contentIsPresent, extensionStates }
178
+ };
179
+ }
180
+ updateFileContent(path, contentCommand) {
181
+ return {
182
+ type: this.updateFileContentType,
183
+ command: { name: 'update-file-content', path, contentCommand }
184
+ };
185
+ }
186
+ setFileContent(path, content, fromRemote = false) {
187
+ return {
188
+ type: this.setFileContentType,
189
+ command: { name: 'set-file-content', path, content, fromRemote }
190
+ };
191
+ }
192
+ removeNode(path, recursive) {
193
+ return {
194
+ type: this.removeType,
195
+ command: { name: 'remove', path, recursive }
196
+ };
197
+ }
198
+ setExtensionState(path, key, state) {
199
+ return {
200
+ type: this.setExtensionStateType,
201
+ command: { name: 'set-extension-state', path, key, state }
202
+ };
203
+ }
204
+ }
@@ -0,0 +1,37 @@
1
+ import { FileNode, FileSystemNode, FileSystemState, Selector } from '../../../api';
2
+ import { FileSystemAdapter, FileSystemNodeActions } from './fs-adapter';
3
+ import { Path, Pathway, PathwayResolver, RelativePathwayResolver } from '@hamak/shared-utils';
4
+ /**
5
+ * Selector that returns a FileSystemNode generally the root of the Filesystem Overlay
6
+ */
7
+ export interface StoreFileSystemOverlaySelector<S> {
8
+ /**
9
+ * The key of the overlay
10
+ */
11
+ key: string;
12
+ selector: Selector<S, FileSystemNode | undefined>;
13
+ }
14
+ /**
15
+ * StoreFileSystemFacade - High-level API for filesystem operations
16
+ */
17
+ export declare class StoreFileSystemFacade<S = any> {
18
+ private fileSystemSelector;
19
+ private adapter;
20
+ constructor(fileSystemSelector: Selector<S, FileSystemState | undefined>, adapter: FileSystemAdapter);
21
+ getActions(): FileSystemNodeActions;
22
+ createSelector(path: string | string[]): Selector<S, FileSystemNode | undefined>;
23
+ createFileSelector(path: string | string[]): Selector<S, FileNode | undefined>;
24
+ selectFromRoot(state: S, path?: string[]): FileSystemNode | undefined;
25
+ selectFileFromRoot(state: S, path?: string[]): FileNode | undefined;
26
+ }
27
+ /**
28
+ * StoreFileSystemPathwayResolver - Pathway resolver for filesystem state
29
+ */
30
+ export declare class StoreFileSystemPathwayResolver<S = any> implements PathwayResolver<FileSystemNode> {
31
+ private state;
32
+ private fs;
33
+ constructor(state: S, fs: StoreFileSystemFacade<S>);
34
+ resolve(path: string | string[] | Pathway): FileSystemNode | undefined;
35
+ relativeTo(path: Path): RelativePathwayResolver<FileSystemNode>;
36
+ }
37
+ //# sourceMappingURL=fs-facade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-facade.d.ts","sourceRoot":"","sources":["../../../../src/impl/fs/core/fs-facade.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,cAAc,EACd,eAAe,EACf,QAAQ,EACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9F;;GAEG;AACH,MAAM,WAAW,8BAA8B,CAAC,CAAC;IAC/C;;OAEG;IACH,GAAG,EAAG,MAAM,CAAC;IACb,QAAQ,EAAG,QAAQ,CAAC,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,CAAA;CACnD;AAED;;GAEG;AACH,qBAAa,qBAAqB,CAAC,CAAC,GAAG,GAAG;IAEtC,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,OAAO;gBADP,kBAAkB,EAAE,QAAQ,CAAC,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,EAC5D,OAAO,EAAG,iBAAiB;IAGrC,UAAU,IAAK,qBAAqB;IAIpC,cAAc,CAAC,IAAI,EAAG,MAAM,GAAG,MAAM,EAAE,GAAI,QAAQ,CAAC,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAIlF,kBAAkB,CAAC,IAAI,EAAG,MAAM,GAAG,MAAM,EAAE,GAAI,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAWhF,cAAc,CAAC,KAAK,EAAG,CAAC,EAAE,IAAI,GAAG,MAAM,EAAO,GAAI,cAAc,GAAG,SAAS;IAmB5E,kBAAkB,CAAC,KAAK,EAAG,CAAC,EAAE,IAAI,GAAG,MAAM,EAAO,GAAI,QAAQ,GAAG,SAAS;CAY3E;AAGD;;GAEG;AACH,qBAAa,8BAA8B,CAAC,CAAC,GAAG,GAAG,CAAE,YAAW,eAAe,CAAC,cAAc,CAAC;IACjF,OAAO,CAAC,KAAK;IAAM,OAAO,CAAC,EAAE;gBAArB,KAAK,EAAG,CAAC,EAAU,EAAE,EAAG,qBAAqB,CAAC,CAAC,CAAC;IAGpE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,cAAc,GAAG,SAAS;IAKtE,UAAU,CAAC,IAAI,EAAG,IAAI,GAAI,uBAAuB,CAAC,cAAc,CAAC;CAGlE"}
@@ -0,0 +1,98 @@
1
+ import { createSelector } from '@reduxjs/toolkit';
2
+ import { Pathway, RelativePathwayResolver } from '@hamak/shared-utils';
3
+ /**
4
+ * StoreFileSystemFacade - High-level API for filesystem operations
5
+ */
6
+ export class StoreFileSystemFacade {
7
+ constructor(fileSystemSelector, adapter) {
8
+ Object.defineProperty(this, "fileSystemSelector", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: fileSystemSelector
13
+ });
14
+ Object.defineProperty(this, "adapter", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: adapter
19
+ });
20
+ }
21
+ getActions() {
22
+ return this.adapter.getActions();
23
+ }
24
+ createSelector(path) {
25
+ return this.adapter.createSelector(this.fileSystemSelector, path);
26
+ }
27
+ createFileSelector(path) {
28
+ const nodeSelector = this.adapter.createSelector(this.fileSystemSelector, path);
29
+ return createSelector([nodeSelector], (f) => {
30
+ if (f?.type === 'file') {
31
+ return f;
32
+ }
33
+ else {
34
+ return undefined;
35
+ }
36
+ });
37
+ }
38
+ selectFromRoot(state, path = []) {
39
+ const fileSystemState = this.fileSystemSelector(state);
40
+ if (fileSystemState === undefined || fileSystemState === null) {
41
+ return undefined;
42
+ }
43
+ else {
44
+ const root = fileSystemState.root;
45
+ return (path ?? []).reduce((acc, step) => {
46
+ if (acc === undefined || acc === null) {
47
+ return undefined;
48
+ }
49
+ else {
50
+ switch (acc.type) {
51
+ case "directory": return acc.children[step];
52
+ case "file": return undefined;
53
+ }
54
+ }
55
+ }, root);
56
+ }
57
+ }
58
+ selectFileFromRoot(state, path = []) {
59
+ const fsNode = this.selectFromRoot(state, path);
60
+ if (fsNode === undefined) {
61
+ return undefined;
62
+ }
63
+ else {
64
+ if (fsNode.type === "file") {
65
+ return fsNode;
66
+ }
67
+ else {
68
+ throw new Error(`Expecting file at path '${Pathway.of(path).toString()}' but got '${fsNode.type}'`);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * StoreFileSystemPathwayResolver - Pathway resolver for filesystem state
75
+ */
76
+ export class StoreFileSystemPathwayResolver {
77
+ constructor(state, fs) {
78
+ Object.defineProperty(this, "state", {
79
+ enumerable: true,
80
+ configurable: true,
81
+ writable: true,
82
+ value: state
83
+ });
84
+ Object.defineProperty(this, "fs", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: fs
89
+ });
90
+ }
91
+ resolve(path) {
92
+ const segments = Pathway.of(path).getSegments();
93
+ return this.fs.selectFromRoot(this.state, segments);
94
+ }
95
+ relativeTo(path) {
96
+ return new RelativePathwayResolver(this, path);
97
+ }
98
+ }
@@ -0,0 +1,8 @@
1
+ export * from './core/fs-adapter';
2
+ export * from './core/fs-facade';
3
+ export * from './commands/fs-commands';
4
+ export * from './commands/structure-commands';
5
+ export { pathSteps, parentPathSteps } from '@hamak/shared-utils';
6
+ export * from './utils/data-updater';
7
+ export * from './utils/deep-equal';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/fs/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGjE,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,11 @@
1
+ // Core filesystem functionality
2
+ export * from './core/fs-adapter';
3
+ export * from './core/fs-facade';
4
+ // Commands
5
+ export * from './commands/fs-commands';
6
+ export * from './commands/structure-commands';
7
+ // Re-export path utilities from shared-utils for backward compatibility
8
+ export { pathSteps, parentPathSteps } from '@hamak/shared-utils';
9
+ // Utilities
10
+ export * from './utils/data-updater';
11
+ export * from './utils/deep-equal';
@@ -0,0 +1,36 @@
1
+ import { Itinerary, StackElement } from '@hamak/shared-utils';
2
+ import { UnitaryStructureNodeCommand, BatchUpdateStructureNodeCommand } from '../commands/structure-commands';
3
+ /**
4
+ * DataUpdater class handles operations on data structures using itineraries
5
+ */
6
+ export declare class DataUpdater {
7
+ /**
8
+ * Delete a value at the specified itinerary
9
+ */
10
+ executeDelete(data: any, itinerary: Itinerary | undefined): void;
11
+ /**
12
+ * Set a value at the specified itinerary
13
+ */
14
+ executeSet(data: any, itinerary: Itinerary | undefined, value: any, prototypeToParent?: StackElement<any>): void;
15
+ /**
16
+ * Add a value at the specified itinerary
17
+ */
18
+ executeAdd(data: any, itinerary: Itinerary | undefined, value: any, prototypeToParent?: StackElement<any>): void;
19
+ /**
20
+ * Insert a value at the specified position
21
+ */
22
+ executeInsert(data: any, itinerary: Itinerary, value: any, prototypeToParent?: StackElement<any>): void;
23
+ /**
24
+ * Rebase a pending command's itinerary on top of an altering command.
25
+ * Returns null if the pending command should be dropped (e.g., targets a deleted element).
26
+ * Enhanced: Handles rebasing for nested itineraries, not just at the first divergence.
27
+ */
28
+ rebasePendingCommandOn(alteringCmd: UnitaryStructureNodeCommand, pendingCmd: UnitaryStructureNodeCommand): UnitaryStructureNodeCommand | null;
29
+ /**
30
+ * Executes a batch of commands, rebasing each on previous mutations.
31
+ * @param data The data object to mutate
32
+ * @param command The batch update command
33
+ */
34
+ executeBatch(data: any, command: BatchUpdateStructureNodeCommand): void;
35
+ }
36
+ //# sourceMappingURL=data-updater.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-updater.d.ts","sourceRoot":"","sources":["../../../../src/impl/fs/utils/data-updater.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,YAAY,EAKb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAChC,MAAM,gCAAgC,CAAC;AAyBxC;;GAEG;AACH,qBAAa,WAAW;IAEtB;;OAEG;IACI,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS;IA8BhE;;OAEG;IACI,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC;IA+BhH;;OAEG;IACI,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC;IAahH;;OAEG;IACI,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC;IAkBvG;;;;OAIG;IACI,sBAAsB,CAC3B,WAAW,EAAE,2BAA2B,EACxC,UAAU,EAAE,2BAA2B,GACtC,2BAA2B,GAAG,IAAI;IAqFrC;;;;OAIG;IACI,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,+BAA+B,GAAG,IAAI;CA4B/E"}
@@ -0,0 +1,248 @@
1
+ import { isDraft, original } from 'immer';
2
+ import { navigate, ensurePath, areSameItineraryStep } from '@hamak/shared-utils';
3
+ /**
4
+ * Type guard for checking if a value is an object
5
+ */
6
+ function isObject(o) {
7
+ if (o === undefined || o === null) {
8
+ return false;
9
+ }
10
+ return (isDraft(o) && typeof original(o) === 'object')
11
+ || typeof o === 'object';
12
+ }
13
+ /**
14
+ * Type guard for checking if a value is an array
15
+ */
16
+ function isArray(o) {
17
+ if (o === undefined || o === null) {
18
+ return false;
19
+ }
20
+ return (isDraft(o) && Array.isArray(original(o)))
21
+ || Array.isArray(o);
22
+ }
23
+ /**
24
+ * DataUpdater class handles operations on data structures using itineraries
25
+ */
26
+ export class DataUpdater {
27
+ /**
28
+ * Delete a value at the specified itinerary
29
+ */
30
+ executeDelete(data, itinerary) {
31
+ if (itinerary === undefined) {
32
+ return;
33
+ }
34
+ const { parent, value: step } = itinerary;
35
+ const parentNode = navigate(data, parent);
36
+ if (!(parentNode === undefined)) {
37
+ if (isArray(parentNode)) {
38
+ if (step.type === 'position') {
39
+ parentNode.splice(step.position, 1);
40
+ }
41
+ else {
42
+ // TODO log expected PositionStep
43
+ }
44
+ }
45
+ else if (isObject(parentNode)) {
46
+ if (step.type === 'property') {
47
+ if (parentNode !== null) {
48
+ delete parentNode[step.propertyName];
49
+ }
50
+ }
51
+ else {
52
+ // TODO log expected PropertyStep
53
+ }
54
+ }
55
+ else {
56
+ // TODO log expected object
57
+ }
58
+ }
59
+ else {
60
+ // TODO log Parent Node not found
61
+ }
62
+ }
63
+ /**
64
+ * Set a value at the specified itinerary
65
+ */
66
+ executeSet(data, itinerary, value, prototypeToParent) {
67
+ if (itinerary === undefined) {
68
+ return;
69
+ }
70
+ const { parent, value: step } = itinerary;
71
+ const parentNode = ensurePath(data, parent, prototypeToParent);
72
+ if (!(parentNode === undefined)) {
73
+ if (isArray(parentNode)) {
74
+ if (step.type === 'position') {
75
+ parentNode[step.position] = value;
76
+ }
77
+ else {
78
+ // TODO log expected PositionStep
79
+ }
80
+ }
81
+ else if (isObject(parentNode)) {
82
+ if (step.type === 'property') {
83
+ if (parentNode !== null) {
84
+ parentNode[step.propertyName] = value;
85
+ }
86
+ }
87
+ else {
88
+ // TODO log expected PropertyStep
89
+ }
90
+ }
91
+ else {
92
+ // TODO log expected object
93
+ }
94
+ }
95
+ else {
96
+ // TODO log Parent Node not found
97
+ }
98
+ }
99
+ /**
100
+ * Add a value at the specified itinerary
101
+ */
102
+ executeAdd(data, itinerary, value, prototypeToParent) {
103
+ const targetNode = ensurePath(data, itinerary, prototypeToParent);
104
+ if (!(targetNode === undefined)) {
105
+ if (isArray(targetNode)) {
106
+ targetNode.push(value);
107
+ }
108
+ else {
109
+ // TODO log expected object
110
+ }
111
+ }
112
+ else {
113
+ // TODO log Parent Node not found
114
+ }
115
+ }
116
+ /**
117
+ * Insert a value at the specified position
118
+ */
119
+ executeInsert(data, itinerary, value, prototypeToParent) {
120
+ const { value: step, parent } = itinerary;
121
+ if (step.type === 'position') {
122
+ const parentNode = ensurePath(data, parent, prototypeToParent);
123
+ if (parentNode !== undefined) {
124
+ if (isArray(parentNode)) {
125
+ parentNode.splice(step.position, 0, value);
126
+ }
127
+ else {
128
+ // TODO log expected object
129
+ }
130
+ }
131
+ else {
132
+ // TODO log Parent Node not found
133
+ }
134
+ }
135
+ else {
136
+ // TODO log expecting position step
137
+ }
138
+ }
139
+ /**
140
+ * Rebase a pending command's itinerary on top of an altering command.
141
+ * Returns null if the pending command should be dropped (e.g., targets a deleted element).
142
+ * Enhanced: Handles rebasing for nested itineraries, not just at the first divergence.
143
+ */
144
+ rebasePendingCommandOn(alteringCmd, pendingCmd) {
145
+ // Convert itinerary stack to array (root to leaf)
146
+ function itineraryToArray(it) {
147
+ const arr = [];
148
+ let current = it;
149
+ while (current) {
150
+ arr.push(current.value);
151
+ current = current.parent;
152
+ }
153
+ return arr.reverse();
154
+ }
155
+ // Convert array back to itinerary stack (leaf to root)
156
+ function arrayToItinerary(arr) {
157
+ // Assumes arr.length > 0
158
+ let it = { parent: undefined, value: arr[0] };
159
+ for (let i = 1; i < arr.length; i++) {
160
+ it = { parent: it, value: arr[i] };
161
+ }
162
+ return it;
163
+ }
164
+ // Rebase a single position step if needed
165
+ function rebasePositionStep(alteringStep, alteringCmd, pendingStep) {
166
+ if (pendingStep.type !== 'position' || alteringStep.type !== 'position')
167
+ return pendingStep;
168
+ let { position: pendingIdx } = pendingStep;
169
+ const { position: alteringIdx } = alteringStep;
170
+ if (alteringCmd.name === 'insert-at' && pendingIdx >= alteringIdx) {
171
+ pendingIdx += 1;
172
+ }
173
+ else if (alteringCmd.name === 'delete-at') {
174
+ if (pendingIdx > alteringIdx) {
175
+ pendingIdx -= 1;
176
+ }
177
+ // If pendingIdx === alteringIdx, leave unchanged (may be dropped by batch context)
178
+ }
179
+ return pendingIdx !== pendingStep.position
180
+ ? { ...pendingStep, position: pendingIdx }
181
+ : pendingStep;
182
+ }
183
+ const alteringArr = itineraryToArray(alteringCmd.itinerary);
184
+ const pendingArr = itineraryToArray(pendingCmd.itinerary);
185
+ // Find first index where steps differ
186
+ let commonLength = 0;
187
+ while (commonLength < alteringArr.length &&
188
+ commonLength < pendingArr.length &&
189
+ areSameItineraryStep(alteringArr[commonLength], pendingArr[commonLength])) {
190
+ commonLength++;
191
+ }
192
+ // Rebase all position steps after the divergence point
193
+ const rebasedArr = pendingArr.slice();
194
+ for (let i = 0; i < alteringArr.length; i++) {
195
+ if (alteringArr[i].type === 'position' &&
196
+ pendingArr.length > i &&
197
+ pendingArr[i].type === 'position') {
198
+ // Only rebase if the pending itinerary matches the altering up to this step
199
+ const isDescendant = alteringArr
200
+ .slice(0, i)
201
+ .every((step, j) => areSameItineraryStep(step, pendingArr[j]));
202
+ if (isDescendant) {
203
+ rebasedArr[i] = rebasePositionStep(alteringArr[i], alteringCmd, pendingArr[i]);
204
+ }
205
+ }
206
+ }
207
+ // If no itinerary, return as is
208
+ if (rebasedArr.length === 0)
209
+ return pendingCmd;
210
+ return {
211
+ ...pendingCmd,
212
+ itinerary: arrayToItinerary(rebasedArr),
213
+ };
214
+ }
215
+ /**
216
+ * Executes a batch of commands, rebasing each on previous mutations.
217
+ * @param data The data object to mutate
218
+ * @param command The batch update command
219
+ */
220
+ executeBatch(data, command) {
221
+ const { commands } = command;
222
+ const applied = [];
223
+ for (let i = 0; i < commands.length; i++) {
224
+ let rebased = commands[i];
225
+ for (let j = 0; j < applied.length && rebased != null; j++) {
226
+ rebased = this.rebasePendingCommandOn(applied[j], rebased);
227
+ }
228
+ if (rebased != null) {
229
+ switch (rebased.name) {
230
+ case 'add-at':
231
+ this.executeAdd(data, rebased.itinerary, rebased.value, rebased.prototypes);
232
+ break;
233
+ case 'insert-at':
234
+ this.executeInsert(data, rebased.itinerary, rebased.value, rebased.prototypes);
235
+ break;
236
+ case 'set-at':
237
+ this.executeSet(data, rebased.itinerary, rebased.value, rebased.prototypes);
238
+ break;
239
+ case 'delete-at':
240
+ this.executeDelete(data, rebased.itinerary);
241
+ break;
242
+ }
243
+ applied.push(rebased);
244
+ }
245
+ // If rebased is null, skip this command (it targets a deleted element)
246
+ }
247
+ }
248
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Deep equality check for objects and arrays
3
+ */
4
+ export declare function deepEqual(obj1: any, obj2: any): boolean;
5
+ //# sourceMappingURL=deep-equal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-equal.d.ts","sourceRoot":"","sources":["../../../../src/impl/fs/utils/deep-equal.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CA+BvD"}