@hamak/ui-store-impl 0.4.6 → 0.4.16
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 +9 -6
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-test.log +0 -115
- package/CHANGELOG.md +0 -41
- package/project.json +0 -24
- package/src/core/index.ts +0 -3
- package/src/core/middleware-registry.test.ts +0 -247
- package/src/core/middleware-registry.ts +0 -64
- package/src/core/reducer-registry.test.ts +0 -215
- package/src/core/reducer-registry.ts +0 -71
- package/src/core/store-manager.test.ts +0 -288
- package/src/core/store-manager.ts +0 -125
- package/src/extensions/store-extensions.ts +0 -90
- package/src/fs/commands/fs-commands.ts +0 -389
- package/src/fs/commands/structure-commands.ts +0 -105
- package/src/fs/core/fs-adapter.ts +0 -180
- package/src/fs/core/fs-facade.ts +0 -100
- package/src/fs/index.ts +0 -14
- package/src/fs/utils/data-updater.ts +0 -273
- package/src/fs/utils/deep-equal.ts +0 -35
- package/src/index.ts +0 -9
- package/src/middleware/event-bridge-middleware.test.ts +0 -131
- package/src/middleware/event-bridge-middleware.ts +0 -26
- package/src/middleware/index.ts +0 -6
- package/src/middleware/logger-middleware.test.ts +0 -129
- package/src/middleware/logger-middleware.ts +0 -25
- package/src/plugin/index.ts +0 -5
- package/src/plugin/store-plugin-factory.ts +0 -142
- package/tsconfig.es2015.json +0 -24
- package/tsconfig.json +0 -19
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hamak/ui-store-impl",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "UI Store Implementation - Redux store implementation with middleware",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"sideEffects": false,
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
10
13
|
"repository": {
|
|
11
14
|
"type": "git",
|
|
12
15
|
"url": "https://github.com/amah/app-framework.git",
|
|
@@ -34,11 +37,11 @@
|
|
|
34
37
|
}
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
37
|
-
"@hamak/shared-utils": "
|
|
38
|
-
"@hamak/ui-store-api": "
|
|
39
|
-
"@hamak/ui-store-spi": "
|
|
40
|
-
"@hamak/microkernel-api": "
|
|
41
|
-
"@hamak/microkernel-spi": "
|
|
40
|
+
"@hamak/shared-utils": "*",
|
|
41
|
+
"@hamak/ui-store-api": "*",
|
|
42
|
+
"@hamak/ui-store-spi": "*",
|
|
43
|
+
"@hamak/microkernel-api": "*",
|
|
44
|
+
"@hamak/microkernel-spi": "*",
|
|
42
45
|
"@reduxjs/toolkit": "^2.0.0",
|
|
43
46
|
"immer": "^10.0.0",
|
|
44
47
|
"redux": "^5.0.1",
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
$ tsc -p tsconfig.json && tsc -p tsconfig.es2015.json
|
package/.turbo/turbo-test.log
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
$ vitest run
|
|
2
|
-
|
|
3
|
-
RUN v2.1.9 /Users/amah/Devs/projects/app-framework/packages/ui-store/ui-store-impl
|
|
4
|
-
|
|
5
|
-
stderr | src/core/middleware-registry.test.ts > MiddlewareRegistry > register > should replace existing middleware with same id
|
|
6
|
-
[MiddlewareRegistry] Middleware "test-middleware" already registered, overwriting.
|
|
7
|
-
|
|
8
|
-
✓ src/core/middleware-registry.test.ts (20 tests) 16ms
|
|
9
|
-
stdout | src/core/store-manager.test.ts > StoreManager > initialization > should initialize store
|
|
10
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
11
|
-
|
|
12
|
-
stdout | src/core/store-manager.test.ts > StoreManager > initialization > should throw error when initializing twice
|
|
13
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
14
|
-
|
|
15
|
-
stdout | src/core/store-manager.test.ts > StoreManager > initialization > should lock middleware registry after initialization
|
|
16
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
17
|
-
|
|
18
|
-
stdout | src/core/store-manager.test.ts > StoreManager > middleware registration > should apply middleware in priority order
|
|
19
|
-
[StoreManager] Store initialized with: {
|
|
20
|
-
reducers: [],
|
|
21
|
-
middleware: [
|
|
22
|
-
{ id: 'high', priority: 100, plugin: undefined },
|
|
23
|
-
{ id: 'medium', priority: 50, plugin: undefined },
|
|
24
|
-
{ id: 'low', priority: 10, plugin: undefined }
|
|
25
|
-
],
|
|
26
|
-
devTools: true
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
stdout | src/core/store-manager.test.ts > StoreManager > reducer registration > should combine multiple reducers
|
|
30
|
-
[StoreManager] Store initialized with: { reducers: [ 'counter', 'name' ], middleware: [], devTools: true }
|
|
31
|
-
|
|
32
|
-
stdout | src/core/store-manager.test.ts > StoreManager > reducer registration > should support hot reducer replacement
|
|
33
|
-
[StoreManager] Store initialized with: { reducers: [ 'feature' ], middleware: [], devTools: true }
|
|
34
|
-
|
|
35
|
-
stdout | src/core/store-manager.test.ts > StoreManager > store operations > should dispatch actions
|
|
36
|
-
[StoreManager] Store initialized with: { reducers: [ 'counter' ], middleware: [], devTools: true }
|
|
37
|
-
|
|
38
|
-
stdout | src/core/store-manager.test.ts > StoreManager > store operations > should get state
|
|
39
|
-
[StoreManager] Store initialized with: { reducers: [ 'data' ], middleware: [], devTools: true }
|
|
40
|
-
|
|
41
|
-
stdout | src/core/store-manager.test.ts > StoreManager > store operations > should subscribe to changes
|
|
42
|
-
[StoreManager] Store initialized with: { reducers: [ 'counter' ], middleware: [], devTools: true }
|
|
43
|
-
|
|
44
|
-
stdout | src/core/store-manager.test.ts > StoreManager > store operations > should replace reducer
|
|
45
|
-
[StoreManager] Store initialized with: { reducers: [ 'data' ], middleware: [], devTools: true }
|
|
46
|
-
|
|
47
|
-
stdout | src/core/store-manager.test.ts > StoreManager > preloaded state > should initialize with preloaded state
|
|
48
|
-
[StoreManager] Store initialized with: { reducers: [ 'counter' ], middleware: [], devTools: true }
|
|
49
|
-
|
|
50
|
-
stdout | src/core/store-manager.test.ts > StoreManager > destroy > should destroy store
|
|
51
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
52
|
-
[StoreManager] Store destroyed
|
|
53
|
-
|
|
54
|
-
stdout | src/core/store-manager.test.ts > StoreManager > destroy > should allow re-initialization after destroy
|
|
55
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
56
|
-
[StoreManager] Store destroyed
|
|
57
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
58
|
-
|
|
59
|
-
stdout | src/core/store-manager.test.ts > StoreManager > DevTools configuration > should accept devTools configuration
|
|
60
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: false }
|
|
61
|
-
|
|
62
|
-
stdout | src/core/store-manager.test.ts > StoreManager > DevTools configuration > should accept enhancers
|
|
63
|
-
[StoreManager] Store initialized with: { reducers: [], middleware: [], devTools: true }
|
|
64
|
-
|
|
65
|
-
✓ src/core/store-manager.test.ts (19 tests) 229ms
|
|
66
|
-
stderr | src/core/reducer-registry.test.ts > ReducerRegistry > register > should warn when replacing without replace flag
|
|
67
|
-
[ReducerRegistry] Reducer "test" already registered. Use replace=true to override.
|
|
68
|
-
|
|
69
|
-
✓ src/core/reducer-registry.test.ts (19 tests) 130ms
|
|
70
|
-
stdout | src/middleware/logger-middleware.test.ts > createLoggerMiddleware > should log actions with type
|
|
71
|
-
[Redux] INCREMENT
|
|
72
|
-
Prev State: { count: 0 }
|
|
73
|
-
Action: { type: 'INCREMENT' }
|
|
74
|
-
Next State: { count: 1 }
|
|
75
|
-
|
|
76
|
-
stdout | src/middleware/logger-middleware.test.ts > createLoggerMiddleware > should pass action through middleware chain
|
|
77
|
-
[Redux] TEST
|
|
78
|
-
Prev State: {}
|
|
79
|
-
Action: { type: 'TEST' }
|
|
80
|
-
Next State: {}
|
|
81
|
-
|
|
82
|
-
stdout | src/middleware/logger-middleware.test.ts > createLoggerMiddleware > should return action result
|
|
83
|
-
[Redux] TEST
|
|
84
|
-
Prev State: {}
|
|
85
|
-
Action: { type: 'TEST', payload: 123 }
|
|
86
|
-
Next State: {}
|
|
87
|
-
|
|
88
|
-
stdout | src/middleware/logger-middleware.test.ts > createLoggerMiddleware > should log state before and after action
|
|
89
|
-
[Redux] SET_VALUE
|
|
90
|
-
Prev State: { value: 0 }
|
|
91
|
-
Action: { type: 'SET_VALUE', payload: 42 }
|
|
92
|
-
Next State: { value: 42 }
|
|
93
|
-
|
|
94
|
-
stdout | src/middleware/logger-middleware.test.ts > createLoggerMiddleware > should work with multiple actions
|
|
95
|
-
[Redux] INCREMENT
|
|
96
|
-
Prev State: { count: 0 }
|
|
97
|
-
Action: { type: 'INCREMENT' }
|
|
98
|
-
Next State: { count: 1 }
|
|
99
|
-
[Redux] INCREMENT
|
|
100
|
-
Prev State: { count: 1 }
|
|
101
|
-
Action: { type: 'INCREMENT' }
|
|
102
|
-
Next State: { count: 2 }
|
|
103
|
-
[Redux] DECREMENT
|
|
104
|
-
Prev State: { count: 2 }
|
|
105
|
-
Action: { type: 'DECREMENT' }
|
|
106
|
-
Next State: { count: 1 }
|
|
107
|
-
|
|
108
|
-
✓ src/middleware/logger-middleware.test.ts (8 tests) 160ms
|
|
109
|
-
✓ src/middleware/event-bridge-middleware.test.ts (8 tests) 73ms
|
|
110
|
-
|
|
111
|
-
Test Files 5 passed (5)
|
|
112
|
-
Tests 74 passed (74)
|
|
113
|
-
Start at 21:18:15
|
|
114
|
-
Duration 3.29s (transform 279ms, setup 0ms, collect 376ms, tests 608ms, environment 1ms, prepare 2.75s)
|
|
115
|
-
|
package/CHANGELOG.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
## 0.4.0 (2025-11-10)
|
|
2
|
-
|
|
3
|
-
### 🚀 Features
|
|
4
|
-
|
|
5
|
-
- implement notification plugin with UI and backend components ([c19ffcf](https://github.com/amah/app-framework/commit/c19ffcf))
|
|
6
|
-
- add ES2015 build support and fix TypeScript config for logging packages ([be5e45e](https://github.com/amah/app-framework/commit/be5e45e))
|
|
7
|
-
- complete logging system build and add optional console interception ([f390bc6](https://github.com/amah/app-framework/commit/f390bc6))
|
|
8
|
-
- implement core pluggable logging system (Phase 1) ([2abdc1a](https://github.com/amah/app-framework/commit/2abdc1a))
|
|
9
|
-
|
|
10
|
-
### 🩹 Fixes
|
|
11
|
-
|
|
12
|
-
- add notification packages to workspaces ([97a234d](https://github.com/amah/app-framework/commit/97a234d))
|
|
13
|
-
|
|
14
|
-
### ❤️ Thank You
|
|
15
|
-
|
|
16
|
-
- Amah
|
|
17
|
-
- Claude
|
|
18
|
-
|
|
19
|
-
## 0.3.0 (2025-11-06)
|
|
20
|
-
|
|
21
|
-
### 🚀 Features
|
|
22
|
-
|
|
23
|
-
- migrate from Turbo to Nx 22 with comprehensive monorepo setup ([e63801e](https://github.com/amah/app-framework/commit/e63801e))
|
|
24
|
-
- add Nx Release for automated dependency management ([01d474f](https://github.com/amah/app-framework/commit/01d474f))
|
|
25
|
-
- migrate from Turbo to Nx 22 monorepo orchestration ([d374271](https://github.com/amah/app-framework/commit/d374271))
|
|
26
|
-
- add configurable main padding and resizable sidebar to DashboardLayout ([c1d25bf](https://github.com/amah/app-framework/commit/c1d25bf))
|
|
27
|
-
- add debug logging and version management system ([ea514fc](https://github.com/amah/app-framework/commit/ea514fc))
|
|
28
|
-
- **ui-store:** add STORE_EXTENSIONS_TOKEN for DI-based middleware/reducer registration ([e855bdd](https://github.com/amah/app-framework/commit/e855bdd))
|
|
29
|
-
- Rename package scope from @amk to @hamak and configure npm publishing ([b6040b5](https://github.com/amah/app-framework/commit/b6040b5))
|
|
30
|
-
- Add hybrid local/CI-CD development workflow with bun link ([d09f528](https://github.com/amah/app-framework/commit/d09f528))
|
|
31
|
-
- Add Turborepo for intelligent build orchestration and fix test type errors ([ba41db8](https://github.com/amah/app-framework/commit/ba41db8))
|
|
32
|
-
- Add Redux store integration with ui-store package and demo ([e5aafa8](https://github.com/amah/app-framework/commit/e5aafa8))
|
|
33
|
-
|
|
34
|
-
### 🩹 Fixes
|
|
35
|
-
|
|
36
|
-
- move git config to top-level release.git in nx.json ([1bb2187](https://github.com/amah/app-framework/commit/1bb2187))
|
|
37
|
-
|
|
38
|
-
### ❤️ Thank You
|
|
39
|
-
|
|
40
|
-
- Amah
|
|
41
|
-
- Claude
|
package/project.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@hamak/ui-store-impl",
|
|
3
|
-
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/ui-store/ui-store-impl/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"targets": {
|
|
7
|
-
"build": {
|
|
8
|
-
"executor": "nx:run-commands",
|
|
9
|
-
"outputs": ["{projectRoot}/dist"],
|
|
10
|
-
"options": {
|
|
11
|
-
"command": "tsc -p tsconfig.json && tsc -p tsconfig.es2015.json",
|
|
12
|
-
"cwd": "{projectRoot}"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"clean": {
|
|
16
|
-
"executor": "nx:run-commands",
|
|
17
|
-
"options": {
|
|
18
|
-
"command": "rm -rf dist",
|
|
19
|
-
"cwd": "{projectRoot}"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"tags": ["type:library", "scope:ui-store"]
|
|
24
|
-
}
|
package/src/core/index.ts
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MiddlewareRegistry Tests
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, test, expect, beforeEach, vi } from 'vitest';
|
|
6
|
-
import { MiddlewareRegistry } from './middleware-registry';
|
|
7
|
-
import type { Middleware } from 'redux';
|
|
8
|
-
import type { MiddlewareRegistration } from '@hamak/ui-store-api';
|
|
9
|
-
|
|
10
|
-
describe('MiddlewareRegistry', () => {
|
|
11
|
-
let registry: MiddlewareRegistry;
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
registry = new MiddlewareRegistry();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe('register', () => {
|
|
18
|
-
test('should register middleware', () => {
|
|
19
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
20
|
-
const registration: MiddlewareRegistration = {
|
|
21
|
-
id: 'test-middleware',
|
|
22
|
-
middleware,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
registry.register(registration);
|
|
26
|
-
|
|
27
|
-
expect(registry.has('test-middleware')).toBe(true);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('should register middleware with default priority of 0', () => {
|
|
31
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
32
|
-
const registration: MiddlewareRegistration = {
|
|
33
|
-
id: 'test-middleware',
|
|
34
|
-
middleware,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
registry.register(registration);
|
|
38
|
-
const info = registry.getInfo('test-middleware');
|
|
39
|
-
|
|
40
|
-
expect(info?.priority).toBe(0);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('should register middleware with custom priority', () => {
|
|
44
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
45
|
-
const registration: MiddlewareRegistration = {
|
|
46
|
-
id: 'test-middleware',
|
|
47
|
-
middleware,
|
|
48
|
-
priority: 100,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
registry.register(registration);
|
|
52
|
-
const info = registry.getInfo('test-middleware');
|
|
53
|
-
|
|
54
|
-
expect(info?.priority).toBe(100);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('should throw error when registering after lock', () => {
|
|
58
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
59
|
-
const registration: MiddlewareRegistration = {
|
|
60
|
-
id: 'test-middleware',
|
|
61
|
-
middleware,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
registry.lock();
|
|
65
|
-
|
|
66
|
-
expect(() => registry.register(registration)).toThrow(
|
|
67
|
-
/Cannot register middleware.*store already created/
|
|
68
|
-
);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('should replace existing middleware with same id', () => {
|
|
72
|
-
const middleware1: Middleware = () => (next) => (action) => next(action);
|
|
73
|
-
const middleware2: Middleware = () => (next) => (action) => next(action);
|
|
74
|
-
|
|
75
|
-
registry.register({
|
|
76
|
-
id: 'test-middleware',
|
|
77
|
-
middleware: middleware1,
|
|
78
|
-
priority: 10,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
registry.register({
|
|
82
|
-
id: 'test-middleware',
|
|
83
|
-
middleware: middleware2,
|
|
84
|
-
priority: 20,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const info = registry.getInfo('test-middleware');
|
|
88
|
-
expect(info?.priority).toBe(20);
|
|
89
|
-
expect(info?.middleware).toBe(middleware2);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('unregister', () => {
|
|
94
|
-
test('should unregister middleware', () => {
|
|
95
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
96
|
-
registry.register({
|
|
97
|
-
id: 'test-middleware',
|
|
98
|
-
middleware,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
registry.unregister('test-middleware');
|
|
102
|
-
|
|
103
|
-
expect(registry.has('test-middleware')).toBe(false);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('should not throw when unregistering non-existent middleware', () => {
|
|
107
|
-
expect(() => registry.unregister('non-existent')).not.toThrow();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test('should throw error when unregistering after lock', () => {
|
|
111
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
112
|
-
registry.register({
|
|
113
|
-
id: 'test-middleware',
|
|
114
|
-
middleware,
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
registry.lock();
|
|
118
|
-
|
|
119
|
-
expect(() => registry.unregister('test-middleware')).toThrow(
|
|
120
|
-
/Cannot unregister middleware after store creation/
|
|
121
|
-
);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('getAll', () => {
|
|
126
|
-
test('should return empty array when no middleware registered', () => {
|
|
127
|
-
expect(registry.getAll()).toEqual([]);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test('should return all middleware in priority order (highest first)', () => {
|
|
131
|
-
const middleware1: Middleware = () => (next) => (action) => next(action);
|
|
132
|
-
const middleware2: Middleware = () => (next) => (action) => next(action);
|
|
133
|
-
const middleware3: Middleware = () => (next) => (action) => next(action);
|
|
134
|
-
|
|
135
|
-
registry.register({ id: 'low', middleware: middleware1, priority: 10 });
|
|
136
|
-
registry.register({ id: 'high', middleware: middleware2, priority: 100 });
|
|
137
|
-
registry.register({ id: 'medium', middleware: middleware3, priority: 50 });
|
|
138
|
-
|
|
139
|
-
const all = registry.getAll();
|
|
140
|
-
|
|
141
|
-
expect(all).toEqual([middleware2, middleware3, middleware1]);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
test('should handle middleware with same priority', () => {
|
|
145
|
-
const middleware1: Middleware = () => (next) => (action) => next(action);
|
|
146
|
-
const middleware2: Middleware = () => (next) => (action) => next(action);
|
|
147
|
-
|
|
148
|
-
registry.register({ id: 'first', middleware: middleware1, priority: 10 });
|
|
149
|
-
registry.register({ id: 'second', middleware: middleware2, priority: 10 });
|
|
150
|
-
|
|
151
|
-
const all = registry.getAll();
|
|
152
|
-
|
|
153
|
-
expect(all.length).toBe(2);
|
|
154
|
-
expect(all).toContain(middleware1);
|
|
155
|
-
expect(all).toContain(middleware2);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe('has', () => {
|
|
160
|
-
test('should return false for non-existent middleware', () => {
|
|
161
|
-
expect(registry.has('non-existent')).toBe(false);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
test('should return true for registered middleware', () => {
|
|
165
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
166
|
-
registry.register({ id: 'test', middleware });
|
|
167
|
-
|
|
168
|
-
expect(registry.has('test')).toBe(true);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('getInfo', () => {
|
|
173
|
-
test('should return undefined for non-existent middleware', () => {
|
|
174
|
-
expect(registry.getInfo('non-existent')).toBeUndefined();
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test('should return registration info for existing middleware', () => {
|
|
178
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
179
|
-
const registration: MiddlewareRegistration = {
|
|
180
|
-
id: 'test',
|
|
181
|
-
middleware,
|
|
182
|
-
priority: 100,
|
|
183
|
-
plugin: 'test-plugin',
|
|
184
|
-
description: 'Test middleware',
|
|
185
|
-
optional: true,
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
registry.register(registration);
|
|
189
|
-
const info = registry.getInfo('test');
|
|
190
|
-
|
|
191
|
-
expect(info).toEqual(registration);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('getAllRegistrations', () => {
|
|
196
|
-
test('should return empty array when no middleware registered', () => {
|
|
197
|
-
expect(registry.getAllRegistrations()).toEqual([]);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
test('should return all registrations', () => {
|
|
201
|
-
const middleware1: Middleware = () => (next) => (action) => next(action);
|
|
202
|
-
const middleware2: Middleware = () => (next) => (action) => next(action);
|
|
203
|
-
|
|
204
|
-
registry.register({ id: 'first', middleware: middleware1 });
|
|
205
|
-
registry.register({ id: 'second', middleware: middleware2 });
|
|
206
|
-
|
|
207
|
-
const registrations = registry.getAllRegistrations();
|
|
208
|
-
|
|
209
|
-
expect(registrations.length).toBe(2);
|
|
210
|
-
expect(registrations.map((r) => r.id)).toContain('first');
|
|
211
|
-
expect(registrations.map((r) => r.id)).toContain('second');
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('lock', () => {
|
|
216
|
-
test('should prevent further registration', () => {
|
|
217
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
218
|
-
|
|
219
|
-
registry.lock();
|
|
220
|
-
|
|
221
|
-
expect(() =>
|
|
222
|
-
registry.register({ id: 'test', middleware })
|
|
223
|
-
).toThrow();
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test('should prevent further unregistration', () => {
|
|
227
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
228
|
-
registry.register({ id: 'test', middleware });
|
|
229
|
-
|
|
230
|
-
registry.lock();
|
|
231
|
-
|
|
232
|
-
expect(() => registry.unregister('test')).toThrow();
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
test('should not affect read operations', () => {
|
|
236
|
-
const middleware: Middleware = () => (next) => (action) => next(action);
|
|
237
|
-
registry.register({ id: 'test', middleware });
|
|
238
|
-
|
|
239
|
-
registry.lock();
|
|
240
|
-
|
|
241
|
-
expect(registry.has('test')).toBe(true);
|
|
242
|
-
expect(registry.getInfo('test')).toBeDefined();
|
|
243
|
-
expect(registry.getAll().length).toBe(1);
|
|
244
|
-
expect(registry.getAllRegistrations().length).toBe(1);
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Middleware Registry Implementation
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { Middleware } from 'redux';
|
|
6
|
-
import type { IMiddlewareRegistry, MiddlewareRegistration } from '@hamak/ui-store-api';
|
|
7
|
-
|
|
8
|
-
export class MiddlewareRegistry implements IMiddlewareRegistry {
|
|
9
|
-
private registrations = new Map<string, MiddlewareRegistration>();
|
|
10
|
-
private locked = false;
|
|
11
|
-
|
|
12
|
-
register(registration: MiddlewareRegistration): void {
|
|
13
|
-
if (this.locked) {
|
|
14
|
-
throw new Error(
|
|
15
|
-
`Cannot register middleware "${registration.id}" - store already created. ` +
|
|
16
|
-
`Register middleware during plugin initialization phase.`
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (this.registrations.has(registration.id)) {
|
|
21
|
-
console.warn(`[MiddlewareRegistry] Middleware "${registration.id}" already registered, overwriting.`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this.registrations.set(registration.id, {
|
|
25
|
-
priority: 0,
|
|
26
|
-
...registration,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
unregister(id: string): void {
|
|
31
|
-
if (this.locked) {
|
|
32
|
-
throw new Error(`Cannot unregister middleware after store creation`);
|
|
33
|
-
}
|
|
34
|
-
this.registrations.delete(id);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
getAll(): Middleware[] {
|
|
38
|
-
const sorted = Array.from(this.registrations.values())
|
|
39
|
-
.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
40
|
-
|
|
41
|
-
return sorted.map(reg => reg.middleware);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
has(id: string): boolean {
|
|
45
|
-
return this.registrations.has(id);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getInfo(id: string): MiddlewareRegistration | undefined {
|
|
49
|
-
return this.registrations.get(id);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
getAllRegistrations(): MiddlewareRegistration[] {
|
|
53
|
-
return Array.from(this.registrations.values())
|
|
54
|
-
.sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Lock the registry (called when store is created)
|
|
59
|
-
* @internal
|
|
60
|
-
*/
|
|
61
|
-
lock(): void {
|
|
62
|
-
this.locked = true;
|
|
63
|
-
}
|
|
64
|
-
}
|