@fjell/core 4.4.48 → 4.4.50

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.
Files changed (94) hide show
  1. package/README.md +92 -0
  2. package/dist/Coordinate.d.ts +7 -0
  3. package/dist/errors/ActionError.d.ts +51 -0
  4. package/dist/errors/BusinessLogicError.d.ts +4 -0
  5. package/dist/errors/DuplicateError.d.ts +4 -0
  6. package/dist/errors/NotFoundError.d.ts +4 -0
  7. package/dist/errors/PermissionError.d.ts +4 -0
  8. package/dist/errors/ValidationError.d.ts +4 -0
  9. package/dist/errors/index.d.ts +6 -0
  10. package/dist/event/emitter.d.ts +140 -0
  11. package/dist/event/events.d.ts +81 -0
  12. package/dist/event/index.d.ts +38 -0
  13. package/dist/event/matching.d.ts +54 -0
  14. package/dist/event/subscription.d.ts +74 -0
  15. package/dist/event/types.d.ts +186 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.js +1584 -47
  18. package/dist/item/IUtils.d.ts +6 -3
  19. package/dist/operations/OperationContext.d.ts +10 -0
  20. package/dist/operations/Operations.d.ts +259 -0
  21. package/dist/operations/contained.d.ts +65 -0
  22. package/dist/operations/errorEnhancer.d.ts +79 -0
  23. package/dist/operations/index.d.ts +2 -0
  24. package/dist/operations/methods.d.ts +134 -0
  25. package/dist/operations/primary.d.ts +57 -0
  26. package/dist/operations/specialized.d.ts +41 -0
  27. package/dist/operations/wrappers/createActionWrapper.d.ts +28 -0
  28. package/dist/operations/wrappers/createAllActionWrapper.d.ts +28 -0
  29. package/dist/operations/wrappers/createAllFacetWrapper.d.ts +27 -0
  30. package/dist/operations/wrappers/createAllWrapper.d.ts +28 -0
  31. package/dist/operations/wrappers/createCreateWrapper.d.ts +28 -0
  32. package/dist/operations/wrappers/createFacetWrapper.d.ts +27 -0
  33. package/dist/operations/wrappers/createFindOneWrapper.d.ts +28 -0
  34. package/dist/operations/wrappers/createFindWrapper.d.ts +28 -0
  35. package/dist/operations/wrappers/createGetWrapper.d.ts +28 -0
  36. package/dist/operations/wrappers/createOneWrapper.d.ts +38 -0
  37. package/dist/operations/wrappers/createRemoveWrapper.d.ts +28 -0
  38. package/dist/operations/wrappers/createUpdateWrapper.d.ts +28 -0
  39. package/dist/operations/wrappers/createUpsertWrapper.d.ts +28 -0
  40. package/dist/operations/wrappers/index.d.ts +34 -0
  41. package/dist/operations/wrappers/types.d.ts +48 -0
  42. package/dist/validation/ItemValidator.d.ts +43 -0
  43. package/dist/validation/KeyValidator.d.ts +56 -0
  44. package/dist/validation/LocationValidator.d.ts +39 -0
  45. package/dist/validation/QueryValidator.d.ts +57 -0
  46. package/dist/validation/index.d.ts +15 -0
  47. package/dist/validation/index.js +501 -0
  48. package/dist/validation/types.d.ts +38 -0
  49. package/package.json +7 -2
  50. package/src/Coordinate.ts +35 -0
  51. package/src/errors/ActionError.ts +69 -0
  52. package/src/errors/BusinessLogicError.ts +24 -0
  53. package/src/errors/DuplicateError.ts +57 -0
  54. package/src/errors/NotFoundError.ts +24 -0
  55. package/src/errors/PermissionError.ts +31 -0
  56. package/src/errors/ValidationError.ts +27 -0
  57. package/src/errors/index.ts +7 -0
  58. package/src/event/emitter.ts +247 -0
  59. package/src/event/events.ts +178 -0
  60. package/src/event/index.ts +130 -0
  61. package/src/event/matching.ts +264 -0
  62. package/src/event/subscription.ts +181 -0
  63. package/src/event/types.ts +282 -0
  64. package/src/index.ts +57 -0
  65. package/src/item/IUtils.ts +9 -80
  66. package/src/operations/OperationContext.ts +12 -0
  67. package/src/operations/Operations.ts +357 -0
  68. package/src/operations/contained.ts +134 -0
  69. package/src/operations/errorEnhancer.ts +204 -0
  70. package/src/operations/index.ts +2 -0
  71. package/src/operations/methods.ts +363 -0
  72. package/src/operations/primary.ts +101 -0
  73. package/src/operations/specialized.ts +71 -0
  74. package/src/operations/wrappers/createActionWrapper.ts +108 -0
  75. package/src/operations/wrappers/createAllActionWrapper.ts +109 -0
  76. package/src/operations/wrappers/createAllFacetWrapper.ts +98 -0
  77. package/src/operations/wrappers/createAllWrapper.ts +103 -0
  78. package/src/operations/wrappers/createCreateWrapper.ts +117 -0
  79. package/src/operations/wrappers/createFacetWrapper.ts +97 -0
  80. package/src/operations/wrappers/createFindOneWrapper.ts +105 -0
  81. package/src/operations/wrappers/createFindWrapper.ts +105 -0
  82. package/src/operations/wrappers/createGetWrapper.ts +96 -0
  83. package/src/operations/wrappers/createOneWrapper.ts +128 -0
  84. package/src/operations/wrappers/createRemoveWrapper.ts +91 -0
  85. package/src/operations/wrappers/createUpdateWrapper.ts +106 -0
  86. package/src/operations/wrappers/createUpsertWrapper.ts +108 -0
  87. package/src/operations/wrappers/index.ts +39 -0
  88. package/src/operations/wrappers/types.ts +63 -0
  89. package/src/validation/ItemValidator.ts +131 -0
  90. package/src/validation/KeyValidator.ts +365 -0
  91. package/src/validation/LocationValidator.ts +136 -0
  92. package/src/validation/QueryValidator.ts +250 -0
  93. package/src/validation/index.ts +32 -0
  94. package/src/validation/types.ts +45 -0
