@fjell/core 4.4.50 → 4.4.51
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 +3 -3
- package/src/AItemService.ts +0 -38
- package/src/Coordinate.ts +0 -35
- package/src/dictionary.ts +0 -84
- package/src/errors/ActionError.ts +0 -69
- package/src/errors/BusinessLogicError.ts +0 -24
- package/src/errors/DuplicateError.ts +0 -57
- package/src/errors/NotFoundError.ts +0 -24
- package/src/errors/PermissionError.ts +0 -31
- package/src/errors/ValidationError.ts +0 -27
- package/src/errors/index.ts +0 -7
- package/src/event/emitter.ts +0 -247
- package/src/event/events.ts +0 -178
- package/src/event/index.ts +0 -130
- package/src/event/matching.ts +0 -264
- package/src/event/subscription.ts +0 -181
- package/src/event/types.ts +0 -282
- package/src/index.ts +0 -70
- package/src/item/IFactory.ts +0 -122
- package/src/item/IQFactory.ts +0 -163
- package/src/item/IQUtils.ts +0 -392
- package/src/item/IUtils.ts +0 -40
- package/src/item/ItemQuery.ts +0 -88
- package/src/items.ts +0 -120
- package/src/key/KUtils.ts +0 -484
- package/src/keys.ts +0 -95
- package/src/logger.ts +0 -5
- package/src/operations/OperationContext.ts +0 -12
- package/src/operations/Operations.ts +0 -357
- package/src/operations/contained.ts +0 -134
- package/src/operations/errorEnhancer.ts +0 -204
- package/src/operations/index.ts +0 -2
- package/src/operations/methods.ts +0 -363
- package/src/operations/primary.ts +0 -101
- package/src/operations/specialized.ts +0 -71
- package/src/operations/wrappers/createActionWrapper.ts +0 -108
- package/src/operations/wrappers/createAllActionWrapper.ts +0 -109
- package/src/operations/wrappers/createAllFacetWrapper.ts +0 -98
- package/src/operations/wrappers/createAllWrapper.ts +0 -103
- package/src/operations/wrappers/createCreateWrapper.ts +0 -117
- package/src/operations/wrappers/createFacetWrapper.ts +0 -97
- package/src/operations/wrappers/createFindOneWrapper.ts +0 -105
- package/src/operations/wrappers/createFindWrapper.ts +0 -105
- package/src/operations/wrappers/createGetWrapper.ts +0 -96
- package/src/operations/wrappers/createOneWrapper.ts +0 -128
- package/src/operations/wrappers/createRemoveWrapper.ts +0 -91
- package/src/operations/wrappers/createUpdateWrapper.ts +0 -106
- package/src/operations/wrappers/createUpsertWrapper.ts +0 -108
- package/src/operations/wrappers/index.ts +0 -39
- package/src/operations/wrappers/types.ts +0 -63
- package/src/validation/ItemValidator.ts +0 -131
- package/src/validation/KeyValidator.ts +0 -365
- package/src/validation/LocationValidator.ts +0 -136
- package/src/validation/QueryValidator.ts +0 -250
- package/src/validation/index.ts +0 -32
- package/src/validation/types.ts +0 -45
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/core",
|
|
3
3
|
"description": "Core Item and Key Framework for Fjell",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.51",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"core",
|
|
7
7
|
"fjell"
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"docs:test": "cd docs && npm run test"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@fjell/logging": "^4.4.
|
|
44
|
+
"@fjell/logging": "^4.4.50",
|
|
45
45
|
"deepmerge": "^4.3.1",
|
|
46
46
|
"luxon": "^3.7.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/eslintrc": "^3.3.1",
|
|
50
50
|
"@eslint/js": "^9.32.0",
|
|
51
|
-
"@fjell/eslint-config": "^1.1.
|
|
51
|
+
"@fjell/eslint-config": "^1.1.28",
|
|
52
52
|
"@swc/core": "^1.13.2",
|
|
53
53
|
"@tsconfig/recommended": "^1.0.10",
|
|
54
54
|
"@types/luxon": "^3.6.2",
|
package/src/AItemService.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { AllItemTypeArrays } from "./keys";
|
|
2
|
-
|
|
3
|
-
export class AItemService<
|
|
4
|
-
S extends string,
|
|
5
|
-
L1 extends string,
|
|
6
|
-
L2 extends string = never,
|
|
7
|
-
L3 extends string = never,
|
|
8
|
-
L4 extends string = never,
|
|
9
|
-
L5 extends string = never
|
|
10
|
-
> {
|
|
11
|
-
|
|
12
|
-
private pkType: S;
|
|
13
|
-
private parentService: AItemService<L1, L2, L3, L4, L5, never> | null = null;
|
|
14
|
-
|
|
15
|
-
constructor(
|
|
16
|
-
pkType: S,
|
|
17
|
-
parentService?: AItemService<L1, L2, L3, L4, L5, never>,
|
|
18
|
-
) {
|
|
19
|
-
this.pkType = pkType;
|
|
20
|
-
if (parentService) {
|
|
21
|
-
this.parentService = parentService;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public getPkType = (): S => {
|
|
26
|
-
return this.pkType;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public getKeyTypes = (): AllItemTypeArrays<S, L1, L2, L3, L4, L5> => {
|
|
30
|
-
let keyTypes: readonly string[] = [this.getPkType()];
|
|
31
|
-
|
|
32
|
-
if (this.parentService) {
|
|
33
|
-
keyTypes = keyTypes.concat(this.parentService.getKeyTypes());
|
|
34
|
-
}
|
|
35
|
-
return keyTypes as AllItemTypeArrays<S, L1, L2, L3, L4, L5>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
}
|
package/src/Coordinate.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { ItemTypeArray } from "./keys";
|
|
2
|
-
import LibLogger from "./logger";
|
|
3
|
-
|
|
4
|
-
const logger = LibLogger.get("Coordinate");
|
|
5
|
-
|
|
6
|
-
export interface Coordinate<
|
|
7
|
-
S extends string,
|
|
8
|
-
L1 extends string = never,
|
|
9
|
-
L2 extends string = never,
|
|
10
|
-
L3 extends string = never,
|
|
11
|
-
L4 extends string = never,
|
|
12
|
-
L5 extends string = never,
|
|
13
|
-
> {
|
|
14
|
-
kta: ItemTypeArray<S, L1, L2, L3, L4, L5>;
|
|
15
|
-
scopes: string[];
|
|
16
|
-
toString: () => string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const createCoordinate = <
|
|
20
|
-
S extends string,
|
|
21
|
-
L1 extends string = never,
|
|
22
|
-
L2 extends string = never,
|
|
23
|
-
L3 extends string = never,
|
|
24
|
-
L4 extends string = never,
|
|
25
|
-
L5 extends string = never,
|
|
26
|
-
>(kta: ItemTypeArray<S, L1, L2, L3, L4, L5> | S, scopes: string[] = []): Coordinate<S, L1, L2, L3, L4, L5> => {
|
|
27
|
-
const ktArray = Array.isArray(kta) ? kta : [kta];
|
|
28
|
-
const toString = () => {
|
|
29
|
-
logger.debug("toString", { kta, scopes });
|
|
30
|
-
return `${ktArray.join(', ')} - ${scopes.join(', ')}`;
|
|
31
|
-
}
|
|
32
|
-
logger.debug("createCoordinate", { kta: ktArray, scopes, toString });
|
|
33
|
-
return { kta: ktArray as ItemTypeArray<S, L1, L2, L3, L4, L5>, scopes, toString };
|
|
34
|
-
}
|
|
35
|
-
|
package/src/dictionary.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import LibLogger from "./logger";
|
|
2
|
-
|
|
3
|
-
const logger = LibLogger.get("Dictionary");
|
|
4
|
-
|
|
5
|
-
interface DictionaryEntry<T, V> {
|
|
6
|
-
originalKey: T;
|
|
7
|
-
value: V;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class Dictionary<T, V> {
|
|
11
|
-
protected map: { [key: string]: DictionaryEntry<T, V> } = {}
|
|
12
|
-
protected hashFunction = (key: T) => JSON.stringify(key);
|
|
13
|
-
|
|
14
|
-
constructor(map?: { [key: string]: V }, hashFunction?: (key: T) => string) {
|
|
15
|
-
if (hashFunction) {
|
|
16
|
-
this.hashFunction = hashFunction
|
|
17
|
-
}
|
|
18
|
-
if (map) {
|
|
19
|
-
// Convert legacy map format to new format
|
|
20
|
-
Object.entries(map).forEach(([hashedKey, value]) => {
|
|
21
|
-
try {
|
|
22
|
-
// Try to parse the key if it looks like JSON
|
|
23
|
-
const originalKey = JSON.parse(hashedKey) as T;
|
|
24
|
-
this.map[hashedKey] = { originalKey, value };
|
|
25
|
-
} catch {
|
|
26
|
-
// If parsing fails, we can't recover the original key
|
|
27
|
-
logger.warning('Cannot recover original key from legacy map entry', { hashedKey });
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public set(key: T, item: V): void {
|
|
34
|
-
logger.trace('set', { key, item });
|
|
35
|
-
const hashedKey = this.hashFunction(key);
|
|
36
|
-
this.map[hashedKey] = { originalKey: key, value: item };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public get(key: T): V | null {
|
|
40
|
-
logger.trace('get', { key });
|
|
41
|
-
const hashedKey = this.hashFunction(key);
|
|
42
|
-
const entry = this.map[hashedKey];
|
|
43
|
-
// Check if entry exists AND the original key matches the requested key
|
|
44
|
-
return entry && this.keysEqual(entry.originalKey, key) ? entry.value : null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private keysEqual(key1: T, key2: T): boolean {
|
|
48
|
-
// For basic equality check - this works for primitives and object references
|
|
49
|
-
// For deep equality, users can provide a custom hash function that avoids collisions
|
|
50
|
-
return key1 === key2;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public delete(key: T): void {
|
|
54
|
-
logger.trace('delete', { key });
|
|
55
|
-
const hashedKey = this.hashFunction(key);
|
|
56
|
-
delete this.map[hashedKey];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public keys(): T[] {
|
|
60
|
-
return Object.values(this.map).map(entry => entry.originalKey);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public values(): V[] {
|
|
64
|
-
return Object.values(this.map).map(entry => entry.value);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public includesKey(key: T): boolean {
|
|
68
|
-
const hashedKey = this.hashFunction(key);
|
|
69
|
-
const entry = this.map[hashedKey];
|
|
70
|
-
return entry ? this.keysEqual(entry.originalKey, key) : false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
public clone(): Dictionary<T, V> {
|
|
74
|
-
const clonedMap: { [key: string]: V } = {};
|
|
75
|
-
Object.entries(this.map).forEach(([hashedKey, entry]) => {
|
|
76
|
-
clonedMap[hashedKey] = entry.value;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const clone = new Dictionary<T, V>(clonedMap, this.hashFunction);
|
|
80
|
-
// Copy the entries directly to preserve original keys
|
|
81
|
-
clone.map = Object.assign({}, this.map);
|
|
82
|
-
return clone;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
export interface ErrorInfo {
|
|
2
|
-
code: string;
|
|
3
|
-
message: string;
|
|
4
|
-
operation: {
|
|
5
|
-
type: 'get' | 'create' | 'update' | 'remove' | 'upsert' |
|
|
6
|
-
'all' | 'one' | 'find' | 'findOne' |
|
|
7
|
-
'action' | 'allAction' | 'facet' | 'allFacet';
|
|
8
|
-
name: string;
|
|
9
|
-
params: Record<string, any>;
|
|
10
|
-
};
|
|
11
|
-
context: {
|
|
12
|
-
itemType: string;
|
|
13
|
-
key?: {
|
|
14
|
-
primary?: string | number;
|
|
15
|
-
composite?: {
|
|
16
|
-
sk: string | number;
|
|
17
|
-
kta: string[];
|
|
18
|
-
locations?: Array<{ lk: string | number; kt: string }>;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
affectedItems?: Array<{
|
|
22
|
-
id: string | number;
|
|
23
|
-
type: string;
|
|
24
|
-
displayName?: string;
|
|
25
|
-
}>;
|
|
26
|
-
parentLocation?: {
|
|
27
|
-
id: string | number;
|
|
28
|
-
type: string;
|
|
29
|
-
};
|
|
30
|
-
requiredPermission?: string;
|
|
31
|
-
};
|
|
32
|
-
details?: {
|
|
33
|
-
validOptions?: string[];
|
|
34
|
-
suggestedAction?: string;
|
|
35
|
-
retryable?: boolean;
|
|
36
|
-
conflictingValue?: any;
|
|
37
|
-
expectedValue?: any;
|
|
38
|
-
};
|
|
39
|
-
technical?: {
|
|
40
|
-
timestamp: string;
|
|
41
|
-
requestId?: string;
|
|
42
|
-
stackTrace?: string;
|
|
43
|
-
cause?: any;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export class ActionError extends Error {
|
|
48
|
-
constructor(
|
|
49
|
-
public readonly errorInfo: ErrorInfo,
|
|
50
|
-
cause?: Error
|
|
51
|
-
) {
|
|
52
|
-
super(errorInfo.message);
|
|
53
|
-
this.name = 'ActionError';
|
|
54
|
-
this.cause = cause;
|
|
55
|
-
|
|
56
|
-
// Ensure timestamp is always set
|
|
57
|
-
if (!this.errorInfo.technical) {
|
|
58
|
-
this.errorInfo.technical = { timestamp: new Date().toISOString() };
|
|
59
|
-
}
|
|
60
|
-
if (!this.errorInfo.technical.timestamp) {
|
|
61
|
-
this.errorInfo.technical.timestamp = new Date().toISOString();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
toJSON(): ErrorInfo {
|
|
66
|
-
return this.errorInfo;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ActionError } from './ActionError';
|
|
2
|
-
|
|
3
|
-
export class BusinessLogicError extends ActionError {
|
|
4
|
-
constructor(
|
|
5
|
-
message: string,
|
|
6
|
-
suggestedAction?: string,
|
|
7
|
-
retryable: boolean = false
|
|
8
|
-
) {
|
|
9
|
-
super({
|
|
10
|
-
code: 'BUSINESS_LOGIC_ERROR',
|
|
11
|
-
message,
|
|
12
|
-
operation: { type: 'action', name: '', params: {} },
|
|
13
|
-
context: { itemType: '' },
|
|
14
|
-
details: {
|
|
15
|
-
suggestedAction,
|
|
16
|
-
retryable
|
|
17
|
-
},
|
|
18
|
-
technical: {
|
|
19
|
-
timestamp: new Date().toISOString()
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { ActionError } from './ActionError';
|
|
2
|
-
|
|
3
|
-
export class DuplicateError extends ActionError {
|
|
4
|
-
constructor(
|
|
5
|
-
message: string,
|
|
6
|
-
existingItemIdOrKey?: string | number | any,
|
|
7
|
-
duplicateField?: string
|
|
8
|
-
) {
|
|
9
|
-
// Extract ID and build key info
|
|
10
|
-
let existingItemId: string | number | null = null;
|
|
11
|
-
let keyInfo: any = null;
|
|
12
|
-
|
|
13
|
-
if (typeof existingItemIdOrKey === 'object' && existingItemIdOrKey !== null) {
|
|
14
|
-
// It's a key object - extract the primary key value and build proper key structure
|
|
15
|
-
existingItemId = existingItemIdOrKey.pk || existingItemIdOrKey.id || existingItemIdOrKey.primary || null;
|
|
16
|
-
|
|
17
|
-
// Build key info with primary field set
|
|
18
|
-
if (existingItemId !== null) {
|
|
19
|
-
keyInfo = {
|
|
20
|
-
primary: existingItemId,
|
|
21
|
-
...existingItemIdOrKey
|
|
22
|
-
};
|
|
23
|
-
} else {
|
|
24
|
-
keyInfo = existingItemIdOrKey;
|
|
25
|
-
}
|
|
26
|
-
} else if (typeof existingItemIdOrKey !== 'undefined') {
|
|
27
|
-
// It's a simple ID
|
|
28
|
-
existingItemId = existingItemIdOrKey;
|
|
29
|
-
keyInfo = { primary: existingItemId };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
super({
|
|
33
|
-
code: 'DUPLICATE_ERROR',
|
|
34
|
-
message,
|
|
35
|
-
operation: { type: 'create', name: '', params: {} },
|
|
36
|
-
context: {
|
|
37
|
-
itemType: '',
|
|
38
|
-
...(keyInfo && { key: keyInfo }),
|
|
39
|
-
...(existingItemId && {
|
|
40
|
-
affectedItems: [{
|
|
41
|
-
id: existingItemId,
|
|
42
|
-
type: '',
|
|
43
|
-
displayName: `Existing item with ${duplicateField || 'key'}`
|
|
44
|
-
}]
|
|
45
|
-
})
|
|
46
|
-
},
|
|
47
|
-
details: {
|
|
48
|
-
retryable: false,
|
|
49
|
-
conflictingValue: duplicateField
|
|
50
|
-
},
|
|
51
|
-
technical: {
|
|
52
|
-
timestamp: new Date().toISOString()
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ActionError } from './ActionError';
|
|
2
|
-
|
|
3
|
-
export class NotFoundError extends ActionError {
|
|
4
|
-
constructor(
|
|
5
|
-
message: string,
|
|
6
|
-
itemType: string,
|
|
7
|
-
key?: any
|
|
8
|
-
) {
|
|
9
|
-
super({
|
|
10
|
-
code: 'NOT_FOUND',
|
|
11
|
-
message,
|
|
12
|
-
operation: { type: 'get', name: '', params: {} },
|
|
13
|
-
context: {
|
|
14
|
-
itemType,
|
|
15
|
-
key: typeof key === 'object' ? key : { primary: key }
|
|
16
|
-
},
|
|
17
|
-
details: { retryable: false },
|
|
18
|
-
technical: {
|
|
19
|
-
timestamp: new Date().toISOString()
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { ActionError } from './ActionError';
|
|
2
|
-
|
|
3
|
-
export class PermissionError extends ActionError {
|
|
4
|
-
constructor(
|
|
5
|
-
message: string,
|
|
6
|
-
requiredPermission?: string,
|
|
7
|
-
currentPermissions?: string[]
|
|
8
|
-
) {
|
|
9
|
-
super({
|
|
10
|
-
code: 'PERMISSION_DENIED',
|
|
11
|
-
message,
|
|
12
|
-
operation: { type: 'action', name: '', params: {} },
|
|
13
|
-
context: {
|
|
14
|
-
itemType: '',
|
|
15
|
-
...(requiredPermission && { requiredPermission })
|
|
16
|
-
},
|
|
17
|
-
details: {
|
|
18
|
-
...(requiredPermission && {
|
|
19
|
-
suggestedAction: `Required permission: ${requiredPermission}`,
|
|
20
|
-
expectedValue: requiredPermission
|
|
21
|
-
}),
|
|
22
|
-
...(currentPermissions && { conflictingValue: currentPermissions }),
|
|
23
|
-
retryable: false
|
|
24
|
-
},
|
|
25
|
-
technical: {
|
|
26
|
-
timestamp: new Date().toISOString()
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ActionError } from './ActionError';
|
|
2
|
-
|
|
3
|
-
export class ValidationError extends ActionError {
|
|
4
|
-
constructor(
|
|
5
|
-
message: string,
|
|
6
|
-
validOptions?: string[],
|
|
7
|
-
suggestedAction?: string,
|
|
8
|
-
conflictingValue?: any
|
|
9
|
-
) {
|
|
10
|
-
super({
|
|
11
|
-
code: 'VALIDATION_ERROR',
|
|
12
|
-
message,
|
|
13
|
-
operation: { type: 'create', name: '', params: {} }, // Will be filled by wrapper
|
|
14
|
-
context: { itemType: '' }, // Will be filled by wrapper
|
|
15
|
-
details: {
|
|
16
|
-
validOptions,
|
|
17
|
-
suggestedAction,
|
|
18
|
-
retryable: true,
|
|
19
|
-
conflictingValue
|
|
20
|
-
},
|
|
21
|
-
technical: {
|
|
22
|
-
timestamp: new Date().toISOString()
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
package/src/errors/index.ts
DELETED
package/src/event/emitter.ts
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
import { ComKey, ItemTypeArray, LocKeyArray, PriKey } from '../keys';
|
|
2
|
-
import { Item } from '../items';
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4
|
-
import { ActionEvent, BaseEvent, CreateEvent, DeleteEvent, UpdateEvent } from './events';
|
|
5
|
-
import { Subscription, SubscriptionOptions } from './subscription';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Core EventEmitter interface that storage libraries implement.
|
|
9
|
-
* Each item type gets its own EventEmitter instance for full type safety.
|
|
10
|
-
* Libraries implement separate EventEmitters per item type (UserEventEmitter, MessageEventEmitter, etc.)
|
|
11
|
-
*/
|
|
12
|
-
export interface EventEmitter<
|
|
13
|
-
S extends string,
|
|
14
|
-
L1 extends string = never,
|
|
15
|
-
L2 extends string = never,
|
|
16
|
-
L3 extends string = never,
|
|
17
|
-
L4 extends string = never,
|
|
18
|
-
L5 extends string = never
|
|
19
|
-
> {
|
|
20
|
-
/**
|
|
21
|
-
* Emit a generic event with full control over event properties.
|
|
22
|
-
* Libraries can use this for custom events or when they need full control.
|
|
23
|
-
*/
|
|
24
|
-
emit(event: BaseEvent<S, L1, L2, L3, L4, L5>): Promise<void>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Emit a create event when an item is created.
|
|
28
|
-
* Convenience method that constructs a properly typed CreateEvent.
|
|
29
|
-
*/
|
|
30
|
-
emitCreate(
|
|
31
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
32
|
-
scopes: string[],
|
|
33
|
-
item: Item<S, L1, L2, L3, L4, L5>
|
|
34
|
-
): Promise<void>;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Emit an update event when an item is modified.
|
|
38
|
-
* Convenience method that constructs a properly typed UpdateEvent.
|
|
39
|
-
*/
|
|
40
|
-
emitUpdate(
|
|
41
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
42
|
-
scopes: string[],
|
|
43
|
-
changes: string[],
|
|
44
|
-
before?: Item<S, L1, L2, L3, L4, L5>,
|
|
45
|
-
after?: Item<S, L1, L2, L3, L4, L5>
|
|
46
|
-
): Promise<void>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Emit a delete event when an item is deleted.
|
|
50
|
-
* Convenience method that constructs a properly typed DeleteEvent.
|
|
51
|
-
*/
|
|
52
|
-
emitDelete(
|
|
53
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
54
|
-
scopes: string[],
|
|
55
|
-
item?: Item<S, L1, L2, L3, L4, L5>
|
|
56
|
-
): Promise<void>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Emit an action event when a custom action is performed.
|
|
60
|
-
* Convenience method that constructs a properly typed ActionEvent.
|
|
61
|
-
*/
|
|
62
|
-
emitAction(
|
|
63
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
64
|
-
scopes: string[],
|
|
65
|
-
actionName: string,
|
|
66
|
-
actionData?: Record<string, unknown>
|
|
67
|
-
): Promise<void>;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Create a scoped emitter that automatically includes the specified scopes.
|
|
71
|
-
* Libraries can use this to avoid passing scopes to every emit call.
|
|
72
|
-
*/
|
|
73
|
-
withScopes(scopes: string[]): ScopedEventEmitter<S, L1, L2, L3, L4, L5>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Scoped EventEmitter that automatically includes configured scopes.
|
|
78
|
-
* Convenience interface for libraries to avoid passing scopes repeatedly.
|
|
79
|
-
*/
|
|
80
|
-
export interface ScopedEventEmitter<
|
|
81
|
-
S extends string,
|
|
82
|
-
L1 extends string = never,
|
|
83
|
-
L2 extends string = never,
|
|
84
|
-
L3 extends string = never,
|
|
85
|
-
L4 extends string = never,
|
|
86
|
-
L5 extends string = never
|
|
87
|
-
> {
|
|
88
|
-
/** The scopes that will be automatically included in all events */
|
|
89
|
-
readonly scopes: string[];
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Emit a generic event with automatic scope inclusion.
|
|
93
|
-
* The event should omit scopes since they'll be added automatically.
|
|
94
|
-
*/
|
|
95
|
-
emit(event: Omit<BaseEvent<S, L1, L2, L3, L4, L5>, 'scopes'>): Promise<void>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Emit a create event with automatic scope inclusion.
|
|
99
|
-
*/
|
|
100
|
-
emitCreate(
|
|
101
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
102
|
-
item: Item<S, L1, L2, L3, L4, L5>
|
|
103
|
-
): Promise<void>;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Emit an update event with automatic scope inclusion.
|
|
107
|
-
*/
|
|
108
|
-
emitUpdate(
|
|
109
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
110
|
-
changes: string[],
|
|
111
|
-
before?: Item<S, L1, L2, L3, L4, L5>,
|
|
112
|
-
after?: Item<S, L1, L2, L3, L4, L5>
|
|
113
|
-
): Promise<void>;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Emit a delete event with automatic scope inclusion.
|
|
117
|
-
*/
|
|
118
|
-
emitDelete(
|
|
119
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
120
|
-
item?: Item<S, L1, L2, L3, L4, L5>
|
|
121
|
-
): Promise<void>;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Emit an action event with automatic scope inclusion.
|
|
125
|
-
*/
|
|
126
|
-
emitAction(
|
|
127
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
128
|
-
actionName: string,
|
|
129
|
-
actionData?: Record<string, unknown>
|
|
130
|
-
): Promise<void>;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* EventSubscriber interface for subscribing to and receiving events.
|
|
135
|
-
* Each item type gets its own EventSubscriber instance for full type safety.
|
|
136
|
-
*/
|
|
137
|
-
export interface EventSubscriber<
|
|
138
|
-
S extends string,
|
|
139
|
-
L1 extends string = never,
|
|
140
|
-
L2 extends string = never,
|
|
141
|
-
L3 extends string = never,
|
|
142
|
-
L4 extends string = never,
|
|
143
|
-
L5 extends string = never
|
|
144
|
-
> {
|
|
145
|
-
/**
|
|
146
|
-
* Subscribe to events using a full subscription object.
|
|
147
|
-
* Returns the subscription ID for later unsubscribing.
|
|
148
|
-
*/
|
|
149
|
-
subscribe(subscription: Omit<Subscription<S, L1, L2, L3, L4, L5>, 'id'>): Promise<string>;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Unsubscribe from events using the subscription ID.
|
|
153
|
-
*/
|
|
154
|
-
unsubscribe(subscriptionId: string): Promise<void>;
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Register a callback to be called when events are received.
|
|
158
|
-
* Multiple callbacks can be registered and they'll all be called.
|
|
159
|
-
*/
|
|
160
|
-
onEvent(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Remove a previously registered event callback.
|
|
164
|
-
*/
|
|
165
|
-
removeEventListener(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Convenience method to subscribe to a specific item.
|
|
169
|
-
* Automatically creates an ItemSubscription with the provided options.
|
|
170
|
-
*/
|
|
171
|
-
subscribeToItem(
|
|
172
|
-
key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,
|
|
173
|
-
options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>
|
|
174
|
-
): Promise<string>;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Convenience method to subscribe to a location.
|
|
178
|
-
* Automatically creates a LocationSubscription with the provided options.
|
|
179
|
-
*/
|
|
180
|
-
subscribeToLocation(
|
|
181
|
-
kta: ItemTypeArray<S, L1, L2, L3, L4, L5>,
|
|
182
|
-
location: LocKeyArray<L1, L2, L3, L4, L5>,
|
|
183
|
-
options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>
|
|
184
|
-
): Promise<string>;
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Get all currently active subscriptions.
|
|
188
|
-
* Useful for debugging and subscription management.
|
|
189
|
-
*/
|
|
190
|
-
getActiveSubscriptions(): Subscription<S, L1, L2, L3, L4, L5>[];
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Check if an event matches any active subscriptions.
|
|
194
|
-
* Used internally by libraries to determine if an event should be processed.
|
|
195
|
-
*/
|
|
196
|
-
matchesSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>): boolean;
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Check if an event matches a specific subscription.
|
|
200
|
-
* Used internally for subscription matching logic.
|
|
201
|
-
*/
|
|
202
|
-
matchesSpecificSubscription(
|
|
203
|
-
event: BaseEvent<S, L1, L2, L3, L4, L5>,
|
|
204
|
-
subscription: Subscription<S, L1, L2, L3, L4, L5>
|
|
205
|
-
): boolean;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Combined EventSystem interface that includes both emitter and subscriber.
|
|
210
|
-
* Libraries can implement this interface to provide both event emission and subscription.
|
|
211
|
-
*/
|
|
212
|
-
export interface EventSystem<
|
|
213
|
-
S extends string,
|
|
214
|
-
L1 extends string = never,
|
|
215
|
-
L2 extends string = never,
|
|
216
|
-
L3 extends string = never,
|
|
217
|
-
L4 extends string = never,
|
|
218
|
-
L5 extends string = never
|
|
219
|
-
> {
|
|
220
|
-
/** Event emitter for publishing events */
|
|
221
|
-
readonly emitter: EventEmitter<S, L1, L2, L3, L4, L5>;
|
|
222
|
-
|
|
223
|
-
/** Event subscriber for receiving events */
|
|
224
|
-
readonly subscriber: EventSubscriber<S, L1, L2, L3, L4, L5>;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Factory function type for creating EventSystems.
|
|
229
|
-
* Libraries implement this to create properly configured event systems.
|
|
230
|
-
*/
|
|
231
|
-
export type EventSystemFactory<
|
|
232
|
-
S extends string,
|
|
233
|
-
L1 extends string = never,
|
|
234
|
-
L2 extends string = never,
|
|
235
|
-
L3 extends string = never,
|
|
236
|
-
L4 extends string = never,
|
|
237
|
-
L5 extends string = never
|
|
238
|
-
> = (scopes: string[]) => EventSystem<S, L1, L2, L3, L4, L5>;
|
|
239
|
-
|
|
240
|
-
// Type aliases for common usage patterns in libraries
|
|
241
|
-
export type UserEventEmitter = EventEmitter<'User'>;
|
|
242
|
-
export type UserEventSubscriber = EventSubscriber<'User'>;
|
|
243
|
-
export type UserEventSystem = EventSystem<'User'>;
|
|
244
|
-
|
|
245
|
-
export type MessageEventEmitter<L1 extends string, L2 extends string> = EventEmitter<'Message', L1, L2>;
|
|
246
|
-
export type MessageEventSubscriber<L1 extends string, L2 extends string> = EventSubscriber<'Message', L1, L2>;
|
|
247
|
-
export type MessageEventSystem<L1 extends string, L2 extends string> = EventSystem<'Message', L1, L2>;
|