qdadm 0.27.0 → 0.28.0
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/package.json +1 -1
- package/src/composables/index.js +1 -0
- package/src/composables/useDeferred.js +85 -0
- package/src/composables/useListPageBuilder.js +3 -0
- package/src/deferred/DeferredRegistry.js +323 -0
- package/src/deferred/index.js +7 -0
- package/src/entity/EntityManager.js +82 -14
- package/src/entity/factory.js +155 -0
- package/src/entity/factory.test.js +189 -0
- package/src/entity/index.js +8 -0
- package/src/entity/storage/ApiStorage.js +4 -1
- package/src/entity/storage/IStorage.js +76 -0
- package/src/entity/storage/LocalStorage.js +4 -1
- package/src/entity/storage/MemoryStorage.js +4 -1
- package/src/entity/storage/MockApiStorage.js +4 -1
- package/src/entity/storage/SdkStorage.js +4 -1
- package/src/entity/storage/factory.js +193 -0
- package/src/entity/storage/factory.test.js +159 -0
- package/src/entity/storage/index.js +13 -0
- package/src/index.js +3 -0
- package/src/kernel/EventRouter.js +264 -0
- package/src/kernel/Kernel.js +123 -8
- package/src/kernel/index.js +4 -0
- package/src/orchestrator/Orchestrator.js +60 -0
- package/src/query/FilterQuery.js +9 -4
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manager Factory/Resolver Pattern
|
|
3
|
+
*
|
|
4
|
+
* Enables declarative manager configuration with auto-resolution.
|
|
5
|
+
* Works with storageFactory for complete auto-wiring.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```js
|
|
9
|
+
* // String pattern → factory creates manager with storage
|
|
10
|
+
* managerFactory('api:/api/bots', 'bots', context) // → EntityManager + ApiStorage
|
|
11
|
+
*
|
|
12
|
+
* // Config object → factory normalizes, resolver creates
|
|
13
|
+
* managerFactory({ storage: 'api:/api/bots', label: 'Bot' }, 'bots', context)
|
|
14
|
+
*
|
|
15
|
+
* // Manager instance → returned directly
|
|
16
|
+
* managerFactory(myManagerInstance, 'bots', context) // → myManagerInstance
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { EntityManager } from './EntityManager.js'
|
|
21
|
+
import { storageFactory } from './storage/factory.js'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default manager resolver - creates manager instance from config
|
|
25
|
+
*
|
|
26
|
+
* Override this via Kernel config for custom manager classes.
|
|
27
|
+
*
|
|
28
|
+
* @param {object} config - Normalized manager config with resolved storage
|
|
29
|
+
* @param {string} entityName - Entity name
|
|
30
|
+
* @param {object} context - Context with managerRegistry
|
|
31
|
+
* @returns {EntityManager} Manager instance
|
|
32
|
+
*/
|
|
33
|
+
export function defaultManagerResolver(config, entityName, context = {}) {
|
|
34
|
+
const { managerRegistry = {} } = context
|
|
35
|
+
|
|
36
|
+
// Look up registered manager class (e.g., from qdadm-gen)
|
|
37
|
+
const ManagerClass = managerRegistry[entityName] || EntityManager
|
|
38
|
+
|
|
39
|
+
// Ensure name is set
|
|
40
|
+
const managerConfig = {
|
|
41
|
+
name: entityName,
|
|
42
|
+
...config
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return new ManagerClass(managerConfig)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Manager factory - normalizes input and delegates to resolver
|
|
50
|
+
*
|
|
51
|
+
* Handles:
|
|
52
|
+
* - EntityManager instance → return directly
|
|
53
|
+
* - String pattern 'type:endpoint' → create storage, then manager
|
|
54
|
+
* - Config object → resolve storage, then manager
|
|
55
|
+
*
|
|
56
|
+
* @param {EntityManager | string | object} config - Manager config
|
|
57
|
+
* @param {string} entityName - Entity name
|
|
58
|
+
* @param {object} context - Context with storageFactory, storageResolver, managerResolver, managerRegistry
|
|
59
|
+
* @returns {EntityManager} Manager instance
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Instance passthrough
|
|
63
|
+
* managerFactory(myManager, 'bots', ctx) // → myManager
|
|
64
|
+
*
|
|
65
|
+
* // String pattern (shorthand for storage)
|
|
66
|
+
* managerFactory('api:/api/bots', 'bots', ctx) // → EntityManager + ApiStorage
|
|
67
|
+
*
|
|
68
|
+
* // Config object
|
|
69
|
+
* managerFactory({
|
|
70
|
+
* storage: 'api:/api/bots',
|
|
71
|
+
* label: 'Bot',
|
|
72
|
+
* fields: { name: { type: 'text' } }
|
|
73
|
+
* }, 'bots', ctx)
|
|
74
|
+
*/
|
|
75
|
+
export function managerFactory(config, entityName, context = {}) {
|
|
76
|
+
const {
|
|
77
|
+
storageResolver,
|
|
78
|
+
managerResolver = defaultManagerResolver
|
|
79
|
+
} = context
|
|
80
|
+
|
|
81
|
+
// Already a Manager instance → return directly
|
|
82
|
+
if (config instanceof EntityManager) {
|
|
83
|
+
return config
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Also check for duck-typed manager (has storage property or list/get methods)
|
|
87
|
+
if (config && typeof config === 'object' && config.storage && typeof config.list === 'function') {
|
|
88
|
+
return config
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// String pattern → treat as storage config, create default manager
|
|
92
|
+
if (typeof config === 'string') {
|
|
93
|
+
const storage = storageFactory(config, entityName, storageResolver)
|
|
94
|
+
return managerResolver({ storage }, entityName, context)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Config object → resolve storage first, then manager
|
|
98
|
+
if (config && typeof config === 'object') {
|
|
99
|
+
let resolvedConfig = { ...config }
|
|
100
|
+
|
|
101
|
+
// Resolve storage if provided as string/config
|
|
102
|
+
if (config.storage && !(config.storage instanceof Object && typeof config.storage.list === 'function')) {
|
|
103
|
+
resolvedConfig.storage = storageFactory(config.storage, entityName, storageResolver)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return managerResolver(resolvedConfig, entityName, context)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
throw new Error(`Invalid manager config for "${entityName}": ${typeof config}. Expected string, object, or Manager instance.`)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create a custom manager factory with context
|
|
114
|
+
*
|
|
115
|
+
* @param {object} context - Context with storageResolver, managerResolver, managerRegistry
|
|
116
|
+
* @returns {function} Manager factory with bound context
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* const myFactory = createManagerFactory({
|
|
120
|
+
* managerRegistry: { bots: BotManager },
|
|
121
|
+
* managerResolver: (config, name, ctx) => {
|
|
122
|
+
* // Custom logic
|
|
123
|
+
* return defaultManagerResolver(config, name, ctx)
|
|
124
|
+
* }
|
|
125
|
+
* })
|
|
126
|
+
*
|
|
127
|
+
* const botsManager = myFactory('api:/api/bots', 'bots')
|
|
128
|
+
*/
|
|
129
|
+
export function createManagerFactory(context) {
|
|
130
|
+
return (config, entityName) => managerFactory(config, entityName, context)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create all managers from a config object
|
|
135
|
+
*
|
|
136
|
+
* @param {object} managersConfig - { entityName: config, ... }
|
|
137
|
+
* @param {object} context - Factory context
|
|
138
|
+
* @returns {object} { entityName: managerInstance, ... }
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* const managers = createManagers({
|
|
142
|
+
* bots: 'api:/api/bots',
|
|
143
|
+
* tasks: { storage: 'api:/api/tasks', label: 'Task' },
|
|
144
|
+
* settings: new SettingsManager({...})
|
|
145
|
+
* }, { managerRegistry })
|
|
146
|
+
*/
|
|
147
|
+
export function createManagers(managersConfig, context = {}) {
|
|
148
|
+
const managers = {}
|
|
149
|
+
|
|
150
|
+
for (const [entityName, config] of Object.entries(managersConfig)) {
|
|
151
|
+
managers[entityName] = managerFactory(config, entityName, context)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return managers
|
|
155
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
managerFactory,
|
|
4
|
+
defaultManagerResolver,
|
|
5
|
+
createManagerFactory,
|
|
6
|
+
createManagers
|
|
7
|
+
} from './factory.js'
|
|
8
|
+
import { EntityManager } from './EntityManager.js'
|
|
9
|
+
import { ApiStorage } from './storage/ApiStorage.js'
|
|
10
|
+
import { MemoryStorage } from './storage/MemoryStorage.js'
|
|
11
|
+
|
|
12
|
+
describe('defaultManagerResolver', () => {
|
|
13
|
+
it('creates EntityManager with config', () => {
|
|
14
|
+
const storage = new MemoryStorage()
|
|
15
|
+
const config = { storage, label: 'Bot' }
|
|
16
|
+
|
|
17
|
+
const manager = defaultManagerResolver(config, 'bots')
|
|
18
|
+
|
|
19
|
+
expect(manager).toBeInstanceOf(EntityManager)
|
|
20
|
+
expect(manager.name).toBe('bots')
|
|
21
|
+
expect(manager.storage).toBe(storage)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('uses registered manager class from registry', () => {
|
|
25
|
+
class CustomManager extends EntityManager {}
|
|
26
|
+
const storage = new MemoryStorage()
|
|
27
|
+
const config = { storage }
|
|
28
|
+
const context = { managerRegistry: { bots: CustomManager } }
|
|
29
|
+
|
|
30
|
+
const manager = defaultManagerResolver(config, 'bots', context)
|
|
31
|
+
|
|
32
|
+
expect(manager).toBeInstanceOf(CustomManager)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('falls back to EntityManager when not in registry', () => {
|
|
36
|
+
const storage = new MemoryStorage()
|
|
37
|
+
const config = { storage }
|
|
38
|
+
const context = { managerRegistry: { other: class extends EntityManager {} } }
|
|
39
|
+
|
|
40
|
+
const manager = defaultManagerResolver(config, 'bots', context)
|
|
41
|
+
|
|
42
|
+
expect(manager).toBeInstanceOf(EntityManager)
|
|
43
|
+
expect(manager.constructor).toBe(EntityManager)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('managerFactory', () => {
|
|
48
|
+
it('returns EntityManager instance directly', () => {
|
|
49
|
+
const manager = new EntityManager({ name: 'test', storage: new MemoryStorage() })
|
|
50
|
+
const result = managerFactory(manager, 'test')
|
|
51
|
+
expect(result).toBe(manager)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('returns duck-typed manager directly', () => {
|
|
55
|
+
const duckManager = {
|
|
56
|
+
storage: new MemoryStorage(),
|
|
57
|
+
list: () => Promise.resolve({ items: [], total: 0 }),
|
|
58
|
+
get: () => Promise.resolve(null)
|
|
59
|
+
}
|
|
60
|
+
const result = managerFactory(duckManager, 'test')
|
|
61
|
+
expect(result).toBe(duckManager)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('creates manager from string pattern', () => {
|
|
65
|
+
const result = managerFactory('api:/api/bots', 'bots')
|
|
66
|
+
expect(result).toBeInstanceOf(EntityManager)
|
|
67
|
+
expect(result.storage).toBeInstanceOf(ApiStorage)
|
|
68
|
+
expect(result.storage.endpoint).toBe('/api/bots')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('creates manager from config object with storage string', () => {
|
|
72
|
+
const result = managerFactory({
|
|
73
|
+
storage: 'api:/api/tasks',
|
|
74
|
+
label: 'Task'
|
|
75
|
+
}, 'tasks')
|
|
76
|
+
|
|
77
|
+
expect(result).toBeInstanceOf(EntityManager)
|
|
78
|
+
expect(result.storage).toBeInstanceOf(ApiStorage)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('uses storage instance directly from config', () => {
|
|
82
|
+
const storage = new MemoryStorage()
|
|
83
|
+
const result = managerFactory({ storage }, 'items')
|
|
84
|
+
|
|
85
|
+
expect(result).toBeInstanceOf(EntityManager)
|
|
86
|
+
expect(result.storage).toBe(storage)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('uses custom storageResolver', () => {
|
|
90
|
+
const customStorage = new MemoryStorage()
|
|
91
|
+
const storageResolver = vi.fn().mockReturnValue(customStorage)
|
|
92
|
+
const context = { storageResolver }
|
|
93
|
+
|
|
94
|
+
const result = managerFactory('api:/test', 'test', context)
|
|
95
|
+
|
|
96
|
+
expect(storageResolver).toHaveBeenCalled()
|
|
97
|
+
expect(result.storage).toBe(customStorage)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('uses custom managerResolver', () => {
|
|
101
|
+
class CustomManager extends EntityManager {}
|
|
102
|
+
const managerResolver = vi.fn().mockImplementation((config, name) => {
|
|
103
|
+
return new CustomManager({ name, ...config })
|
|
104
|
+
})
|
|
105
|
+
const context = { managerResolver }
|
|
106
|
+
|
|
107
|
+
const result = managerFactory('api:/test', 'test', context)
|
|
108
|
+
|
|
109
|
+
expect(managerResolver).toHaveBeenCalled()
|
|
110
|
+
expect(result).toBeInstanceOf(CustomManager)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('uses managerRegistry for generated classes', () => {
|
|
114
|
+
class BotManager extends EntityManager {}
|
|
115
|
+
const context = { managerRegistry: { bots: BotManager } }
|
|
116
|
+
|
|
117
|
+
const result = managerFactory('api:/api/bots', 'bots', context)
|
|
118
|
+
|
|
119
|
+
expect(result).toBeInstanceOf(BotManager)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('throws for invalid config', () => {
|
|
123
|
+
expect(() => managerFactory(123, 'test'))
|
|
124
|
+
.toThrow('Invalid manager config')
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('createManagerFactory', () => {
|
|
129
|
+
it('creates factory with bound context', () => {
|
|
130
|
+
class CustomManager extends EntityManager {}
|
|
131
|
+
const context = { managerRegistry: { bots: CustomManager } }
|
|
132
|
+
const factory = createManagerFactory(context)
|
|
133
|
+
|
|
134
|
+
const result = factory('api:/api/bots', 'bots')
|
|
135
|
+
|
|
136
|
+
expect(result).toBeInstanceOf(CustomManager)
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe('createManagers', () => {
|
|
141
|
+
it('creates managers from config object', () => {
|
|
142
|
+
const config = {
|
|
143
|
+
bots: 'api:/api/bots',
|
|
144
|
+
tasks: { storage: 'memory:tasks', label: 'Task' }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const managers = createManagers(config)
|
|
148
|
+
|
|
149
|
+
expect(managers.bots).toBeInstanceOf(EntityManager)
|
|
150
|
+
expect(managers.bots.storage).toBeInstanceOf(ApiStorage)
|
|
151
|
+
expect(managers.tasks).toBeInstanceOf(EntityManager)
|
|
152
|
+
expect(managers.tasks.storage).toBeInstanceOf(MemoryStorage)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('uses context for all managers', () => {
|
|
156
|
+
class BotManager extends EntityManager {}
|
|
157
|
+
class TaskManager extends EntityManager {}
|
|
158
|
+
const context = {
|
|
159
|
+
managerRegistry: { bots: BotManager, tasks: TaskManager }
|
|
160
|
+
}
|
|
161
|
+
const config = {
|
|
162
|
+
bots: 'api:/api/bots',
|
|
163
|
+
tasks: 'api:/api/tasks'
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const managers = createManagers(config, context)
|
|
167
|
+
|
|
168
|
+
expect(managers.bots).toBeInstanceOf(BotManager)
|
|
169
|
+
expect(managers.tasks).toBeInstanceOf(TaskManager)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('passes through existing manager instances', () => {
|
|
173
|
+
const existingManager = new EntityManager({ name: 'existing', storage: new MemoryStorage() })
|
|
174
|
+
const config = {
|
|
175
|
+
bots: 'api:/api/bots',
|
|
176
|
+
existing: existingManager
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const managers = createManagers(config)
|
|
180
|
+
|
|
181
|
+
expect(managers.existing).toBe(existingManager)
|
|
182
|
+
expect(managers.bots).toBeInstanceOf(EntityManager)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('returns empty object for empty config', () => {
|
|
186
|
+
const managers = createManagers({})
|
|
187
|
+
expect(managers).toEqual({})
|
|
188
|
+
})
|
|
189
|
+
})
|
package/src/entity/index.js
CHANGED
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
// EntityManager
|
|
8
8
|
export { EntityManager, createEntityManager } from './EntityManager.js'
|
|
9
9
|
|
|
10
|
+
// Manager Factory
|
|
11
|
+
export {
|
|
12
|
+
managerFactory,
|
|
13
|
+
defaultManagerResolver,
|
|
14
|
+
createManagerFactory,
|
|
15
|
+
createManagers
|
|
16
|
+
} from './factory.js'
|
|
17
|
+
|
|
10
18
|
// Storage adapters
|
|
11
19
|
export * from './storage/index.js'
|
|
12
20
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IStorage } from './IStorage.js'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* ApiStorage - REST API storage adapter
|
|
3
5
|
*
|
|
@@ -20,7 +22,7 @@
|
|
|
20
22
|
* })
|
|
21
23
|
* ```
|
|
22
24
|
*/
|
|
23
|
-
export class ApiStorage {
|
|
25
|
+
export class ApiStorage extends IStorage {
|
|
24
26
|
/**
|
|
25
27
|
* Storage capabilities declaration.
|
|
26
28
|
* Describes what features this storage adapter supports.
|
|
@@ -44,6 +46,7 @@ export class ApiStorage {
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
constructor(options = {}) {
|
|
49
|
+
super()
|
|
47
50
|
const {
|
|
48
51
|
endpoint,
|
|
49
52
|
client = null,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IStorage - Base class for storage adapters
|
|
3
|
+
*
|
|
4
|
+
* Provides instanceof checking for storageFactory.
|
|
5
|
+
* All storage adapters should extend this class.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```js
|
|
9
|
+
* class MyStorage extends IStorage {
|
|
10
|
+
* static capabilities = { supportsTotal: true, ... }
|
|
11
|
+
* async list(params) { ... }
|
|
12
|
+
* async get(id) { ... }
|
|
13
|
+
* async create(data) { ... }
|
|
14
|
+
* async update(id, data) { ... }
|
|
15
|
+
* async delete(id) { ... }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class IStorage {
|
|
20
|
+
/**
|
|
21
|
+
* Default capabilities - override in subclass
|
|
22
|
+
* @type {import('./index.js').StorageCapabilities}
|
|
23
|
+
*/
|
|
24
|
+
static capabilities = {
|
|
25
|
+
supportsTotal: false,
|
|
26
|
+
supportsFilters: false,
|
|
27
|
+
supportsPagination: false,
|
|
28
|
+
supportsCaching: false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* List entities with optional filtering/pagination
|
|
33
|
+
* @param {object} params - Query parameters
|
|
34
|
+
* @returns {Promise<{items: Array, total?: number}>}
|
|
35
|
+
*/
|
|
36
|
+
async list(params = {}) {
|
|
37
|
+
throw new Error('list() not implemented')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get single entity by ID
|
|
42
|
+
* @param {string} id - Entity ID
|
|
43
|
+
* @returns {Promise<object|null>}
|
|
44
|
+
*/
|
|
45
|
+
async get(id) {
|
|
46
|
+
throw new Error('get() not implemented')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create new entity
|
|
51
|
+
* @param {object} data - Entity data
|
|
52
|
+
* @returns {Promise<object>} Created entity with ID
|
|
53
|
+
*/
|
|
54
|
+
async create(data) {
|
|
55
|
+
throw new Error('create() not implemented')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Update entity by ID
|
|
60
|
+
* @param {string} id - Entity ID
|
|
61
|
+
* @param {object} data - Updated data
|
|
62
|
+
* @returns {Promise<object>} Updated entity
|
|
63
|
+
*/
|
|
64
|
+
async update(id, data) {
|
|
65
|
+
throw new Error('update() not implemented')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Delete entity by ID
|
|
70
|
+
* @param {string} id - Entity ID
|
|
71
|
+
* @returns {Promise<void>}
|
|
72
|
+
*/
|
|
73
|
+
async delete(id) {
|
|
74
|
+
throw new Error('delete() not implemented')
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IStorage } from './IStorage.js'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* LocalStorage - Browser localStorage storage adapter
|
|
3
5
|
*
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
* })
|
|
18
20
|
* ```
|
|
19
21
|
*/
|
|
20
|
-
export class LocalStorage {
|
|
22
|
+
export class LocalStorage extends IStorage {
|
|
21
23
|
/**
|
|
22
24
|
* Storage capabilities declaration.
|
|
23
25
|
* Describes what features this storage adapter supports.
|
|
@@ -47,6 +49,7 @@ export class LocalStorage {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
constructor(options = {}) {
|
|
52
|
+
super()
|
|
50
53
|
const {
|
|
51
54
|
key,
|
|
52
55
|
idField = 'id',
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IStorage } from './IStorage.js'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* MemoryStorage - In-memory storage adapter
|
|
3
5
|
*
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
* })
|
|
18
20
|
* ```
|
|
19
21
|
*/
|
|
20
|
-
export class MemoryStorage {
|
|
22
|
+
export class MemoryStorage extends IStorage {
|
|
21
23
|
/**
|
|
22
24
|
* Storage capabilities declaration.
|
|
23
25
|
* Describes what features this storage adapter supports.
|
|
@@ -47,6 +49,7 @@ export class MemoryStorage {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
constructor(options = {}) {
|
|
52
|
+
super()
|
|
50
53
|
const {
|
|
51
54
|
idField = 'id',
|
|
52
55
|
generateId = () => Date.now().toString(36) + Math.random().toString(36).substr(2),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IStorage } from './IStorage.js'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* MockApiStorage - In-memory storage with localStorage persistence
|
|
3
5
|
*
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
*
|
|
19
21
|
* localStorage key pattern: mockapi_${entityName}_data
|
|
20
22
|
*/
|
|
21
|
-
export class MockApiStorage {
|
|
23
|
+
export class MockApiStorage extends IStorage {
|
|
22
24
|
/**
|
|
23
25
|
* Storage capabilities declaration.
|
|
24
26
|
* Describes what features this storage adapter supports.
|
|
@@ -48,6 +50,7 @@ export class MockApiStorage {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
constructor(options = {}) {
|
|
53
|
+
super()
|
|
51
54
|
const {
|
|
52
55
|
entityName,
|
|
53
56
|
idField = 'id',
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IStorage } from './IStorage.js'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* SdkStorage - hey-api SDK storage adapter
|
|
3
5
|
*
|
|
@@ -93,7 +95,7 @@
|
|
|
93
95
|
* })
|
|
94
96
|
* ```
|
|
95
97
|
*/
|
|
96
|
-
export class SdkStorage {
|
|
98
|
+
export class SdkStorage extends IStorage {
|
|
97
99
|
/**
|
|
98
100
|
* Storage capabilities declaration
|
|
99
101
|
* @type {import('./index.js').StorageCapabilities}
|
|
@@ -141,6 +143,7 @@ export class SdkStorage {
|
|
|
141
143
|
* @param {boolean} [options.clientSidePagination=false] - Enable client-side pagination for list()
|
|
142
144
|
*/
|
|
143
145
|
constructor(options = {}) {
|
|
146
|
+
super()
|
|
144
147
|
const {
|
|
145
148
|
sdk = null,
|
|
146
149
|
getSdk = null,
|