@hamak/ui-store-api 0.2.2 → 0.2.3

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.
@@ -1,2 +1 @@
1
-
2
- $ tsc -p tsconfig.json && tsc -p tsconfig.es2015.json
1
+ $ tsc -p tsconfig.json && tsc -p tsconfig.es2015.json
@@ -0,0 +1,12 @@
1
+ $ vitest run
2
+
3
+ RUN v2.1.9 /Users/amah/Devs/projects/app-framework/packages/ui-store/ui-store-api
4
+
5
+ ✓ src/types/extension-types.test.ts (7 tests) 6ms
6
+ ✓ src/tokens/service-tokens.test.ts (8 tests) 8ms
7
+
8
+ Test Files 2 passed (2)
9
+ Tests 15 passed (15)
10
+ Start at 21:18:14
11
+ Duration 1.81s (transform 109ms, setup 0ms, collect 217ms, tests 14ms, environment 0ms, prepare 938ms)
12
+
@@ -5,3 +5,4 @@
5
5
  export const STORE_MANAGER_TOKEN = Symbol('StoreManager');
6
6
  export const MIDDLEWARE_REGISTRY_TOKEN = Symbol('MiddlewareRegistry');
7
7
  export const REDUCER_REGISTRY_TOKEN = Symbol('ReducerRegistry');
8
+ export const STORE_EXTENSIONS_TOKEN = Symbol('StoreExtensions');
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Store extension types
3
+ */
4
+ export {};
@@ -4,3 +4,4 @@
4
4
  export * from './store-types';
5
5
  export * from './middleware-types';
6
6
  export * from './reducer-types';
7
+ export * from './extension-types';
@@ -5,4 +5,5 @@
5
5
  export declare const STORE_MANAGER_TOKEN: unique symbol;
6
6
  export declare const MIDDLEWARE_REGISTRY_TOKEN: unique symbol;
7
7
  export declare const REDUCER_REGISTRY_TOKEN: unique symbol;
8
+ export declare const STORE_EXTENSIONS_TOKEN: unique symbol;
8
9
  //# sourceMappingURL=service-tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-tokens.d.ts","sourceRoot":"","sources":["../../src/tokens/service-tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,mBAAmB,eAAyB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,eAA+B,CAAC;AACtE,eAAO,MAAM,sBAAsB,eAA4B,CAAC"}
