@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 @@
|
|
|
1
|
+
{"version":3,"file":"autosave-config-resolver.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/autosave-config-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAG5B,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,cAAc,GAAG,SAAS,GAC/B,sBAAsB,GAAG,SAAS,CAOpC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,GAAG,SAAS,GAC/B,cAAc,GAAG,SAAS,CAE5B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,aAAa,GAAE,cAAwC,GACtD,cAAc,CAkChB;AAoBD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,aAAa,CAAC,EAAE,cAAc,GAC7B,OAAO,CAGT;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EAAE,GACb,cAAc,GAAG,SAAS,CAW5B;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/C"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Configuration Resolver
|
|
3
|
+
*
|
|
4
|
+
* Resolves autosave configuration with hierarchical inheritance.
|
|
5
|
+
* Configuration priority (highest to lowest):
|
|
6
|
+
* 1. File node extension state config
|
|
7
|
+
* 2. Parent folder config (recursive, respects inherit flag)
|
|
8
|
+
* 3. Default config
|
|
9
|
+
*/
|
|
10
|
+
import { AUTOSAVE_EXTENSION_KEY, DEFAULT_AUTOSAVE_CONFIG, } from '../../api';
|
|
11
|
+
/**
|
|
12
|
+
* Get autosave extension state from a node
|
|
13
|
+
*/
|
|
14
|
+
export function getAutosaveExtensionState(node) {
|
|
15
|
+
if (!node?.state?.extensionStates) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return node.state.extensionStates[AUTOSAVE_EXTENSION_KEY];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get autosave config from a node's extension state
|
|
22
|
+
*/
|
|
23
|
+
export function getAutosaveConfig(node) {
|
|
24
|
+
return getAutosaveExtensionState(node)?.config;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve autosave configuration for a path with inheritance
|
|
28
|
+
*
|
|
29
|
+
* @param root - Root directory node
|
|
30
|
+
* @param path - Path segments to the target node
|
|
31
|
+
* @param defaultConfig - Default configuration to use if none found
|
|
32
|
+
* @returns Resolved configuration
|
|
33
|
+
*/
|
|
34
|
+
export function resolveAutosaveConfig(root, path, defaultConfig = DEFAULT_AUTOSAVE_CONFIG) {
|
|
35
|
+
const configs = [];
|
|
36
|
+
// Walk down the path, collecting configs
|
|
37
|
+
let currentNode = root;
|
|
38
|
+
for (let i = 0; i <= path.length; i++) {
|
|
39
|
+
if (!currentNode)
|
|
40
|
+
break;
|
|
41
|
+
const config = getAutosaveConfig(currentNode);
|
|
42
|
+
if (config) {
|
|
43
|
+
configs.push(config);
|
|
44
|
+
// If inherit is false, stop here
|
|
45
|
+
if (config.inherit === false) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Move to next segment
|
|
50
|
+
if (i < path.length && currentNode.type === 'directory') {
|
|
51
|
+
currentNode = currentNode.children[path[i]];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Merge configs from root to target (later configs override earlier)
|
|
55
|
+
// Start with default, then apply each config in order
|
|
56
|
+
let result = { ...defaultConfig };
|
|
57
|
+
for (const config of configs) {
|
|
58
|
+
result = mergeConfigs(result, config);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Merge two autosave configs (source overrides target for defined values)
|
|
64
|
+
*/
|
|
65
|
+
function mergeConfigs(target, source) {
|
|
66
|
+
return {
|
|
67
|
+
enabled: source.enabled,
|
|
68
|
+
debounceMs: source.debounceMs ?? target.debounceMs,
|
|
69
|
+
maxWaitMs: source.maxWaitMs ?? target.maxWaitMs,
|
|
70
|
+
saveOnBlur: source.saveOnBlur ?? target.saveOnBlur,
|
|
71
|
+
retryOnFailure: source.retryOnFailure ?? target.retryOnFailure,
|
|
72
|
+
maxRetries: source.maxRetries ?? target.maxRetries,
|
|
73
|
+
inherit: source.inherit ?? target.inherit,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Check if autosave is effectively enabled for a path
|
|
78
|
+
*/
|
|
79
|
+
export function isAutosaveEnabled(root, path, defaultConfig) {
|
|
80
|
+
const config = resolveAutosaveConfig(root, path, defaultConfig);
|
|
81
|
+
return config.enabled;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get node at path
|
|
85
|
+
*/
|
|
86
|
+
export function getNodeAtPath(root, path) {
|
|
87
|
+
let current = root;
|
|
88
|
+
for (const segment of path) {
|
|
89
|
+
if (!current || current.type !== 'directory') {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
current = current.children[segment];
|
|
93
|
+
}
|
|
94
|
+
return current;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Convert path array to string key
|
|
98
|
+
*/
|
|
99
|
+
export function pathToKey(path) {
|
|
100
|
+
return path.join('/');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Convert string key back to path array
|
|
104
|
+
*/
|
|
105
|
+
export function keyToPath(key) {
|
|
106
|
+
return key === '' ? [] : key.split('/');
|
|
107
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Middleware
|
|
3
|
+
*
|
|
4
|
+
* Core middleware that orchestrates autosave operations:
|
|
5
|
+
* 1. Detects file content changes
|
|
6
|
+
* 2. Manages debounce timers per file
|
|
7
|
+
* 3. Delegates save operations to registered providers
|
|
8
|
+
* 4. Handles retries on failure
|
|
9
|
+
*/
|
|
10
|
+
import type { Middleware } from 'redux';
|
|
11
|
+
import type { IAutosaveProviderRegistry, AutosaveResult } from '../../spi';
|
|
12
|
+
import { type AutosaveConfig } from '../../api';
|
|
13
|
+
/**
|
|
14
|
+
* Autosave middleware configuration
|
|
15
|
+
*/
|
|
16
|
+
export interface AutosaveMiddlewareConfig {
|
|
17
|
+
/** Autosave provider registry */
|
|
18
|
+
registry: IAutosaveProviderRegistry;
|
|
19
|
+
/** Redux slice name for filesystem state. Default: 'fileSystem' */
|
|
20
|
+
fsSliceName?: string;
|
|
21
|
+
/** Default autosave configuration */
|
|
22
|
+
defaultConfig?: Partial<AutosaveConfig>;
|
|
23
|
+
/** Callback when save starts */
|
|
24
|
+
onSaveStart?: (path: string[]) => void;
|
|
25
|
+
/** Callback when save succeeds */
|
|
26
|
+
onSaveSuccess?: (path: string[], result: AutosaveResult) => void;
|
|
27
|
+
/** Callback when save fails */
|
|
28
|
+
onSaveError?: (path: string[], error: {
|
|
29
|
+
code: string;
|
|
30
|
+
message: string;
|
|
31
|
+
}) => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create autosave middleware
|
|
35
|
+
*/
|
|
36
|
+
export declare function createAutosaveMiddleware(config: AutosaveMiddlewareConfig): Middleware;
|
|
37
|
+
//# sourceMappingURL=autosave-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autosave-middleware.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/autosave-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAElE,OAAO,KAAK,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAgFnB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,iCAAiC;IACjC,QAAQ,EAAE,yBAAyB,CAAC;IAEpC,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAExC,gCAAgC;IAChC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAEvC,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAEjE,+BAA+B;IAC/B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAClF;AAcD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,UAAU,CA6RZ"}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Middleware
|
|
3
|
+
*
|
|
4
|
+
* Core middleware that orchestrates autosave operations:
|
|
5
|
+
* 1. Detects file content changes
|
|
6
|
+
* 2. Manages debounce timers per file
|
|
7
|
+
* 3. Delegates save operations to registered providers
|
|
8
|
+
* 4. Handles retries on failure
|
|
9
|
+
*/
|
|
10
|
+
import { AutosaveActionTypes, autosaveActions, DEFAULT_AUTOSAVE_CONFIG, } from '../../api';
|
|
11
|
+
import { resolveAutosaveConfig, getNodeAtPath, pathToKey, } from './autosave-config-resolver';
|
|
12
|
+
/**
|
|
13
|
+
* Content change action types to monitor
|
|
14
|
+
*/
|
|
15
|
+
const CONTENT_CHANGE_ACTION_TYPES = [
|
|
16
|
+
'set-file-content',
|
|
17
|
+
'update-file-content',
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Check if an action is a content change action
|
|
21
|
+
*/
|
|
22
|
+
function isContentChangeAction(action) {
|
|
23
|
+
// Check for filesystem command actions
|
|
24
|
+
if (action.type === '@@fs/COMMAND' && action.command) {
|
|
25
|
+
return CONTENT_CHANGE_ACTION_TYPES.includes(action.command.name);
|
|
26
|
+
}
|
|
27
|
+
// Check for direct content change actions from fs-adapter
|
|
28
|
+
if (typeof action.type === 'string') {
|
|
29
|
+
const type = action.type.toLowerCase();
|
|
30
|
+
return (type.includes('setfilecontent') ||
|
|
31
|
+
type.includes('updatefilecontent') ||
|
|
32
|
+
type.includes('set_file_content') ||
|
|
33
|
+
type.includes('update_file_content'));
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if content change is from remote (should not trigger autosave)
|
|
39
|
+
*/
|
|
40
|
+
function isFromRemote(action) {
|
|
41
|
+
if (action.command?.fromRemote === true) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
if (action.payload?.fromRemote === true) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (action.fromRemote === true) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get path from action
|
|
54
|
+
*/
|
|
55
|
+
function getPathFromAction(action) {
|
|
56
|
+
// Try command path
|
|
57
|
+
if (action.command?.path) {
|
|
58
|
+
return Array.isArray(action.command.path)
|
|
59
|
+
? action.command.path
|
|
60
|
+
: [action.command.path];
|
|
61
|
+
}
|
|
62
|
+
// Try payload path
|
|
63
|
+
if (action.payload?.path) {
|
|
64
|
+
return Array.isArray(action.payload.path)
|
|
65
|
+
? action.payload.path
|
|
66
|
+
: [action.payload.path];
|
|
67
|
+
}
|
|
68
|
+
// Try direct path
|
|
69
|
+
if (action.path) {
|
|
70
|
+
return Array.isArray(action.path) ? action.path : [action.path];
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create autosave middleware
|
|
76
|
+
*/
|
|
77
|
+
export function createAutosaveMiddleware(config) {
|
|
78
|
+
const { registry, fsSliceName = 'fileSystem', defaultConfig = {}, onSaveStart, onSaveSuccess, onSaveError, } = config;
|
|
79
|
+
const mergedDefaultConfig = {
|
|
80
|
+
...DEFAULT_AUTOSAVE_CONFIG,
|
|
81
|
+
...defaultConfig,
|
|
82
|
+
};
|
|
83
|
+
// Track pending saves by path key
|
|
84
|
+
const pendingSaves = new Map();
|
|
85
|
+
/**
|
|
86
|
+
* Get filesystem root from state
|
|
87
|
+
*/
|
|
88
|
+
function getRoot(state) {
|
|
89
|
+
return state[fsSliceName]?.root;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Clear timers for a path
|
|
93
|
+
*/
|
|
94
|
+
function clearTimers(pathKey) {
|
|
95
|
+
const pending = pendingSaves.get(pathKey);
|
|
96
|
+
if (pending) {
|
|
97
|
+
clearTimeout(pending.debounceTimer);
|
|
98
|
+
if (pending.maxWaitTimer) {
|
|
99
|
+
clearTimeout(pending.maxWaitTimer);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Cancel pending save
|
|
105
|
+
*/
|
|
106
|
+
function cancelPending(pathKey) {
|
|
107
|
+
clearTimers(pathKey);
|
|
108
|
+
pendingSaves.delete(pathKey);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Schedule autosave for a path
|
|
112
|
+
*/
|
|
113
|
+
function scheduleAutosave(store, path, providerId, config) {
|
|
114
|
+
const pathKey = pathToKey(path);
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
const debounceMs = config.debounceMs ?? DEFAULT_AUTOSAVE_CONFIG.debounceMs;
|
|
117
|
+
const maxWaitMs = config.maxWaitMs ?? DEFAULT_AUTOSAVE_CONFIG.maxWaitMs;
|
|
118
|
+
// Clear existing debounce timer (but keep max wait if exists)
|
|
119
|
+
const existing = pendingSaves.get(pathKey);
|
|
120
|
+
if (existing) {
|
|
121
|
+
clearTimeout(existing.debounceTimer);
|
|
122
|
+
}
|
|
123
|
+
// Create debounce timer
|
|
124
|
+
const debounceTimer = setTimeout(() => {
|
|
125
|
+
store.dispatch(autosaveActions.debounceExpired(path));
|
|
126
|
+
}, debounceMs);
|
|
127
|
+
// Create max wait timer if not exists
|
|
128
|
+
let maxWaitTimer = existing?.maxWaitTimer;
|
|
129
|
+
if (!maxWaitTimer) {
|
|
130
|
+
maxWaitTimer = setTimeout(() => {
|
|
131
|
+
store.dispatch(autosaveActions.debounceExpired(path));
|
|
132
|
+
}, maxWaitMs);
|
|
133
|
+
}
|
|
134
|
+
// Store pending save
|
|
135
|
+
pendingSaves.set(pathKey, {
|
|
136
|
+
path,
|
|
137
|
+
providerId,
|
|
138
|
+
debounceTimer,
|
|
139
|
+
maxWaitTimer,
|
|
140
|
+
retryCount: existing?.retryCount ?? 0,
|
|
141
|
+
config,
|
|
142
|
+
});
|
|
143
|
+
// Dispatch change detected
|
|
144
|
+
store.dispatch(autosaveActions.changeDetected(path, now, now + debounceMs, providerId));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Execute save operation
|
|
148
|
+
*/
|
|
149
|
+
async function executeSave(store, path) {
|
|
150
|
+
const pathKey = pathToKey(path);
|
|
151
|
+
const pending = pendingSaves.get(pathKey);
|
|
152
|
+
if (!pending) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Clear timers
|
|
156
|
+
clearTimers(pathKey);
|
|
157
|
+
// Get current state
|
|
158
|
+
const state = store.getState();
|
|
159
|
+
const root = getRoot(state);
|
|
160
|
+
if (!root) {
|
|
161
|
+
pendingSaves.delete(pathKey);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Get node
|
|
165
|
+
const node = getNodeAtPath(root, path);
|
|
166
|
+
if (!node || node.type !== 'file') {
|
|
167
|
+
pendingSaves.delete(pathKey);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Get provider
|
|
171
|
+
const provider = registry.get(pending.providerId);
|
|
172
|
+
if (!provider) {
|
|
173
|
+
pendingSaves.delete(pathKey);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// Dispatch save started
|
|
177
|
+
store.dispatch(autosaveActions.saveStarted(path, pending.providerId));
|
|
178
|
+
onSaveStart?.(path);
|
|
179
|
+
try {
|
|
180
|
+
// Execute save via provider
|
|
181
|
+
const result = await provider.save(path, node.content, node, store.dispatch);
|
|
182
|
+
if (result.success) {
|
|
183
|
+
// Success
|
|
184
|
+
pendingSaves.delete(pathKey);
|
|
185
|
+
store.dispatch(autosaveActions.saveSucceeded(path, result.timestamp));
|
|
186
|
+
onSaveSuccess?.(path, result);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// Provider reported failure
|
|
190
|
+
handleSaveFailure(store, path, result.error ?? { code: 'UNKNOWN', message: 'Save failed' });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
// Exception during save
|
|
195
|
+
handleSaveFailure(store, path, {
|
|
196
|
+
code: error.code ?? 'ERROR',
|
|
197
|
+
message: error.message ?? 'Unknown error',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Handle save failure with retry logic
|
|
203
|
+
*/
|
|
204
|
+
function handleSaveFailure(store, path, error) {
|
|
205
|
+
const pathKey = pathToKey(path);
|
|
206
|
+
const pending = pendingSaves.get(pathKey);
|
|
207
|
+
if (!pending) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const retryCount = pending.retryCount + 1;
|
|
211
|
+
const maxRetries = pending.config.maxRetries ?? DEFAULT_AUTOSAVE_CONFIG.maxRetries;
|
|
212
|
+
const shouldRetry = pending.config.retryOnFailure !== false && retryCount < maxRetries;
|
|
213
|
+
// Dispatch failure
|
|
214
|
+
store.dispatch(autosaveActions.saveFailed(path, error, retryCount));
|
|
215
|
+
onSaveError?.(path, error);
|
|
216
|
+
if (shouldRetry) {
|
|
217
|
+
// Schedule retry with exponential backoff
|
|
218
|
+
const retryDelay = Math.min(1000 * Math.pow(2, retryCount - 1), 10000);
|
|
219
|
+
const retryAt = Date.now() + retryDelay;
|
|
220
|
+
store.dispatch(autosaveActions.retryScheduled(path, retryAt, retryCount));
|
|
221
|
+
// Update pending save with retry timer
|
|
222
|
+
pending.retryCount = retryCount;
|
|
223
|
+
pending.debounceTimer = setTimeout(() => {
|
|
224
|
+
executeSave(store, path);
|
|
225
|
+
}, retryDelay);
|
|
226
|
+
pendingSaves.set(pathKey, pending);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// No more retries
|
|
230
|
+
pendingSaves.delete(pathKey);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The middleware
|
|
235
|
+
*/
|
|
236
|
+
const autosaveMiddleware = (store) => (next) => (action) => {
|
|
237
|
+
const result = next(action);
|
|
238
|
+
const typedAction = action;
|
|
239
|
+
// ─────────────────────────────────────────────────────────────────
|
|
240
|
+
// Handle content changes
|
|
241
|
+
// ─────────────────────────────────────────────────────────────────
|
|
242
|
+
if (isContentChangeAction(typedAction) && !isFromRemote(typedAction)) {
|
|
243
|
+
const path = getPathFromAction(typedAction);
|
|
244
|
+
if (path) {
|
|
245
|
+
const state = store.getState();
|
|
246
|
+
const root = getRoot(state);
|
|
247
|
+
if (root) {
|
|
248
|
+
// Resolve config
|
|
249
|
+
const autosaveConfig = resolveAutosaveConfig(root, path, mergedDefaultConfig);
|
|
250
|
+
if (autosaveConfig.enabled) {
|
|
251
|
+
// Get node
|
|
252
|
+
const node = getNodeAtPath(root, path);
|
|
253
|
+
if (node) {
|
|
254
|
+
// Find provider
|
|
255
|
+
const provider = registry.findProvider(path, node);
|
|
256
|
+
if (provider) {
|
|
257
|
+
scheduleAutosave(store, path, provider.id, autosaveConfig);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// ─────────────────────────────────────────────────────────────────
|
|
265
|
+
// Handle autosave actions
|
|
266
|
+
// ─────────────────────────────────────────────────────────────────
|
|
267
|
+
switch (typedAction.type) {
|
|
268
|
+
case AutosaveActionTypes.DEBOUNCE_EXPIRED: {
|
|
269
|
+
const path = typedAction.payload.path;
|
|
270
|
+
void executeSave(store, path);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case AutosaveActionTypes.FLUSH_PENDING: {
|
|
274
|
+
const path = typedAction.payload.path;
|
|
275
|
+
const pathKey = pathToKey(path);
|
|
276
|
+
if (pendingSaves.has(pathKey)) {
|
|
277
|
+
void executeSave(store, path);
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case AutosaveActionTypes.FLUSH_ALL_PENDING: {
|
|
282
|
+
const paths = Array.from(pendingSaves.values()).map((p) => p.path);
|
|
283
|
+
for (const path of paths) {
|
|
284
|
+
void executeSave(store, path);
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case AutosaveActionTypes.CANCEL_PENDING: {
|
|
289
|
+
const path = typedAction.payload.path;
|
|
290
|
+
cancelPending(pathToKey(path));
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
};
|
|
296
|
+
return autosaveMiddleware;
|
|
297
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Provider Registry Implementation
|
|
3
|
+
*/
|
|
4
|
+
import type { FileSystemNode } from '@hamak/shared-utils';
|
|
5
|
+
import type { IAutosaveProvider, IAutosaveProviderRegistry } from '../../spi';
|
|
6
|
+
export declare class AutosaveProviderRegistry implements IAutosaveProviderRegistry {
|
|
7
|
+
private providers;
|
|
8
|
+
register(provider: IAutosaveProvider): void;
|
|
9
|
+
unregister(providerId: string): void;
|
|
10
|
+
get(providerId: string): IAutosaveProvider | undefined;
|
|
11
|
+
findProvider(path: string[], node: FileSystemNode): IAutosaveProvider | undefined;
|
|
12
|
+
getAll(): IAutosaveProvider[];
|
|
13
|
+
has(providerId: string): boolean;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=autosave-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autosave-registry.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/autosave-registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAE9E,qBAAa,wBAAyB,YAAW,yBAAyB;IACxE,OAAO,CAAC,SAAS,CAAwC;IAEzD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAS3C,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIpC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAItD,YAAY,CACV,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,cAAc,GACnB,iBAAiB,GAAG,SAAS;IAShC,MAAM,IAAI,iBAAiB,EAAE;IAI7B,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;CAGjC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Provider Registry Implementation
|
|
3
|
+
*/
|
|
4
|
+
export class AutosaveProviderRegistry {
|
|
5
|
+
constructor() {
|
|
6
|
+
Object.defineProperty(this, "providers", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: new Map()
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
register(provider) {
|
|
14
|
+
if (this.providers.has(provider.id)) {
|
|
15
|
+
console.warn(`[AutosaveRegistry] Provider "${provider.id}" already registered, overwriting.`);
|
|
16
|
+
}
|
|
17
|
+
this.providers.set(provider.id, provider);
|
|
18
|
+
}
|
|
19
|
+
unregister(providerId) {
|
|
20
|
+
this.providers.delete(providerId);
|
|
21
|
+
}
|
|
22
|
+
get(providerId) {
|
|
23
|
+
return this.providers.get(providerId);
|
|
24
|
+
}
|
|
25
|
+
findProvider(path, node) {
|
|
26
|
+
// Get all providers that support this path, sorted by priority (descending)
|
|
27
|
+
const supportingProviders = Array.from(this.providers.values())
|
|
28
|
+
.filter((provider) => provider.supports(path, node))
|
|
29
|
+
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
30
|
+
return supportingProviders[0];
|
|
31
|
+
}
|
|
32
|
+
getAll() {
|
|
33
|
+
return Array.from(this.providers.values());
|
|
34
|
+
}
|
|
35
|
+
has(providerId) {
|
|
36
|
+
return this.providers.has(providerId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Sync Middleware
|
|
3
|
+
*
|
|
4
|
+
* Updates FileSystemNode extension states based on autosave lifecycle actions.
|
|
5
|
+
* This middleware runs after the main autosave middleware and updates the
|
|
6
|
+
* state so components can display autosave status.
|
|
7
|
+
*/
|
|
8
|
+
import type { Middleware, AnyAction } from 'redux';
|
|
9
|
+
import { type AutosaveExtensionState } from '../../api';
|
|
10
|
+
/**
|
|
11
|
+
* Autosave sync middleware configuration
|
|
12
|
+
*/
|
|
13
|
+
export interface AutosaveSyncMiddlewareConfig {
|
|
14
|
+
/**
|
|
15
|
+
* Function to dispatch extension state update.
|
|
16
|
+
* This should update the node's extensionStates[AUTOSAVE_EXTENSION_KEY].
|
|
17
|
+
*/
|
|
18
|
+
updateExtensionState: (path: string[], state: Partial<AutosaveExtensionState>) => AnyAction;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create autosave sync middleware
|
|
22
|
+
*/
|
|
23
|
+
export declare function createAutosaveSyncMiddleware(config: AutosaveSyncMiddlewareConfig): Middleware;
|
|
24
|
+
//# sourceMappingURL=autosave-sync-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autosave-sync-middleware.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/autosave-sync-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAGL,KAAK,sBAAsB,EAE5B,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,oBAAoB,EAAE,CACpB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,CAAC,sBAAsB,CAAC,KACnC,SAAS,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,GACnC,UAAU,CAmHZ"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Sync Middleware
|
|
3
|
+
*
|
|
4
|
+
* Updates FileSystemNode extension states based on autosave lifecycle actions.
|
|
5
|
+
* This middleware runs after the main autosave middleware and updates the
|
|
6
|
+
* state so components can display autosave status.
|
|
7
|
+
*/
|
|
8
|
+
import { AutosaveActionTypes, autosaveActions, } from '../../api';
|
|
9
|
+
/**
|
|
10
|
+
* Create autosave sync middleware
|
|
11
|
+
*/
|
|
12
|
+
export function createAutosaveSyncMiddleware(config) {
|
|
13
|
+
const { updateExtensionState } = config;
|
|
14
|
+
const autosaveSyncMiddleware = (store) => (next) => (action) => {
|
|
15
|
+
const result = next(action);
|
|
16
|
+
const typedAction = action;
|
|
17
|
+
// Only process autosave actions
|
|
18
|
+
if (!autosaveActions.isAutosaveAction(typedAction)) {
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
const dispatch = store.dispatch;
|
|
22
|
+
switch (typedAction.type) {
|
|
23
|
+
case AutosaveActionTypes.SET_CONFIG: {
|
|
24
|
+
const { path, config: autosaveConfig } = typedAction.payload;
|
|
25
|
+
dispatch(updateExtensionState(path, {
|
|
26
|
+
config: autosaveConfig,
|
|
27
|
+
effectivelyEnabled: autosaveConfig.enabled,
|
|
28
|
+
status: autosaveConfig.enabled ? 'idle' : 'disabled',
|
|
29
|
+
}));
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case AutosaveActionTypes.CLEAR_CONFIG: {
|
|
33
|
+
const { path } = typedAction.payload;
|
|
34
|
+
dispatch(updateExtensionState(path, {
|
|
35
|
+
config: undefined,
|
|
36
|
+
// Status will be recomputed based on parent config
|
|
37
|
+
}));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case AutosaveActionTypes.CHANGE_DETECTED: {
|
|
41
|
+
const { path, detectedAt, providerId } = typedAction.payload;
|
|
42
|
+
dispatch(updateExtensionState(path, {
|
|
43
|
+
status: 'pending',
|
|
44
|
+
pendingSince: detectedAt,
|
|
45
|
+
providerId,
|
|
46
|
+
}));
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case AutosaveActionTypes.SAVE_STARTED: {
|
|
50
|
+
const { path, providerId } = typedAction.payload;
|
|
51
|
+
dispatch(updateExtensionState(path, {
|
|
52
|
+
status: 'saving',
|
|
53
|
+
lastSaveAttempt: Date.now(),
|
|
54
|
+
providerId,
|
|
55
|
+
}));
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case AutosaveActionTypes.SAVE_SUCCEEDED: {
|
|
59
|
+
const { path, timestamp } = typedAction.payload;
|
|
60
|
+
dispatch(updateExtensionState(path, {
|
|
61
|
+
status: 'idle',
|
|
62
|
+
lastSaveSuccess: timestamp,
|
|
63
|
+
lastSaveError: undefined,
|
|
64
|
+
retryCount: 0,
|
|
65
|
+
pendingSince: undefined,
|
|
66
|
+
}));
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case AutosaveActionTypes.SAVE_FAILED: {
|
|
70
|
+
const { path, error } = typedAction.payload;
|
|
71
|
+
dispatch(updateExtensionState(path, {
|
|
72
|
+
status: 'error',
|
|
73
|
+
lastSaveError: error,
|
|
74
|
+
retryCount: error.attempt,
|
|
75
|
+
}));
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case AutosaveActionTypes.RETRY_SCHEDULED: {
|
|
79
|
+
const { path, attempt } = typedAction.payload;
|
|
80
|
+
dispatch(updateExtensionState(path, {
|
|
81
|
+
status: 'pending',
|
|
82
|
+
retryCount: attempt,
|
|
83
|
+
}));
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case AutosaveActionTypes.CANCEL_PENDING: {
|
|
87
|
+
const { path } = typedAction.payload;
|
|
88
|
+
dispatch(updateExtensionState(path, {
|
|
89
|
+
status: 'idle',
|
|
90
|
+
pendingSince: undefined,
|
|
91
|
+
}));
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
};
|
|
97
|
+
return autosaveSyncMiddleware;
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
|