@hamak/ui-remote-resource 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/dist/api/actions/entity-action-factory.d.ts +28 -0
- package/dist/api/actions/entity-action-factory.d.ts.map +1 -0
- package/dist/api/actions/entity-action-factory.js +62 -0
- package/dist/api/actions/entity-action-types.d.ts +104 -0
- package/dist/api/actions/entity-action-types.d.ts.map +1 -0
- package/dist/api/actions/entity-action-types.js +16 -0
- package/dist/api/actions/resource-action-factory.d.ts +40 -0
- package/dist/api/actions/resource-action-factory.d.ts.map +1 -0
- package/dist/api/actions/resource-action-factory.js +93 -0
- package/dist/api/actions/resource-action-types.d.ts +105 -0
- package/dist/api/actions/resource-action-types.d.ts.map +1 -0
- package/dist/api/actions/resource-action-types.js +13 -0
- package/dist/api/constants.d.ts +6 -0
- package/dist/api/constants.d.ts.map +1 -0
- package/dist/api/constants.js +5 -0
- package/dist/api/contracts/i-entity-registry.d.ts +19 -0
- package/dist/api/contracts/i-entity-registry.d.ts.map +1 -0
- package/dist/api/contracts/i-entity-registry.js +1 -0
- package/dist/api/contracts/i-resource-registry.d.ts +19 -0
- package/dist/api/contracts/i-resource-registry.d.ts.map +1 -0
- package/dist/api/contracts/i-resource-registry.js +1 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +15 -0
- package/dist/api/types/action-types.d.ts +34 -0
- package/dist/api/types/action-types.d.ts.map +1 -0
- package/dist/api/types/action-types.js +1 -0
- package/dist/api/types/resource-attributes.d.ts +43 -0
- package/dist/api/types/resource-attributes.d.ts.map +1 -0
- package/dist/api/types/resource-attributes.js +1 -0
- package/dist/api/types/resource-types.d.ts +20 -0
- package/dist/api/types/resource-types.d.ts.map +1 -0
- package/dist/api/types/resource-types.js +1 -0
- package/dist/api/utils/resource-attributes-util.d.ts +183 -0
- package/dist/api/utils/resource-attributes-util.d.ts.map +1 -0
- package/dist/api/utils/resource-attributes-util.js +280 -0
- package/dist/impl/autosave/index.d.ts +5 -0
- package/dist/impl/autosave/index.d.ts.map +1 -0
- package/dist/impl/autosave/index.js +4 -0
- package/dist/impl/autosave/resource-autosave-provider.d.ts +49 -0
- package/dist/impl/autosave/resource-autosave-provider.d.ts.map +1 -0
- package/dist/impl/autosave/resource-autosave-provider.js +112 -0
- package/dist/impl/index.d.ts +20 -0
- package/dist/impl/index.d.ts.map +1 -0
- package/dist/impl/index.js +20 -0
- package/dist/impl/middleware/entity-middleware.d.ts +13 -0
- package/dist/impl/middleware/entity-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/entity-middleware.js +221 -0
- package/dist/impl/middleware/entity-sync-middleware.d.ts +7 -0
- package/dist/impl/middleware/entity-sync-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/entity-sync-middleware.js +32 -0
- package/dist/impl/middleware/resource-middleware.d.ts +13 -0
- package/dist/impl/middleware/resource-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/resource-middleware.js +97 -0
- package/dist/impl/middleware/sync-middleware.d.ts +12 -0
- package/dist/impl/middleware/sync-middleware.d.ts.map +1 -0
- package/dist/impl/middleware/sync-middleware.js +80 -0
- package/dist/impl/plugin/resource-plugin-factory.d.ts +31 -0
- package/dist/impl/plugin/resource-plugin-factory.d.ts.map +1 -0
- package/dist/impl/plugin/resource-plugin-factory.js +131 -0
- package/dist/impl/providers/mock-resource-provider.d.ts +147 -0
- package/dist/impl/providers/mock-resource-provider.d.ts.map +1 -0
- package/dist/impl/providers/mock-resource-provider.js +242 -0
- package/dist/impl/providers/rest-resource-provider.d.ts +51 -0
- package/dist/impl/providers/rest-resource-provider.d.ts.map +1 -0
- package/dist/impl/providers/rest-resource-provider.js +128 -0
- package/dist/impl/registry/entity-registry.d.ts +54 -0
- package/dist/impl/registry/entity-registry.d.ts.map +1 -0
- package/dist/impl/registry/entity-registry.js +51 -0
- package/dist/impl/registry/resource-registry.d.ts +80 -0
- package/dist/impl/registry/resource-registry.d.ts.map +1 -0
- package/dist/impl/registry/resource-registry.js +74 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/spi/config/endpoint-definition.d.ts +46 -0
- package/dist/spi/config/endpoint-definition.d.ts.map +1 -0
- package/dist/spi/config/endpoint-definition.js +1 -0
- package/dist/spi/config/entity-definition.d.ts +50 -0
- package/dist/spi/config/entity-definition.d.ts.map +1 -0
- package/dist/spi/config/entity-definition.js +1 -0
- package/dist/spi/config/plugin-config.d.ts +21 -0
- package/dist/spi/config/plugin-config.d.ts.map +1 -0
- package/dist/spi/config/plugin-config.js +1 -0
- package/dist/spi/index.d.ts +6 -0
- package/dist/spi/index.d.ts.map +1 -0
- package/dist/spi/index.js +7 -0
- package/dist/spi/providers/i-resource-provider.d.ts +42 -0
- package/dist/spi/providers/i-resource-provider.d.ts.map +1 -0
- package/dist/spi/providers/i-resource-provider.js +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ResourceOperation, EntityKey } from './resource-types';
|
|
2
|
+
/**
|
|
3
|
+
* Remote resource attributes stored in extensionStates
|
|
4
|
+
*
|
|
5
|
+
* Note: Does not include loading/error/schema as these are already in FileSystemNode:
|
|
6
|
+
* - loading: FileSystemNodeState.contentLoading
|
|
7
|
+
* - error: FileSystemNodeState.contentLoadError
|
|
8
|
+
* - schema: FileNode.schema (top-level field)
|
|
9
|
+
*/
|
|
10
|
+
export interface RemoteResourceAttributes {
|
|
11
|
+
/** Last fetch timestamp */
|
|
12
|
+
lastFetched?: number;
|
|
13
|
+
/** Cache expiry timestamp */
|
|
14
|
+
expiresAt?: number;
|
|
15
|
+
/** Endpoint ID that populated this file */
|
|
16
|
+
endpointId?: string;
|
|
17
|
+
/** Resource-specific metadata */
|
|
18
|
+
metadata?: {
|
|
19
|
+
status?: number;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
};
|
|
23
|
+
/** Last operation performed */
|
|
24
|
+
lastOperation?: ResourceOperation;
|
|
25
|
+
/** Optimistic update flag */
|
|
26
|
+
optimistic?: boolean;
|
|
27
|
+
/** Entity-specific attributes (if this resource represents an entity) */
|
|
28
|
+
entity?: EntityAttributes;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Entity-specific attributes (nested under resource attributes)
|
|
32
|
+
*/
|
|
33
|
+
export interface EntityAttributes {
|
|
34
|
+
/** Entity type identifier */
|
|
35
|
+
entityId: string;
|
|
36
|
+
/** Entity keys (for re-fetching, updating, deleting) */
|
|
37
|
+
keys: EntityKey;
|
|
38
|
+
/** Entity key schema fields */
|
|
39
|
+
keyFields: string[];
|
|
40
|
+
/** Entity version (for optimistic locking) */
|
|
41
|
+
version?: string | number;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=resource-attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-attributes.d.ts","sourceRoot":"","sources":["../../../src/api/types/resource-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iCAAiC;IACjC,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IAEF,+BAA+B;IAC/B,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAElC,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,yEAAyE;IACzE,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IAEjB,wDAAwD;IACxD,IAAI,EAAE,SAAS,CAAC;IAEhB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource operation types
|
|
3
|
+
*/
|
|
4
|
+
export type ResourceOperation = 'fetch' | 'create' | 'update' | 'delete';
|
|
5
|
+
/**
|
|
6
|
+
* Entity key - can be simple or composite
|
|
7
|
+
* Examples:
|
|
8
|
+
* - Simple: { id: "123" }
|
|
9
|
+
* - Composite: { tenantId: "org1", userId: "user123" }
|
|
10
|
+
*/
|
|
11
|
+
export type EntityKey = Record<string, string | number>;
|
|
12
|
+
/**
|
|
13
|
+
* Error object structure
|
|
14
|
+
*/
|
|
15
|
+
export interface ErrorObject {
|
|
16
|
+
message: string;
|
|
17
|
+
code?: string;
|
|
18
|
+
details?: any;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=resource-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-types.d.ts","sourceRoot":"","sources":["../../../src/api/types/resource-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
type FileSystemNode = any;
|
|
2
|
+
import type { RemoteResourceAttributes, EntityAttributes } from '../types/resource-attributes';
|
|
3
|
+
import type { EntityKey, ResourceOperation } from '../types/resource-types';
|
|
4
|
+
/**
|
|
5
|
+
* Utility class for accessing and manipulating remote resource attributes
|
|
6
|
+
* stored in file node extension states.
|
|
7
|
+
*
|
|
8
|
+
* Note: This utility accesses loading/error/schema from FileSystemNode directly:
|
|
9
|
+
* - loading: node.state.contentLoading
|
|
10
|
+
* - error: node.state.contentLoadError
|
|
11
|
+
* - schema: node.schema (for FileNode)
|
|
12
|
+
*/
|
|
13
|
+
export declare class ResourceAttributesUtil {
|
|
14
|
+
/**
|
|
15
|
+
* Extension state key for remote resource attributes
|
|
16
|
+
*/
|
|
17
|
+
readonly extensionKey = "ui-remote-resource";
|
|
18
|
+
/**
|
|
19
|
+
* Get remote resource attributes from file node extension state
|
|
20
|
+
*/
|
|
21
|
+
getResourceAttributes(node: FileSystemNode | undefined): RemoteResourceAttributes | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Check if file has resource attributes
|
|
24
|
+
*/
|
|
25
|
+
hasResourceAttributes(node: FileSystemNode | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get loading state from FileSystemNodeState (not extension state)
|
|
28
|
+
*/
|
|
29
|
+
isLoading(node: FileSystemNode | undefined): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Get error information from FileSystemNodeState (not extension state)
|
|
32
|
+
*/
|
|
33
|
+
getError(node: FileSystemNode | undefined): {
|
|
34
|
+
message?: string;
|
|
35
|
+
code?: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Check if resource has error
|
|
39
|
+
*/
|
|
40
|
+
hasError(node: FileSystemNode | undefined): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Get resource metadata from extension state
|
|
43
|
+
*/
|
|
44
|
+
getMetadata(node: FileSystemNode | undefined): Record<string, any> | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Get last fetch timestamp from extension state
|
|
47
|
+
*/
|
|
48
|
+
getLastFetchTime(node: FileSystemNode | undefined): number | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Get cache expiry timestamp from extension state
|
|
51
|
+
*/
|
|
52
|
+
getExpiryTime(node: FileSystemNode | undefined): number | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Check if resource is cached and not expired
|
|
55
|
+
*/
|
|
56
|
+
isCached(node: FileSystemNode | undefined): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Get endpoint ID from extension state
|
|
59
|
+
*/
|
|
60
|
+
getEndpointId(node: FileSystemNode | undefined): string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Get schema reference from FileNode (not extension state)
|
|
63
|
+
*/
|
|
64
|
+
getSchema(node: FileSystemNode | undefined): string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Get last operation performed from extension state
|
|
67
|
+
*/
|
|
68
|
+
getLastOperation(node: FileSystemNode | undefined): ResourceOperation | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Check if resource is optimistic update
|
|
71
|
+
*/
|
|
72
|
+
isOptimistic(node: FileSystemNode | undefined): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Get entity attributes from extension state
|
|
75
|
+
*/
|
|
76
|
+
getEntityAttributes(node: FileSystemNode | undefined): EntityAttributes | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Check if file represents an entity
|
|
79
|
+
*/
|
|
80
|
+
isEntity(node: FileSystemNode | undefined): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Get entity ID
|
|
83
|
+
*/
|
|
84
|
+
getEntityId(node: FileSystemNode | undefined): string | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Get entity keys
|
|
87
|
+
*/
|
|
88
|
+
getEntityKeys(node: FileSystemNode | undefined): EntityKey | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Get entity key fields
|
|
91
|
+
*/
|
|
92
|
+
getEntityKeyFields(node: FileSystemNode | undefined): string[] | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Get entity version
|
|
95
|
+
*/
|
|
96
|
+
getEntityVersion(node: FileSystemNode | undefined): string | number | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Get specific entity key value
|
|
99
|
+
*/
|
|
100
|
+
getEntityKeyValue(node: FileSystemNode | undefined, keyField: string): string | number | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Create resource attributes object (for extension state only)
|
|
103
|
+
* Does NOT include loading/error/schema - those go in FileSystemNodeState/FileNode
|
|
104
|
+
*/
|
|
105
|
+
createResourceAttributes(partial: Partial<RemoteResourceAttributes>): RemoteResourceAttributes;
|
|
106
|
+
/**
|
|
107
|
+
* Create entity attributes object
|
|
108
|
+
*/
|
|
109
|
+
createEntityAttributes(entityId: string, keys: EntityKey, keyFields: string[], version?: string | number): EntityAttributes;
|
|
110
|
+
/**
|
|
111
|
+
* Merge resource attributes (for partial updates in extension state)
|
|
112
|
+
*/
|
|
113
|
+
mergeResourceAttributes(existing: RemoteResourceAttributes | undefined, updates: Partial<RemoteResourceAttributes>): RemoteResourceAttributes;
|
|
114
|
+
/**
|
|
115
|
+
* Create attributes for successful resource call
|
|
116
|
+
* Note: loading/error are managed separately in FileSystemNodeState
|
|
117
|
+
*/
|
|
118
|
+
createSuccessAttributes(endpointId: string, metadata?: any, operation?: ResourceOperation): RemoteResourceAttributes;
|
|
119
|
+
/**
|
|
120
|
+
* Check if resource needs refresh based on cache duration
|
|
121
|
+
*/
|
|
122
|
+
needsRefresh(node: FileSystemNode | undefined, cacheDurationMs?: number): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Calculate cache expiry time
|
|
125
|
+
*/
|
|
126
|
+
calculateExpiryTime(cacheDurationMs: number): number;
|
|
127
|
+
/**
|
|
128
|
+
* Get complete resource state for component use
|
|
129
|
+
*/
|
|
130
|
+
getResourceState(node: FileSystemNode | undefined): {
|
|
131
|
+
data: any;
|
|
132
|
+
loading: boolean;
|
|
133
|
+
error: {
|
|
134
|
+
message?: string | undefined;
|
|
135
|
+
code?: string | undefined;
|
|
136
|
+
} | undefined;
|
|
137
|
+
metadata: {
|
|
138
|
+
[key: string]: any;
|
|
139
|
+
status?: number | undefined;
|
|
140
|
+
headers?: Record<string, string> | undefined;
|
|
141
|
+
} | undefined;
|
|
142
|
+
lastFetched: number | undefined;
|
|
143
|
+
cached: boolean;
|
|
144
|
+
endpointId: string | undefined;
|
|
145
|
+
schema: string | undefined;
|
|
146
|
+
lastOperation: ResourceOperation | undefined;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Get complete entity state for component use
|
|
150
|
+
*/
|
|
151
|
+
getEntityState(node: FileSystemNode | undefined): {
|
|
152
|
+
isEntity: boolean;
|
|
153
|
+
entityId: string | undefined;
|
|
154
|
+
entityKeys: EntityKey | undefined;
|
|
155
|
+
entityKeyFields: string[] | undefined;
|
|
156
|
+
entityVersion: string | number | undefined;
|
|
157
|
+
data: any;
|
|
158
|
+
loading: boolean;
|
|
159
|
+
error: {
|
|
160
|
+
message?: string | undefined;
|
|
161
|
+
code?: string | undefined;
|
|
162
|
+
} | undefined;
|
|
163
|
+
metadata: {
|
|
164
|
+
[key: string]: any;
|
|
165
|
+
status?: number | undefined;
|
|
166
|
+
headers?: Record<string, string> | undefined;
|
|
167
|
+
} | undefined;
|
|
168
|
+
lastFetched: number | undefined;
|
|
169
|
+
cached: boolean;
|
|
170
|
+
endpointId: string | undefined;
|
|
171
|
+
schema: string | undefined;
|
|
172
|
+
lastOperation: ResourceOperation | undefined;
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Singleton instance
|
|
177
|
+
*/
|
|
178
|
+
export declare const resourceAttributesUtil: ResourceAttributesUtil;
|
|
179
|
+
/**
|
|
180
|
+
* Default export for convenience
|
|
181
|
+
*/
|
|
182
|
+
export default resourceAttributesUtil;
|
|
183
|
+
//# sourceMappingURL=resource-attributes-util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-attributes-util.d.ts","sourceRoot":"","sources":["../../../src/api/utils/resource-attributes-util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { REMOTE_RESOURCE_EXTENSION_KEY } from '../constants';
|
|
2
|
+
/**
|
|
3
|
+
* Utility class for accessing and manipulating remote resource attributes
|
|
4
|
+
* stored in file node extension states.
|
|
5
|
+
*
|
|
6
|
+
* Note: This utility accesses loading/error/schema from FileSystemNode directly:
|
|
7
|
+
* - loading: node.state.contentLoading
|
|
8
|
+
* - error: node.state.contentLoadError
|
|
9
|
+
* - schema: node.schema (for FileNode)
|
|
10
|
+
*/
|
|
11
|
+
export class ResourceAttributesUtil {
|
|
12
|
+
constructor() {
|
|
13
|
+
/**
|
|
14
|
+
* Extension state key for remote resource attributes
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(this, "extensionKey", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: REMOTE_RESOURCE_EXTENSION_KEY
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
// ========== Resource Attributes Accessors ==========
|
|
24
|
+
/**
|
|
25
|
+
* Get remote resource attributes from file node extension state
|
|
26
|
+
*/
|
|
27
|
+
getResourceAttributes(node) {
|
|
28
|
+
if (!node || node.type !== 'file') {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const fileNode = node;
|
|
32
|
+
return fileNode.state?.extensionStates?.[this.extensionKey];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if file has resource attributes
|
|
36
|
+
*/
|
|
37
|
+
hasResourceAttributes(node) {
|
|
38
|
+
return this.getResourceAttributes(node) !== undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get loading state from FileSystemNodeState (not extension state)
|
|
42
|
+
*/
|
|
43
|
+
isLoading(node) {
|
|
44
|
+
if (!node)
|
|
45
|
+
return false;
|
|
46
|
+
return node.state?.contentLoading === true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get error information from FileSystemNodeState (not extension state)
|
|
50
|
+
*/
|
|
51
|
+
getError(node) {
|
|
52
|
+
if (!node)
|
|
53
|
+
return undefined;
|
|
54
|
+
return node.state?.contentLoadError;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if resource has error
|
|
58
|
+
*/
|
|
59
|
+
hasError(node) {
|
|
60
|
+
return this.getError(node) !== undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get resource metadata from extension state
|
|
64
|
+
*/
|
|
65
|
+
getMetadata(node) {
|
|
66
|
+
return this.getResourceAttributes(node)?.metadata;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get last fetch timestamp from extension state
|
|
70
|
+
*/
|
|
71
|
+
getLastFetchTime(node) {
|
|
72
|
+
return this.getResourceAttributes(node)?.lastFetched;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get cache expiry timestamp from extension state
|
|
76
|
+
*/
|
|
77
|
+
getExpiryTime(node) {
|
|
78
|
+
return this.getResourceAttributes(node)?.expiresAt;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if resource is cached and not expired
|
|
82
|
+
*/
|
|
83
|
+
isCached(node) {
|
|
84
|
+
const attrs = this.getResourceAttributes(node);
|
|
85
|
+
if (!attrs || !attrs.lastFetched) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (attrs.expiresAt) {
|
|
89
|
+
return Date.now() < attrs.expiresAt;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get endpoint ID from extension state
|
|
95
|
+
*/
|
|
96
|
+
getEndpointId(node) {
|
|
97
|
+
return this.getResourceAttributes(node)?.endpointId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get schema reference from FileNode (not extension state)
|
|
101
|
+
*/
|
|
102
|
+
getSchema(node) {
|
|
103
|
+
if (!node || node.type !== 'file') {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const fileNode = node;
|
|
107
|
+
return typeof fileNode.schema === 'string'
|
|
108
|
+
? fileNode.schema
|
|
109
|
+
: fileNode.schema?.schemaObject;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get last operation performed from extension state
|
|
113
|
+
*/
|
|
114
|
+
getLastOperation(node) {
|
|
115
|
+
return this.getResourceAttributes(node)?.lastOperation;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if resource is optimistic update
|
|
119
|
+
*/
|
|
120
|
+
isOptimistic(node) {
|
|
121
|
+
return this.getResourceAttributes(node)?.optimistic === true;
|
|
122
|
+
}
|
|
123
|
+
// ========== Entity Attributes Accessors ==========
|
|
124
|
+
/**
|
|
125
|
+
* Get entity attributes from extension state
|
|
126
|
+
*/
|
|
127
|
+
getEntityAttributes(node) {
|
|
128
|
+
const resourceAttrs = this.getResourceAttributes(node);
|
|
129
|
+
return resourceAttrs?.entity;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Check if file represents an entity
|
|
133
|
+
*/
|
|
134
|
+
isEntity(node) {
|
|
135
|
+
return this.getEntityAttributes(node) !== undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get entity ID
|
|
139
|
+
*/
|
|
140
|
+
getEntityId(node) {
|
|
141
|
+
return this.getEntityAttributes(node)?.entityId;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get entity keys
|
|
145
|
+
*/
|
|
146
|
+
getEntityKeys(node) {
|
|
147
|
+
return this.getEntityAttributes(node)?.keys;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get entity key fields
|
|
151
|
+
*/
|
|
152
|
+
getEntityKeyFields(node) {
|
|
153
|
+
return this.getEntityAttributes(node)?.keyFields;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get entity version
|
|
157
|
+
*/
|
|
158
|
+
getEntityVersion(node) {
|
|
159
|
+
return this.getEntityAttributes(node)?.version;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get specific entity key value
|
|
163
|
+
*/
|
|
164
|
+
getEntityKeyValue(node, keyField) {
|
|
165
|
+
const keys = this.getEntityKeys(node);
|
|
166
|
+
return keys?.[keyField];
|
|
167
|
+
}
|
|
168
|
+
// ========== Attribute Builders ==========
|
|
169
|
+
/**
|
|
170
|
+
* Create resource attributes object (for extension state only)
|
|
171
|
+
* Does NOT include loading/error/schema - those go in FileSystemNodeState/FileNode
|
|
172
|
+
*/
|
|
173
|
+
createResourceAttributes(partial) {
|
|
174
|
+
return {
|
|
175
|
+
...partial
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Create entity attributes object
|
|
180
|
+
*/
|
|
181
|
+
createEntityAttributes(entityId, keys, keyFields, version) {
|
|
182
|
+
return {
|
|
183
|
+
entityId,
|
|
184
|
+
keys,
|
|
185
|
+
keyFields,
|
|
186
|
+
version
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Merge resource attributes (for partial updates in extension state)
|
|
191
|
+
*/
|
|
192
|
+
mergeResourceAttributes(existing, updates) {
|
|
193
|
+
return {
|
|
194
|
+
...existing,
|
|
195
|
+
...updates,
|
|
196
|
+
// Deep merge metadata
|
|
197
|
+
metadata: {
|
|
198
|
+
...existing?.metadata,
|
|
199
|
+
...updates.metadata
|
|
200
|
+
},
|
|
201
|
+
// Deep merge entity (if present in both)
|
|
202
|
+
entity: updates.entity !== undefined
|
|
203
|
+
? { ...existing?.entity, ...updates.entity }
|
|
204
|
+
: existing?.entity
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Create attributes for successful resource call
|
|
209
|
+
* Note: loading/error are managed separately in FileSystemNodeState
|
|
210
|
+
*/
|
|
211
|
+
createSuccessAttributes(endpointId, metadata, operation) {
|
|
212
|
+
return {
|
|
213
|
+
endpointId,
|
|
214
|
+
metadata,
|
|
215
|
+
lastFetched: Date.now(),
|
|
216
|
+
lastOperation: operation
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// ========== Cache Utilities ==========
|
|
220
|
+
/**
|
|
221
|
+
* Check if resource needs refresh based on cache duration
|
|
222
|
+
*/
|
|
223
|
+
needsRefresh(node, cacheDurationMs) {
|
|
224
|
+
if (!cacheDurationMs) {
|
|
225
|
+
return !this.isCached(node);
|
|
226
|
+
}
|
|
227
|
+
const lastFetched = this.getLastFetchTime(node);
|
|
228
|
+
if (!lastFetched) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
return Date.now() - lastFetched > cacheDurationMs;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Calculate cache expiry time
|
|
235
|
+
*/
|
|
236
|
+
calculateExpiryTime(cacheDurationMs) {
|
|
237
|
+
return Date.now() + cacheDurationMs;
|
|
238
|
+
}
|
|
239
|
+
// ========== Utility Methods ==========
|
|
240
|
+
/**
|
|
241
|
+
* Get complete resource state for component use
|
|
242
|
+
*/
|
|
243
|
+
getResourceState(node) {
|
|
244
|
+
const attrs = this.getResourceAttributes(node);
|
|
245
|
+
return {
|
|
246
|
+
data: node?.type === 'file' ? node.content : undefined,
|
|
247
|
+
loading: this.isLoading(node),
|
|
248
|
+
error: this.getError(node),
|
|
249
|
+
metadata: attrs?.metadata,
|
|
250
|
+
lastFetched: attrs?.lastFetched,
|
|
251
|
+
cached: this.isCached(node),
|
|
252
|
+
endpointId: attrs?.endpointId,
|
|
253
|
+
schema: this.getSchema(node),
|
|
254
|
+
lastOperation: attrs?.lastOperation
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Get complete entity state for component use
|
|
259
|
+
*/
|
|
260
|
+
getEntityState(node) {
|
|
261
|
+
const resourceState = this.getResourceState(node);
|
|
262
|
+
const entityAttrs = this.getEntityAttributes(node);
|
|
263
|
+
return {
|
|
264
|
+
...resourceState,
|
|
265
|
+
isEntity: !!entityAttrs,
|
|
266
|
+
entityId: entityAttrs?.entityId,
|
|
267
|
+
entityKeys: entityAttrs?.keys,
|
|
268
|
+
entityKeyFields: entityAttrs?.keyFields,
|
|
269
|
+
entityVersion: entityAttrs?.version
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Singleton instance
|
|
275
|
+
*/
|
|
276
|
+
export const resourceAttributesUtil = new ResourceAttributesUtil();
|
|
277
|
+
/**
|
|
278
|
+
* Default export for convenience
|
|
279
|
+
*/
|
|
280
|
+
export default resourceAttributesUtil;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Autosave Provider
|
|
3
|
+
*
|
|
4
|
+
* Implements autosave for files managed by the remote resource plugin.
|
|
5
|
+
* Uses UPDATE_ENTITY or RESOURCE_CALL_REQUEST actions to save files.
|
|
6
|
+
*/
|
|
7
|
+
import type { Dispatch, AnyAction } from 'redux';
|
|
8
|
+
import type { FileSystemNode } from '@hamak/shared-utils';
|
|
9
|
+
import type { IAutosaveProvider, AutosaveResult } from '@hamak/ui-store-spi';
|
|
10
|
+
import { EntityActionFactory } from '../../api';
|
|
11
|
+
import { ResourceActionFactory } from '../../api';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for ResourceAutosaveProvider
|
|
14
|
+
*/
|
|
15
|
+
export interface ResourceAutosaveProviderConfig {
|
|
16
|
+
/** Entity action factory */
|
|
17
|
+
entityActionFactory?: EntityActionFactory;
|
|
18
|
+
/** Resource action factory */
|
|
19
|
+
resourceActionFactory?: ResourceActionFactory;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Autosave provider for remote resources
|
|
23
|
+
*
|
|
24
|
+
* This provider handles autosave for files that are managed via the
|
|
25
|
+
* remote resource plugin. It checks for the presence of resource/entity
|
|
26
|
+
* extension state and uses appropriate actions to save changes.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ResourceAutosaveProvider implements IAutosaveProvider {
|
|
29
|
+
readonly id = "remote-resource";
|
|
30
|
+
readonly priority = 20;
|
|
31
|
+
private entityActionFactory;
|
|
32
|
+
private resourceActionFactory;
|
|
33
|
+
constructor(config?: ResourceAutosaveProviderConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Check if this provider supports a given path.
|
|
36
|
+
* Returns true if the node has remote resource extension state.
|
|
37
|
+
*/
|
|
38
|
+
supports(_path: string[], node: FileSystemNode): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Save file content to remote server.
|
|
41
|
+
* Dispatches UPDATE_ENTITY (if entity) or RESOURCE_CALL_REQUEST (if resource).
|
|
42
|
+
*/
|
|
43
|
+
save(path: string[], content: unknown, node: FileSystemNode, dispatch: Dispatch<AnyAction>): Promise<AutosaveResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Cancel is a no-op for resources since we don't track in-flight requests here.
|
|
46
|
+
*/
|
|
47
|
+
cancel(_path: string[]): void;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=resource-autosave-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-autosave-provider.d.ts","sourceRoot":"","sources":["../../../src/impl/autosave/resource-autosave-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,4BAA4B;IAC5B,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C,8BAA8B;IAC9B,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,QAAQ,CAAC,EAAE,qBAAqB;IAChC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,qBAAqB,CAAwB;gBAEzC,MAAM,GAAE,8BAAmC;IAKvD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAKxD;;;OAGG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC;IAgE1B;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;CAG9B"}
|