1
+ {"version":3,"file":"service-tokens.d.ts","sourceRoot":"","sources":["../../src/tokens/service-tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,mBAAmB,eAAyB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,eAA+B,CAAC;AACtE,eAAO,MAAM,sBAAsB,eAA4B,CAAC;AAChE,eAAO,MAAM,sBAAsB,eAA4B,CAAC"}
@@ -5,3 +5,4 @@
5
5
  export const STORE_MANAGER_TOKEN = Symbol('StoreManager');
6
6
  export const MIDDLEWARE_REGISTRY_TOKEN = Symbol('MiddlewareRegistry');
7
7
  export const REDUCER_REGISTRY_TOKEN = Symbol('ReducerRegistry');
8
+ export const STORE_EXTENSIONS_TOKEN = Symbol('StoreExtensions');
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Store extension types
3
+ */
4
+ import type { Reducer } from 'redux';
5
+ import type { MiddlewareRegistration } from './middleware-types';
6
+ /**
7
+ * Middleware contribution matches registry entries
8
+ */
9
+ export type StoreMiddlewareExtension = MiddlewareRegistration;
10
+ /**
11
+ * Extension payload that mirrors store plugin config
12
+ */
13
+ export interface StorePluginExtensions {
14
+ middleware?: StoreMiddlewareExtension[];
15
+ reducers?: Record<string, Reducer>;
16
+ }
17
+ /**
18
+ * Registry exposed via STORE_EXTENSIONS_TOKEN
19
+ */
20
+ export interface StoreExtensionsRegistry {
21
+ register(source: string, extensions: StorePluginExtensions): void;
22
+ }
23
+ //# sourceMappingURL=extension-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-types.d.ts","sourceRoot":"","sources":["../../src/types/extension-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,wBAAwB,EAAE,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACnE"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Store extension types
3
+ */
4
+ export {};
@@ -4,4 +4,5 @@
4
4
  export * from './store-types';
5
5
  export * from './middleware-types';
6
6
  export * from './reducer-types';
7
+ export * from './extension-types';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
@@ -4,3 +4,4 @@
4
4
  export * from './store-types';
5
5
  export * from './middleware-types';
6
6
  export * from './reducer-types';
7
+ export * from './extension-types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hamak/ui-store-api",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "UI Store API - Redux store interfaces and contracts",
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Service Tokens Tests
3
+ */
4
+
5
+ import { describe, test, expect } from 'vitest';
6
+ import {
7
+ STORE_MANAGER_TOKEN,
8
+ MIDDLEWARE_REGISTRY_TOKEN,
9
+ REDUCER_REGISTRY_TOKEN,
10
+ STORE_EXTENSIONS_TOKEN,
11
+ } from './service-tokens';
12
+
13
+ describe('Service Tokens', () => {
14
+ describe('Token Definitions', () => {
15
+ test('STORE_MANAGER_TOKEN should be defined as symbol', () => {
16
+ expect(typeof STORE_MANAGER_TOKEN).toBe('symbol');
17
+ expect(STORE_MANAGER_TOKEN.toString()).toBe('Symbol(StoreManager)');
18
+ });
19
+
20
+ test('MIDDLEWARE_REGISTRY_TOKEN should be defined as symbol', () => {
21
+ expect(typeof MIDDLEWARE_REGISTRY_TOKEN).toBe('symbol');
22
+ expect(MIDDLEWARE_REGISTRY_TOKEN.toString()).toBe('Symbol(MiddlewareRegistry)');
23
+ });
24
+
25
+ test('REDUCER_REGISTRY_TOKEN should be defined as symbol', () => {
26
+ expect(typeof REDUCER_REGISTRY_TOKEN).toBe('symbol');
27
+ expect(REDUCER_REGISTRY_TOKEN.toString()).toBe('Symbol(ReducerRegistry)');
28
+ });
29
+
30
+ test('STORE_EXTENSIONS_TOKEN should be defined as symbol', () => {
31
+ expect(typeof STORE_EXTENSIONS_TOKEN).toBe('symbol');
32
+ expect(STORE_EXTENSIONS_TOKEN.toString()).toBe('Symbol(StoreExtensions)');
33
+ });
34
+ });
35
+
36
+ describe('Token Uniqueness', () => {
37
+ test('each token should be unique', () => {
38
+ const tokens = [
39
+ STORE_MANAGER_TOKEN,
40
+ MIDDLEWARE_REGISTRY_TOKEN,
41
+ REDUCER_REGISTRY_TOKEN,
42
+ STORE_EXTENSIONS_TOKEN,
43
+ ];
44
+
45
+ const uniqueTokens = new Set(tokens);
46
+ expect(uniqueTokens.size).toBe(tokens.length);
47
+ });
48
+
49
+ test('tokens should not equal each other', () => {
50
+ expect(STORE_MANAGER_TOKEN).not.toBe(MIDDLEWARE_REGISTRY_TOKEN);
51
+ expect(STORE_MANAGER_TOKEN).not.toBe(REDUCER_REGISTRY_TOKEN);
52
+ expect(STORE_MANAGER_TOKEN).not.toBe(STORE_EXTENSIONS_TOKEN);
53
+ expect(MIDDLEWARE_REGISTRY_TOKEN).not.toBe(REDUCER_REGISTRY_TOKEN);
54
+ expect(MIDDLEWARE_REGISTRY_TOKEN).not.toBe(STORE_EXTENSIONS_TOKEN);
55
+ expect(REDUCER_REGISTRY_TOKEN).not.toBe(STORE_EXTENSIONS_TOKEN);
56
+ });
57
+ });
58
+
59
+ describe('Token Usage', () => {
60
+ test('tokens should be usable as Map keys', () => {
61
+ const map = new Map();
62
+ map.set(STORE_MANAGER_TOKEN, 'store manager');
63
+ map.set(MIDDLEWARE_REGISTRY_TOKEN, 'middleware registry');
64
+ map.set(REDUCER_REGISTRY_TOKEN, 'reducer registry');
65
+ map.set(STORE_EXTENSIONS_TOKEN, 'store extensions');
66
+
67
+ expect(map.get(STORE_MANAGER_TOKEN)).toBe('store manager');
68
+ expect(map.get(MIDDLEWARE_REGISTRY_TOKEN)).toBe('middleware registry');
69
+ expect(map.get(REDUCER_REGISTRY_TOKEN)).toBe('reducer registry');
70
+ expect(map.get(STORE_EXTENSIONS_TOKEN)).toBe('store extensions');
71
+ expect(map.size).toBe(4);
72
+ });
73
+
74
+ test('tokens should be usable as object keys', () => {
75
+ const obj = {
76
+ [STORE_MANAGER_TOKEN]: 'store manager',
77
+ [MIDDLEWARE_REGISTRY_TOKEN]: 'middleware registry',
78
+ [REDUCER_REGISTRY_TOKEN]: 'reducer registry',
79
+ [STORE_EXTENSIONS_TOKEN]: 'store extensions',
80
+ };
81
+
82
+ expect(obj[STORE_MANAGER_TOKEN]).toBe('store manager');
83
+ expect(obj[MIDDLEWARE_REGISTRY_TOKEN]).toBe('middleware registry');
84
+ expect(obj[REDUCER_REGISTRY_TOKEN]).toBe('reducer registry');
85
+ expect(obj[STORE_EXTENSIONS_TOKEN]).toBe('store extensions');
86
+ });
87
+ });
88
+ });
@@ -6,3 +6,4 @@
6
6
  export const STORE_MANAGER_TOKEN = Symbol('StoreManager');
7
7
  export const MIDDLEWARE_REGISTRY_TOKEN = Symbol('MiddlewareRegistry');
8
8
  export const REDUCER_REGISTRY_TOKEN = Symbol('ReducerRegistry');
9
+ export const STORE_EXTENSIONS_TOKEN = Symbol('StoreExtensions');
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Extension Types Tests
3
+ */
4
+
5
+ import { describe, test, expect } from 'vitest';
6
+ import type {
7
+ StoreMiddlewareExtension,
8
+ StorePluginExtensions,
9
+ StoreExtensionsRegistry,
10
+ } from './extension-types';
11
+ import type { Middleware } from 'redux';
12
+
13
+ describe('Extension Types', () => {
14
+ describe('StorePluginExtensions', () => {
15
+ test('should accept middleware array', () => {
16
+ const middleware: Middleware = () => (next) => (action) => next(action);
17
+ const extensions: StorePluginExtensions = {
18
+ middleware: [
19
+ {
20
+ id: 'test',
21
+ middleware,
22
+ },
23
+ ],
24
+ };
25
+
26
+ expect(extensions.middleware).toBeDefined();
27
+ expect(extensions.middleware?.length).toBe(1);
28
+ });
29
+
30
+ test('should accept reducers record', () => {
31
+ const reducer = (state = {}) => state;
32
+ const extensions: StorePluginExtensions = {
33
+ reducers: {
34
+ testReducer: reducer,
35
+ },
36
+ };
37
+
38
+ expect(extensions.reducers).toBeDefined();
39
+ expect(extensions.reducers?.testReducer).toBe(reducer);
40
+ });
41
+
42
+ test('should accept both middleware and reducers', () => {
43
+ const middleware: Middleware = () => (next) => (action) => next(action);
44
+ const reducer = (state = {}) => state;
45
+ const extensions: StorePluginExtensions = {
46
+ middleware: [{ id: 'test', middleware }],
47
+ reducers: { testReducer: reducer },
48
+ };
49
+
50
+ expect(extensions.middleware).toBeDefined();
51
+ expect(extensions.reducers).toBeDefined();
52
+ });
53
+
54
+ test('should accept empty object', () => {
55
+ const extensions: StorePluginExtensions = {};
56
+
57
+ expect(extensions).toBeDefined();
58
+ expect(extensions.middleware).toBeUndefined();
59
+ expect(extensions.reducers).toBeUndefined();
60
+ });
61
+ });
62
+
63
+ describe('StoreExtensionsRegistry', () => {
64
+ test('should define register method signature', () => {
65
+ const mockRegistry: StoreExtensionsRegistry = {
66
+ register: (source: string, extensions: StorePluginExtensions) => {
67
+ expect(source).toBeDefined();
68
+ expect(extensions).toBeDefined();
69
+ },
70
+ };
71
+
72
+ mockRegistry.register('test-source', {});
73
+ });
74
+
75
+ test('should accept source and extensions', () => {
76
+ const middleware: Middleware = () => (next) => (action) => next(action);
77
+ const reducer = (state = {}) => state;
78
+
79
+ const mockRegistry: StoreExtensionsRegistry = {
80
+ register: (source: string, extensions: StorePluginExtensions) => {
81
+ expect(source).toBe('test-plugin');
82
+ expect(extensions.middleware?.length).toBe(1);
83
+ expect(extensions.reducers?.testReducer).toBe(reducer);
84
+ },
85
+ };
86
+
87
+ mockRegistry.register('test-plugin', {
88
+ middleware: [{ id: 'test', middleware }],
89
+ reducers: { testReducer: reducer },
90
+ });
91
+ });
92
+ });
93
+
94
+ describe('StoreMiddlewareExtension', () => {
95
+ test('should match MiddlewareRegistration structure', () => {
96
+ const middleware: Middleware = () => (next) => (action) => next(action);
97
+ const extension: StoreMiddlewareExtension = {
98
+ id: 'test-middleware',
99
+ middleware,
100
+ priority: 100,
101
+ };
102
+
103
+ expect(extension.id).toBe('test-middleware');
104
+ expect(extension.middleware).toBe(middleware);
105
+ expect(extension.priority).toBe(100);
106
+ });
107
+ });
108
+ });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Store extension types
3
+ */
4
+
5
+ import type { Reducer } from 'redux';
6
+ import type { MiddlewareRegistration } from './middleware-types';
7
+
8
+ /**
9
+ * Middleware contribution matches registry entries
10
+ */
11
+ export type StoreMiddlewareExtension = MiddlewareRegistration;
12
+
13
+ /**
14
+ * Extension payload that mirrors store plugin config
15
+ */
16
+ export interface StorePluginExtensions {
17
+ middleware?: StoreMiddlewareExtension[];
18
+ reducers?: Record<string, Reducer>;
19
+ }
20
+
21
+ /**
22
+ * Registry exposed via STORE_EXTENSIONS_TOKEN
23
+ */
24
+ export interface StoreExtensionsRegistry {
25
+ register(source: string, extensions: StorePluginExtensions): void;
26
+ }
@@ -5,3 +5,4 @@
5
5
  export * from './store-types';
6
6
  export * from './middleware-types';
7
7
  export * from './reducer-types';
8
+ export * from './extension-types';