package/README.md CHANGED
@@ -109,6 +109,98 @@ const query = IQFactory.create('user')
109
109
  const results = await IQUtils.execute(query)
110
110
  ```
111
111
 
112
+ ### Operations Interface
113
+
114
+ @fjell/core provides the standard Operations interface used across all fjell libraries. This interface defines the contract for working with Items:
115
+
116
+ ```typescript
117
+ import { Operations, PrimaryOperations, ContainedOperations } from '@fjell/core';
118
+
119
+ // For primary items
120
+ const userOps: PrimaryOperations<User, 'user'> = ...;
121
+
122
+ // For contained items
123
+ const commentOps: ContainedOperations<Comment, 'comment', 'post'> = ...;
124
+ ```
125
+
126
+ See [Operations README](src/operations/README.md) for detailed documentation.
127
+
128
+ ### Validation Module
129
+
130
+ @fjell/core provides centralized validation functions for ensuring data integrity across the Fjell ecosystem:
131
+
132
+ ```typescript
133
+ import {
134
+ validateLocations,
135
+ validateKey,
136
+ validatePK,
137
+ validateKeys
138
+ } from '@fjell/core/validation';
139
+ ```
140
+
141
+ #### Location Validation
142
+
143
+ Validates that location key arrays match the expected coordinate hierarchy:
144
+
145
+ ```typescript
146
+ import { validateLocations } from '@fjell/core/validation';
147
+
148
+ // Validate location array order
149
+ validateLocations(
150
+ [{ kt: 'store', lk: 'store-1' }],
151
+ coordinate,
152
+ 'create' // operation name for error context
153
+ );
154
+
155
+ // Non-throwing validation
156
+ import { isValidLocations } from '@fjell/core/validation';
157
+ const result = isValidLocations(
158
+ [{ kt: 'store', lk: 'store-1' }],
159
+ coordinate,
160
+ 'create'
161
+ );
162
+ if (!result.valid) {
163
+ console.log(result.error); // Validation error message
164
+ }
165
+ ```
166
+
167
+ #### Key Validation
168
+
169
+ Validates PriKey and ComKey structures match library type:
170
+
171
+ ```typescript
172
+ import { validateKey, validatePriKey, validateComKey } from '@fjell/core/validation';
173
+
174
+ // Validate any key type
175
+ validateKey(key, coordinate, 'get');
176
+
177
+ // Validate specific key types
178
+ validatePriKey(priKey, coordinate, 'update');
179
+ validateComKey(comKey, coordinate, 'remove');
180
+ ```
181
+
182
+ #### Item Validation
183
+
184
+ Validates Item keys match expected types:
185
+
186
+ ```typescript
187
+ import { validatePK, validateKeys } from '@fjell/core/validation';
188
+
189
+ // Validate item has correct primary key type
190
+ const validatedItem = validatePK(item, 'product');
191
+
192
+ // Validate item key types match key type array
193
+ const validatedItem = validateKeys(item, ['product', 'store']);
194
+ ```
195
+
196
+ **Features:**
197
+ - **Comprehensive Error Messages**: Detailed context including operation name, expected vs actual values
198
+ - **Type Safety**: Full TypeScript support with proper type inference
199
+ - **Performance**: Optimized O(n) validation with minimal overhead
200
+ - **Flexible**: Both throwing and non-throwing variants available
201
+
202
+ See [Validation Examples](examples/validation-example.ts) for detailed usage patterns.
203
+
112
204
  ## Architecture Philosophy
113
205
 
114
206
  Fjell Core is designed around **progressive enhancement**:
@@ -0,0 +1,7 @@
1
+ import type { ItemTypeArray } from "./keys";
2
+ export interface Coordinate<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
3
+ kta: ItemTypeArray<S, L1, L2, L3, L4, L5>;
4
+ scopes: string[];
5
+ toString: () => string;
6
+ }
7
+ export declare const createCoordinate: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(kta: ItemTypeArray<S, L1, L2, L3, L4, L5> | S, scopes?: string[]) => Coordinate<S, L1, L2, L3, L4, L5>;
@@ -0,0 +1,51 @@
1
+ export interface ErrorInfo {
2
+ code: string;
3
+ message: string;
4
+ operation: {
5
+ type: 'get' | 'create' | 'update' | 'remove' | 'upsert' | 'all' | 'one' | 'find' | 'findOne' | 'action' | 'allAction' | 'facet' | 'allFacet';
6
+ name: string;
7
+ params: Record<string, any>;
8
+ };
9
+ context: {
10
+ itemType: string;
11
+ key?: {
12
+ primary?: string | number;
13
+ composite?: {
14
+ sk: string | number;
15
+ kta: string[];
16
+ locations?: Array<{
17
+ lk: string | number;
18
+ kt: string;
19
+ }>;
20
+ };
21
+ };
22
+ affectedItems?: Array<{
23
+ id: string | number;
24
+ type: string;
25
+ displayName?: string;
26
+ }>;
27
+ parentLocation?: {
28
+ id: string | number;
29
+ type: string;
30
+ };
31
+ requiredPermission?: string;
32
+ };
33
+ details?: {
34
+ validOptions?: string[];
35
+ suggestedAction?: string;
36
+ retryable?: boolean;
37
+ conflictingValue?: any;
38
+ expectedValue?: any;
39
+ };
40
+ technical?: {
41
+ timestamp: string;
42
+ requestId?: string;
43
+ stackTrace?: string;
44
+ cause?: any;
45
+ };
46
+ }
47
+ export declare class ActionError extends Error {
48
+ readonly errorInfo: ErrorInfo;
49
+ constructor(errorInfo: ErrorInfo, cause?: Error);
50
+ toJSON(): ErrorInfo;
51
+ }
@@ -0,0 +1,4 @@
1
+ import { ActionError } from './ActionError';
2
+ export declare class BusinessLogicError extends ActionError {
3
+ constructor(message: string, suggestedAction?: string, retryable?: boolean);
4
+ }
@@ -0,0 +1,4 @@
1
+ import { ActionError } from './ActionError';
2
+ export declare class DuplicateError extends ActionError {
3
+ constructor(message: string, existingItemIdOrKey?: string | number | any, duplicateField?: string);
4
+ }
@@ -0,0 +1,4 @@
1
+ import { ActionError } from './ActionError';
2
+ export declare class NotFoundError extends ActionError {
3
+ constructor(message: string, itemType: string, key?: any);
4
+ }
@@ -0,0 +1,4 @@
1
+ import { ActionError } from './ActionError';
2
+ export declare class PermissionError extends ActionError {
3
+ constructor(message: string, requiredPermission?: string, currentPermissions?: string[]);
4
+ }
@@ -0,0 +1,4 @@
1
+ import { ActionError } from './ActionError';
2
+ export declare class ValidationError extends ActionError {
3
+ constructor(message: string, validOptions?: string[], suggestedAction?: string, conflictingValue?: any);
4
+ }
@@ -0,0 +1,6 @@
1
+ export * from './ActionError';
2
+ export * from './ValidationError';
3
+ export * from './NotFoundError';
4
+ export * from './BusinessLogicError';
5
+ export * from './PermissionError';
6
+ export * from './DuplicateError';
@@ -0,0 +1,140 @@
1
+ import { ComKey, ItemTypeArray, LocKeyArray, PriKey } from '../keys';
2
+ import { Item } from '../items';
3
+ import { BaseEvent } from './events';
4
+ import { Subscription, SubscriptionOptions } from './subscription';
5
+ /**
6
+ * Core EventEmitter interface that storage libraries implement.
7
+ * Each item type gets its own EventEmitter instance for full type safety.
8
+ * Libraries implement separate EventEmitters per item type (UserEventEmitter, MessageEventEmitter, etc.)
9
+ */
10
+ export interface EventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
11
+ /**
12
+ * Emit a generic event with full control over event properties.
13
+ * Libraries can use this for custom events or when they need full control.
14
+ */
15
+ emit(event: BaseEvent<S, L1, L2, L3, L4, L5>): Promise<void>;
16
+ /**
17
+ * Emit a create event when an item is created.
18
+ * Convenience method that constructs a properly typed CreateEvent.
19
+ */
20
+ emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
21
+ /**
22
+ * Emit an update event when an item is modified.
23
+ * Convenience method that constructs a properly typed UpdateEvent.
24
+ */
25
+ emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
26
+ /**
27
+ * Emit a delete event when an item is deleted.
28
+ * Convenience method that constructs a properly typed DeleteEvent.
29
+ */
30
+ emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
31
+ /**
32
+ * Emit an action event when a custom action is performed.
33
+ * Convenience method that constructs a properly typed ActionEvent.
34
+ */
35
+ emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], actionName: string, actionData?: Record<string, unknown>): Promise<void>;
36
+ /**
37
+ * Create a scoped emitter that automatically includes the specified scopes.
38
+ * Libraries can use this to avoid passing scopes to every emit call.
39
+ */
40
+ withScopes(scopes: string[]): ScopedEventEmitter<S, L1, L2, L3, L4, L5>;
41
+ }
42
+ /**
43
+ * Scoped EventEmitter that automatically includes configured scopes.
44
+ * Convenience interface for libraries to avoid passing scopes repeatedly.
45
+ */
46
+ export interface ScopedEventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
47
+ /** The scopes that will be automatically included in all events */
48
+ readonly scopes: string[];
49
+ /**
50
+ * Emit a generic event with automatic scope inclusion.
51
+ * The event should omit scopes since they'll be added automatically.
52
+ */
53
+ emit(event: Omit<BaseEvent<S, L1, L2, L3, L4, L5>, 'scopes'>): Promise<void>;
54
+ /**
55
+ * Emit a create event with automatic scope inclusion.
56
+ */
57
+ emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
58
+ /**
59
+ * Emit an update event with automatic scope inclusion.
60
+ */
61
+ emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
62
+ /**
63
+ * Emit a delete event with automatic scope inclusion.
64
+ */
65
+ emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
66
+ /**
67
+ * Emit an action event with automatic scope inclusion.
68
+ */
69
+ emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, actionName: string, actionData?: Record<string, unknown>): Promise<void>;
70
+ }
71
+ /**
72
+ * EventSubscriber interface for subscribing to and receiving events.
73
+ * Each item type gets its own EventSubscriber instance for full type safety.
74
+ */
75
+ export interface EventSubscriber<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
76
+ /**
77
+ * Subscribe to events using a full subscription object.
78
+ * Returns the subscription ID for later unsubscribing.
79
+ */
80
+ subscribe(subscription: Omit<Subscription<S, L1, L2, L3, L4, L5>, 'id'>): Promise<string>;
81
+ /**
82
+ * Unsubscribe from events using the subscription ID.
83
+ */
84
+ unsubscribe(subscriptionId: string): Promise<void>;
85
+ /**
86
+ * Register a callback to be called when events are received.
87
+ * Multiple callbacks can be registered and they'll all be called.
88
+ */
89
+ onEvent(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
90
+ /**
91
+ * Remove a previously registered event callback.
92
+ */
93
+ removeEventListener(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
94
+ /**
95
+ * Convenience method to subscribe to a specific item.
96
+ * Automatically creates an ItemSubscription with the provided options.
97
+ */
98
+ subscribeToItem(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>;
99
+ /**
100
+ * Convenience method to subscribe to a location.
101
+ * Automatically creates a LocationSubscription with the provided options.
102
+ */
103
+ subscribeToLocation(kta: ItemTypeArray<S, L1, L2, L3, L4, L5>, location: LocKeyArray<L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>;
104
+ /**
105
+ * Get all currently active subscriptions.
106
+ * Useful for debugging and subscription management.
107
+ */
108
+ getActiveSubscriptions(): Subscription<S, L1, L2, L3, L4, L5>[];
109
+ /**
110
+ * Check if an event matches any active subscriptions.
111
+ * Used internally by libraries to determine if an event should be processed.
112
+ */
113
+ matchesSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>): boolean;
114
+ /**
115
+ * Check if an event matches a specific subscription.
116
+ * Used internally for subscription matching logic.
117
+ */
118
+ matchesSpecificSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>, subscription: Subscription<S, L1, L2, L3, L4, L5>): boolean;
119
+ }
120
+ /**
121
+ * Combined EventSystem interface that includes both emitter and subscriber.
122
+ * Libraries can implement this interface to provide both event emission and subscription.
123
+ */
124
+ export interface EventSystem<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
125
+ /** Event emitter for publishing events */
126
+ readonly emitter: EventEmitter<S, L1, L2, L3, L4, L5>;
127
+ /** Event subscriber for receiving events */
128
+ readonly subscriber: EventSubscriber<S, L1, L2, L3, L4, L5>;
129
+ }
130
+ /**
131
+ * Factory function type for creating EventSystems.
132
+ * Libraries implement this to create properly configured event systems.
133
+ */
134
+ export type EventSystemFactory<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = (scopes: string[]) => EventSystem<S, L1, L2, L3, L4, L5>;
135
+ export type UserEventEmitter = EventEmitter<'User'>;
136
+ export type UserEventSubscriber = EventSubscriber<'User'>;
137
+ export type UserEventSystem = EventSystem<'User'>;
138
+ export type MessageEventEmitter<L1 extends string, L2 extends string> = EventEmitter<'Message', L1, L2>;
139
+ export type MessageEventSubscriber<L1 extends string, L2 extends string> = EventSubscriber<'Message', L1, L2>;
140
+ export type MessageEventSystem<L1 extends string, L2 extends string> = EventSystem<'Message', L1, L2>;
@@ -0,0 +1,81 @@
1
+ import { ComKey, PriKey } from '../keys';
2
+ import { Item } from '../items';
3
+ /**
4
+ * Base event interface that all events extend.
5
+ * Provides core event properties with full type safety using the existing PriKey/ComKey system.
6
+ */
7
+ export interface BaseEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
8
+ /** Type of event - "create", "update", "delete", etc. */
9
+ eventType: string;
10
+ /** The key of the item that was affected - maintains full type safety */
11
+ key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>;
12
+ /** Which storage backend(s) generated this event - enables filtering by implementation */
13
+ scopes: string[];
14
+ /** When the event occurred */
15
+ timestamp: Date;
16
+ /** Optional: the full item content - fully typed, no loss of type information */
17
+ item?: Item<S, L1, L2, L3, L4, L5>;
18
+ }
19
+ /**
20
+ * Event emitted when an item is created.
21
+ * The item property is required since we always have the created item data.
22
+ */
23
+ export interface CreateEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseEvent<S, L1, L2, L3, L4, L5> {
24
+ eventType: 'create';
25
+ /** The created item - always available for create events */
26
+ item: Item<S, L1, L2, L3, L4, L5>;
27
+ }
28
+ /**
29
+ * Event emitted when an item is updated.
30
+ * Provides detailed change tracking with before/after states.
31
+ */
32
+ export interface UpdateEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseEvent<S, L1, L2, L3, L4, L5> {
33
+ eventType: 'update';
34
+ /** List of field names that were changed */
35
+ changes: string[];
36
+ /** Optional: item state before the update */
37
+ before?: Item<S, L1, L2, L3, L4, L5>;
38
+ /** Optional: item state after the update */
39
+ after?: Item<S, L1, L2, L3, L4, L5>;
40
+ }
41
+ /**
42
+ * Event emitted when an item is deleted.
43
+ * May include the deleted item data for cleanup/undo operations.
44
+ */
45
+ export interface DeleteEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseEvent<S, L1, L2, L3, L4, L5> {
46
+ eventType: 'delete';
47
+ /** Optional: the deleted item content - useful for cleanup/undo */
48
+ item?: Item<S, L1, L2, L3, L4, L5>;
49
+ }
50
+ /**
51
+ * Event emitted when a custom action is performed on an item.
52
+ * Allows libraries to define custom event types beyond standard CRUD.
53
+ */
54
+ export interface ActionEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseEvent<S, L1, L2, L3, L4, L5> {
55
+ eventType: 'action';
56
+ /** Name of the action that was performed */
57
+ actionName: string;
58
+ /** Optional: action-specific data */
59
+ actionData?: Record<string, unknown>;
60
+ }
61
+ /**
62
+ * Union type of all standard event types.
63
+ * Libraries can extend this with custom events if needed.
64
+ */
65
+ export type Event<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = CreateEvent<S, L1, L2, L3, L4, L5> | UpdateEvent<S, L1, L2, L3, L4, L5> | DeleteEvent<S, L1, L2, L3, L4, L5> | ActionEvent<S, L1, L2, L3, L4, L5>;
66
+ /**
67
+ * Type guard to check if an event is a CreateEvent
68
+ */
69
+ export declare function isCreateEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>): event is CreateEvent<S, L1, L2, L3, L4, L5>;
70
+ /**
71
+ * Type guard to check if an event is an UpdateEvent
72
+ */
73
+ export declare function isUpdateEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>): event is UpdateEvent<S, L1, L2, L3, L4, L5>;
74
+ /**
75
+ * Type guard to check if an event is a DeleteEvent
76
+ */
77
+ export declare function isDeleteEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>): event is DeleteEvent<S, L1, L2, L3, L4, L5>;
78
+ /**
79
+ * Type guard to check if an event is an ActionEvent
80
+ */
81
+ export declare function isActionEvent<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>): event is ActionEvent<S, L1, L2, L3, L4, L5>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Event System Public API
3
+ *
4
+ * This module exports all the public interfaces and utilities for the Fjell event system.
5
+ * The event system provides type-safe, item-level change events with full PriKey/ComKey integration.
6
+ *
7
+ * Key Features:
8
+ * - Full type safety using existing PriKey/ComKey system
9
+ * - Storage-agnostic event interfaces
10
+ * - Item-specific and location-based subscriptions
11
+ * - Separate EventEmitters per item type for optimal type safety
12
+ * - Real-time awareness for application needs (not reliable business execution)
13
+ *
14
+ * Usage:
15
+ * - Libraries implement EventEmitter/EventSubscriber interfaces
16
+ * - Applications subscribe to events through library instances
17
+ * - Events are delivered through callback functions with full type safety
18
+ */
19
+ export { BaseEvent, CreateEvent, UpdateEvent, DeleteEvent, ActionEvent, Event, isCreateEvent, isUpdateEvent, isDeleteEvent, isActionEvent, } from './events';
20
+ export { BaseSubscription, ItemSubscription, LocationSubscription, Subscription, SubscriptionOptions, isItemSubscription, isLocationSubscription, generateSubscriptionId, createItemSubscription, createLocationSubscription, } from './subscription';
21
+ export { EventEmitter, ScopedEventEmitter, EventSubscriber, EventSystem, EventSystemFactory, UserEventEmitter, UserEventSubscriber, UserEventSystem, MessageEventEmitter, MessageEventSubscriber, MessageEventSystem, } from './emitter';
22
+ export { doesEventMatchSubscription, doesScopeMatch, doesEventTypeMatch, doesKeyMatch, doesKeyMatchLocation, doesLocationMatch, findMatchingSubscriptions, extractLocationValues, compareLocationValues, } from './matching';
23
+ export { STANDARD_EVENT_TYPES, StandardEventType, STANDARD_SCOPES, StandardScope, SubscriptionStatus, SubscriptionMetadata, ManagedSubscription, EventHandler, SafeEventHandler, EventBatch, EventStats, EventSystemConfig, DEFAULT_EVENT_CONFIG, EventSystemError, SubscriptionError, EventEmissionError, EventMatchingError, createEventSystemError, isEventSystemError, ExtractItemType, ExtractEventTypes, } from './types';
24
+ /**
25
+ * Version of the event system API.
26
+ * Used for compatibility checking and debugging.
27
+ */
28
+ export declare const EVENT_SYSTEM_VERSION = "1.0.0";
29
+ /**
30
+ * Supported event types for reference.
31
+ * Libraries should use these standard types for consistency.
32
+ */
33
+ export declare const SUPPORTED_EVENT_TYPES: readonly ["create", "update", "delete", "action"];
34
+ /**
35
+ * Supported storage scopes for reference.
36
+ * Libraries should use these standard scopes for consistency.
37
+ */
38
+ export declare const SUPPORTED_SCOPES: readonly ["firestore", "sequelize", "postgresql", "mysql", "mongodb", "redis"];
@@ -0,0 +1,54 @@
1
+ import { ComKey, ItemTypeArray, LocKeyArray, PriKey } from '../keys';
2
+ import { BaseEvent } from './events';
3
+ import { Subscription } from './subscription';
4
+ /**
5
+ * Core subscription matching logic.
6
+ * Determines whether an event should be delivered to a specific subscription.
7
+ */
8
+ export declare function doesEventMatchSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>, subscription: Subscription<S, L1, L2, L3, L4, L5>): boolean;
9
+ /**
10
+ * Check if event scopes match subscription scope requirements.
11
+ *
12
+ * @param eventScopes - Scopes from the event (e.g., ["firestore"])
13
+ * @param subscriptionScopes - Optional scopes required by subscription
14
+ * @returns true if scopes are compatible
15
+ */
16
+ export declare function doesScopeMatch(eventScopes: string[], subscriptionScopes?: string[]): boolean;
17
+ /**
18
+ * Check if event type matches subscription event type requirements.
19
+ *
20
+ * @param eventType - Type from the event (e.g., "create", "update")
21
+ * @param subscriptionEventTypes - Optional event types required by subscription
22
+ * @returns true if event type is compatible
23
+ */
24
+ export declare function doesEventTypeMatch(eventType: string, subscriptionEventTypes?: string[]): boolean;
25
+ /**
26
+ * Check if two keys are exactly equal.
27
+ * Used for item-based subscriptions that want events for a specific key.
28
+ */
29
+ export declare function doesKeyMatch<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(eventKey: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, subscriptionKey: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>): boolean;
30
+ /**
31
+ * Check if an event key matches a location-based subscription.
32
+ * This is more complex as it needs to determine if the event key is "within" the subscription location.
33
+ */
34
+ export declare function doesKeyMatchLocation<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(eventKey: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, subscriptionKta: ItemTypeArray<S, L1, L2, L3, L4, L5>, subscriptionLocation: LocKeyArray<L1, L2, L3, L4, L5>): boolean;
35
+ /**
36
+ * Check if an event's location keys match a subscription's location requirements.
37
+ * This implements the hierarchical location matching logic.
38
+ */
39
+ export declare function doesLocationMatch<L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(eventLocation: LocKeyArray<L1, L2, L3, L4, L5>, subscriptionLocation: LocKeyArray<L1, L2, L3, L4, L5>, _subscriptionKta: ItemTypeArray<string, L1, L2, L3, L4, L5>): boolean;
40
+ /**
41
+ * Find all subscriptions that match a given event.
42
+ * Used by EventSubscriber implementations to determine which subscriptions should receive an event.
43
+ */
44
+ export declare function findMatchingSubscriptions<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(event: BaseEvent<S, L1, L2, L3, L4, L5>, subscriptions: Subscription<S, L1, L2, L3, L4, L5>[]): Subscription<S, L1, L2, L3, L4, L5>[];
45
+ /**
46
+ * Utility function to extract the location from a ComKey for comparison purposes.
47
+ * Returns the location key values as strings for easier comparison.
48
+ */
49
+ export declare function extractLocationValues<L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(location: LocKeyArray<L1, L2, L3, L4, L5>): string[];
50
+ /**
51
+ * Utility function to compare two location arrays by their values.
52
+ * Useful for debugging and testing location matching logic.
53
+ */
54
+ export declare function compareLocationValues<L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(location1: LocKeyArray<L1, L2, L3, L4, L5>, location2: LocKeyArray<L1, L2, L3, L4, L5>): boolean;
@@ -0,0 +1,74 @@
1
+ import { ComKey, ItemTypeArray, LocKeyArray, PriKey } from '../keys';
2
+ import { ItemQuery } from '../item/ItemQuery';
3
+ /**
4
+ * Base subscription interface that all subscription types extend.
5
+ * Provides core subscription properties with full type safety.
6
+ */
7
+ export interface BaseSubscription {
8
+ /** Unique subscription identifier - generated when subscription is created */
9
+ id: string;
10
+ /** Optional: specific event types to listen for (defaults to all if not specified) */
11
+ eventTypes?: string[];
12
+ /** Optional: storage backends to listen to (defaults to all if not specified) */
13
+ scopes?: string[];
14
+ /** Optional: additional filtering criteria using existing ItemQuery system */
15
+ query?: ItemQuery;
16
+ }
17
+ /**
18
+ * Subscription to events for a specific item using PriKey or ComKey.
19
+ * Provides exact item-level event subscriptions with full type safety.
20
+ */
21
+ export interface ItemSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseSubscription {
22
+ /** The specific key to subscribe to - fully typed PriKey or ComKey */
23
+ key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>;
24
+ }
25
+ /**
26
+ * Subscription to events for all items in a location using KTA + location array.
27
+ * Provides location-based event subscriptions with full type safety.
28
+ */
29
+ export interface LocationSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends BaseSubscription {
30
+ /** Item type array defining the type hierarchy */
31
+ kta: ItemTypeArray<S, L1, L2, L3, L4, L5>;
32
+ /** Location key array defining the specific location */
33
+ location: LocKeyArray<L1, L2, L3, L4, L5>;
34
+ }
35
+ /**
36
+ * Union type of all subscription types.
37
+ * This allows handling any subscription type generically while maintaining type safety.
38
+ */
39
+ export type Subscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = ItemSubscription<S, L1, L2, L3, L4, L5> | LocationSubscription<S, L1, L2, L3, L4, L5>;
40
+ /**
41
+ * Options for creating subscriptions.
42
+ * Used by convenience methods to create subscriptions without requiring full subscription objects.
43
+ */
44
+ export interface SubscriptionOptions<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
45
+ /** Optional: specific event types to listen for */
46
+ eventTypes?: string[];
47
+ /** Optional: storage backends to listen to */
48
+ scopes?: string[];
49
+ /** Optional: additional filtering criteria */
50
+ query?: ItemQuery;
51
+ }
52
+ /**
53
+ * Type guard to check if a subscription is an ItemSubscription
54
+ */
55
+ export declare function isItemSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(subscription: Subscription<S, L1, L2, L3, L4, L5>): subscription is ItemSubscription<S, L1, L2, L3, L4, L5>;
56
+ /**
57
+ * Type guard to check if a subscription is a LocationSubscription
58
+ */
59
+ export declare function isLocationSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(subscription: Subscription<S, L1, L2, L3, L4, L5>): subscription is LocationSubscription<S, L1, L2, L3, L4, L5>;
60
+ /**
61
+ * Utility function to generate unique subscription IDs.
62
+ * Libraries can use this or implement their own ID generation strategy.
63
+ */
64
+ export declare function generateSubscriptionId(): string;
65
+ /**
66
+ * Utility function to create an ItemSubscription with generated ID.
67
+ * Simplifies subscription creation for library implementations.
68
+ */
69
+ export declare function createItemSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): ItemSubscription<S, L1, L2, L3, L4, L5>;
70
+ /**
71
+ * Utility function to create a LocationSubscription with generated ID.
72
+ * Simplifies subscription creation for library implementations.
73
+ */
74
+ export declare function createLocationSubscription<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(kta: ItemTypeArray<S, L1, L2, L3, L4, L5>, location: LocKeyArray<L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): LocationSubscription<S, L1, L2, L3, L4, L5>;