@fjell/core 4.4.49 → 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.
- package/dist/event/emitter.d.ts +140 -0
- package/dist/event/events.d.ts +81 -0
- package/dist/event/index.d.ts +38 -0
- package/dist/event/matching.d.ts +54 -0
- package/dist/event/subscription.d.ts +74 -0
- package/dist/event/types.d.ts +186 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +272 -0
- package/package.json +1 -1
- package/src/event/emitter.ts +247 -0
- package/src/event/events.ts +178 -0
- package/src/event/index.ts +130 -0
- package/src/event/matching.ts +264 -0
- package/src/event/subscription.ts +181 -0
- package/src/event/types.ts +282 -0
- package/src/index.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -1519,6 +1519,50 @@ function getErrorInfo(error) {
|
|
|
1519
1519
|
};
|
|
1520
1520
|
}
|
|
1521
1521
|
|
|
1522
|
+
// src/event/events.ts
|
|
1523
|
+
function isCreateEvent(event) {
|
|
1524
|
+
return event.eventType === "create";
|
|
1525
|
+
}
|
|
1526
|
+
function isUpdateEvent(event) {
|
|
1527
|
+
return event.eventType === "update";
|
|
1528
|
+
}
|
|
1529
|
+
function isDeleteEvent(event) {
|
|
1530
|
+
return event.eventType === "delete";
|
|
1531
|
+
}
|
|
1532
|
+
function isActionEvent(event) {
|
|
1533
|
+
return event.eventType === "action";
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
// src/event/subscription.ts
|
|
1537
|
+
function isItemSubscription(subscription) {
|
|
1538
|
+
return "key" in subscription;
|
|
1539
|
+
}
|
|
1540
|
+
function isLocationSubscription(subscription) {
|
|
1541
|
+
return "kta" in subscription && "location" in subscription;
|
|
1542
|
+
}
|
|
1543
|
+
function generateSubscriptionId() {
|
|
1544
|
+
return `sub-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1545
|
+
}
|
|
1546
|
+
function createItemSubscription(key, options) {
|
|
1547
|
+
return {
|
|
1548
|
+
id: generateSubscriptionId(),
|
|
1549
|
+
key,
|
|
1550
|
+
eventTypes: options?.eventTypes,
|
|
1551
|
+
scopes: options?.scopes,
|
|
1552
|
+
query: options?.query
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
function createLocationSubscription(kta, location, options) {
|
|
1556
|
+
return {
|
|
1557
|
+
id: generateSubscriptionId(),
|
|
1558
|
+
kta,
|
|
1559
|
+
location,
|
|
1560
|
+
eventTypes: options?.eventTypes,
|
|
1561
|
+
scopes: options?.scopes,
|
|
1562
|
+
query: options?.query
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1522
1566
|
// src/operations/Operations.ts
|
|
1523
1567
|
function isPriKey2(key) {
|
|
1524
1568
|
return !("loc" in key) || !key.loc;
|
|
@@ -1527,6 +1571,203 @@ function isComKey2(key) {
|
|
|
1527
1571
|
return "loc" in key && key.loc && Array.isArray(key.loc) && key.loc.length > 0;
|
|
1528
1572
|
}
|
|
1529
1573
|
|
|
1574
|
+
// src/event/matching.ts
|
|
1575
|
+
function doesEventMatchSubscription(event, subscription) {
|
|
1576
|
+
if (!doesScopeMatch(event.scopes, subscription.scopes)) {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
if (!doesEventTypeMatch(event.eventType, subscription.eventTypes)) {
|
|
1580
|
+
return false;
|
|
1581
|
+
}
|
|
1582
|
+
if (isItemSubscription(subscription)) {
|
|
1583
|
+
return doesKeyMatch(event.key, subscription.key);
|
|
1584
|
+
} else if (isLocationSubscription(subscription)) {
|
|
1585
|
+
return doesKeyMatchLocation(event.key, subscription.kta, subscription.location);
|
|
1586
|
+
}
|
|
1587
|
+
return false;
|
|
1588
|
+
}
|
|
1589
|
+
function doesScopeMatch(eventScopes, subscriptionScopes) {
|
|
1590
|
+
if (!subscriptionScopes || subscriptionScopes.length === 0) {
|
|
1591
|
+
return true;
|
|
1592
|
+
}
|
|
1593
|
+
return subscriptionScopes.some(
|
|
1594
|
+
(requiredScope) => eventScopes.includes(requiredScope)
|
|
1595
|
+
);
|
|
1596
|
+
}
|
|
1597
|
+
function doesEventTypeMatch(eventType, subscriptionEventTypes) {
|
|
1598
|
+
if (!subscriptionEventTypes || subscriptionEventTypes.length === 0) {
|
|
1599
|
+
return true;
|
|
1600
|
+
}
|
|
1601
|
+
return subscriptionEventTypes.includes(eventType);
|
|
1602
|
+
}
|
|
1603
|
+
function doesKeyMatch(eventKey, subscriptionKey) {
|
|
1604
|
+
if (isPriKey2(eventKey) && isPriKey2(subscriptionKey)) {
|
|
1605
|
+
return eventKey.pk === subscriptionKey.pk && eventKey.kt === subscriptionKey.kt;
|
|
1606
|
+
}
|
|
1607
|
+
if (isComKey2(eventKey) && isComKey2(subscriptionKey)) {
|
|
1608
|
+
const eventComKey = eventKey;
|
|
1609
|
+
const subscriptionComKey = subscriptionKey;
|
|
1610
|
+
if (eventComKey.pk !== subscriptionComKey.pk || eventComKey.kt !== subscriptionComKey.kt) {
|
|
1611
|
+
return false;
|
|
1612
|
+
}
|
|
1613
|
+
if (eventComKey.loc.length !== subscriptionComKey.loc.length) {
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
return eventComKey.loc.every((eventLocKey, index) => {
|
|
1617
|
+
const subLocKey = subscriptionComKey.loc[index];
|
|
1618
|
+
return eventLocKey.lk === subLocKey.lk && eventLocKey.kt === subLocKey.kt;
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
return false;
|
|
1622
|
+
}
|
|
1623
|
+
function doesKeyMatchLocation(eventKey, subscriptionKta, subscriptionLocation) {
|
|
1624
|
+
const targetItemType = subscriptionKta[subscriptionKta.length - 1];
|
|
1625
|
+
if (eventKey.kt !== targetItemType) {
|
|
1626
|
+
return false;
|
|
1627
|
+
}
|
|
1628
|
+
if (isPriKey2(eventKey)) {
|
|
1629
|
+
return subscriptionLocation.length === 0;
|
|
1630
|
+
}
|
|
1631
|
+
if (isComKey2(eventKey)) {
|
|
1632
|
+
const comKey = eventKey;
|
|
1633
|
+
return doesLocationMatch(comKey.loc, subscriptionLocation, subscriptionKta);
|
|
1634
|
+
}
|
|
1635
|
+
return false;
|
|
1636
|
+
}
|
|
1637
|
+
function doesLocationMatch(eventLocation, subscriptionLocation, _subscriptionKta) {
|
|
1638
|
+
if (subscriptionLocation.length === 0) {
|
|
1639
|
+
return true;
|
|
1640
|
+
}
|
|
1641
|
+
if (eventLocation.length < subscriptionLocation.length) {
|
|
1642
|
+
return false;
|
|
1643
|
+
}
|
|
1644
|
+
for (let i = 0; i < subscriptionLocation.length; i++) {
|
|
1645
|
+
const eventLocKey = eventLocation[i];
|
|
1646
|
+
const subLocKey = subscriptionLocation[i];
|
|
1647
|
+
if (!eventLocKey || !subLocKey) {
|
|
1648
|
+
return false;
|
|
1649
|
+
}
|
|
1650
|
+
if (eventLocKey.lk !== subLocKey.lk || eventLocKey.kt !== subLocKey.kt) {
|
|
1651
|
+
return false;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
return true;
|
|
1655
|
+
}
|
|
1656
|
+
function findMatchingSubscriptions(event, subscriptions) {
|
|
1657
|
+
return subscriptions.filter(
|
|
1658
|
+
(subscription) => doesEventMatchSubscription(event, subscription)
|
|
1659
|
+
);
|
|
1660
|
+
}
|
|
1661
|
+
function extractLocationValues(location) {
|
|
1662
|
+
return location.map((locKey) => String(locKey.lk));
|
|
1663
|
+
}
|
|
1664
|
+
function compareLocationValues(location1, location2) {
|
|
1665
|
+
if (location1.length !== location2.length) {
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
return location1.every((locKey1, index) => {
|
|
1669
|
+
const locKey2 = location2[index];
|
|
1670
|
+
return locKey1.lk === locKey2.lk && locKey1.kt === locKey2.kt;
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// src/event/types.ts
|
|
1675
|
+
var STANDARD_EVENT_TYPES = {
|
|
1676
|
+
CREATE: "create",
|
|
1677
|
+
UPDATE: "update",
|
|
1678
|
+
DELETE: "delete",
|
|
1679
|
+
ACTION: "action"
|
|
1680
|
+
};
|
|
1681
|
+
var STANDARD_SCOPES = {
|
|
1682
|
+
FIRESTORE: "firestore",
|
|
1683
|
+
SEQUELIZE: "sequelize",
|
|
1684
|
+
POSTGRESQL: "postgresql",
|
|
1685
|
+
MYSQL: "mysql",
|
|
1686
|
+
MONGODB: "mongodb",
|
|
1687
|
+
REDIS: "redis"
|
|
1688
|
+
};
|
|
1689
|
+
var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
|
|
1690
|
+
SubscriptionStatus2["PENDING"] = "pending";
|
|
1691
|
+
SubscriptionStatus2["ACTIVE"] = "active";
|
|
1692
|
+
SubscriptionStatus2["PAUSED"] = "paused";
|
|
1693
|
+
SubscriptionStatus2["ERROR"] = "error";
|
|
1694
|
+
SubscriptionStatus2["CANCELLED"] = "cancelled";
|
|
1695
|
+
return SubscriptionStatus2;
|
|
1696
|
+
})(SubscriptionStatus || {});
|
|
1697
|
+
var DEFAULT_EVENT_CONFIG = {
|
|
1698
|
+
maxBatchSize: 100,
|
|
1699
|
+
maxBatchWaitTime: 50,
|
|
1700
|
+
// 50ms
|
|
1701
|
+
maxRetryAttempts: 3,
|
|
1702
|
+
retryDelay: 1e3,
|
|
1703
|
+
// 1 second
|
|
1704
|
+
enableStats: true,
|
|
1705
|
+
maxSubscriptions: 1e3,
|
|
1706
|
+
subscriptionCleanupInterval: 3e5
|
|
1707
|
+
// 5 minutes
|
|
1708
|
+
};
|
|
1709
|
+
var EventSystemError = class extends Error {
|
|
1710
|
+
constructor(message, code, details) {
|
|
1711
|
+
super(message);
|
|
1712
|
+
this.code = code;
|
|
1713
|
+
this.details = details;
|
|
1714
|
+
this.name = "EventSystemError";
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
var SubscriptionError = class extends EventSystemError {
|
|
1718
|
+
constructor(message, subscriptionId, details) {
|
|
1719
|
+
super(message, "SUBSCRIPTION_ERROR", { subscriptionId, ...details });
|
|
1720
|
+
this.subscriptionId = subscriptionId;
|
|
1721
|
+
this.name = "SubscriptionError";
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
var EventEmissionError = class extends EventSystemError {
|
|
1725
|
+
constructor(message, eventType, details) {
|
|
1726
|
+
super(message, "EVENT_EMISSION_ERROR", { eventType, ...details });
|
|
1727
|
+
this.eventType = eventType;
|
|
1728
|
+
this.name = "EventEmissionError";
|
|
1729
|
+
}
|
|
1730
|
+
};
|
|
1731
|
+
var EventMatchingError = class extends EventSystemError {
|
|
1732
|
+
constructor(message, details) {
|
|
1733
|
+
super(message, "EVENT_MATCHING_ERROR", details);
|
|
1734
|
+
this.name = "EventMatchingError";
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
function createEventSystemError(type, message, details) {
|
|
1738
|
+
switch (type) {
|
|
1739
|
+
case "subscription":
|
|
1740
|
+
return new SubscriptionError(message, details?.subscriptionId || "unknown", details);
|
|
1741
|
+
case "emission":
|
|
1742
|
+
return new EventEmissionError(message, details?.eventType || "unknown", details);
|
|
1743
|
+
case "matching":
|
|
1744
|
+
return new EventMatchingError(message, details);
|
|
1745
|
+
case "general":
|
|
1746
|
+
default:
|
|
1747
|
+
return new EventSystemError(message, "GENERAL_ERROR", details);
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
function isEventSystemError(error) {
|
|
1751
|
+
return error instanceof EventSystemError;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
// src/event/index.ts
|
|
1755
|
+
var EVENT_SYSTEM_VERSION = "1.0.0";
|
|
1756
|
+
var SUPPORTED_EVENT_TYPES = [
|
|
1757
|
+
"create",
|
|
1758
|
+
"update",
|
|
1759
|
+
"delete",
|
|
1760
|
+
"action"
|
|
1761
|
+
];
|
|
1762
|
+
var SUPPORTED_SCOPES = [
|
|
1763
|
+
"firestore",
|
|
1764
|
+
"sequelize",
|
|
1765
|
+
"postgresql",
|
|
1766
|
+
"mysql",
|
|
1767
|
+
"mongodb",
|
|
1768
|
+
"redis"
|
|
1769
|
+
];
|
|
1770
|
+
|
|
1530
1771
|
// src/operations/wrappers/createOneWrapper.ts
|
|
1531
1772
|
var logger9 = logger_default.get("operations", "wrappers", "one");
|
|
1532
1773
|
function createOneWrapper(coordinate, implementation, options = {}) {
|
|
@@ -2078,12 +2319,23 @@ export {
|
|
|
2078
2319
|
AItemService,
|
|
2079
2320
|
ActionError,
|
|
2080
2321
|
BusinessLogicError,
|
|
2322
|
+
DEFAULT_EVENT_CONFIG,
|
|
2081
2323
|
Dictionary,
|
|
2082
2324
|
DuplicateError,
|
|
2325
|
+
EVENT_SYSTEM_VERSION,
|
|
2326
|
+
EventEmissionError,
|
|
2327
|
+
EventMatchingError,
|
|
2328
|
+
EventSystemError,
|
|
2083
2329
|
IFactory,
|
|
2084
2330
|
IQFactory,
|
|
2085
2331
|
NotFoundError,
|
|
2086
2332
|
PermissionError,
|
|
2333
|
+
STANDARD_EVENT_TYPES,
|
|
2334
|
+
STANDARD_SCOPES,
|
|
2335
|
+
SUPPORTED_EVENT_TYPES,
|
|
2336
|
+
SUPPORTED_SCOPES,
|
|
2337
|
+
SubscriptionError,
|
|
2338
|
+
SubscriptionStatus,
|
|
2087
2339
|
ValidationError,
|
|
2088
2340
|
abbrevAgg,
|
|
2089
2341
|
abbrevCompoundCondition,
|
|
@@ -2093,6 +2345,7 @@ export {
|
|
|
2093
2345
|
abbrevQuery,
|
|
2094
2346
|
abbrevRef,
|
|
2095
2347
|
cPK,
|
|
2348
|
+
compareLocationValues,
|
|
2096
2349
|
constructPriKey,
|
|
2097
2350
|
createActionWrapper,
|
|
2098
2351
|
createAllActionWrapper,
|
|
@@ -2100,34 +2353,52 @@ export {
|
|
|
2100
2353
|
createAllWrapper,
|
|
2101
2354
|
createCoordinate,
|
|
2102
2355
|
createCreateWrapper,
|
|
2356
|
+
createEventSystemError,
|
|
2103
2357
|
createFacetWrapper,
|
|
2104
2358
|
createFindOneWrapper,
|
|
2105
2359
|
createFindWrapper,
|
|
2106
2360
|
createGetWrapper,
|
|
2361
|
+
createItemSubscription,
|
|
2362
|
+
createLocationSubscription,
|
|
2107
2363
|
createNormalizedHashFunction,
|
|
2108
2364
|
createOneWrapper,
|
|
2109
2365
|
createRemoveWrapper,
|
|
2110
2366
|
createUpdateWrapper,
|
|
2111
2367
|
createUpsertWrapper,
|
|
2368
|
+
doesEventMatchSubscription,
|
|
2369
|
+
doesEventTypeMatch,
|
|
2370
|
+
doesKeyMatch,
|
|
2371
|
+
doesKeyMatchLocation,
|
|
2372
|
+
doesLocationMatch,
|
|
2373
|
+
doesScopeMatch,
|
|
2112
2374
|
enhanceError,
|
|
2113
2375
|
executeWithContext,
|
|
2114
2376
|
executeWithContextSync,
|
|
2115
2377
|
extractKeyTypeArray,
|
|
2378
|
+
extractLocationValues,
|
|
2379
|
+
findMatchingSubscriptions,
|
|
2116
2380
|
generateKeyArray,
|
|
2381
|
+
generateSubscriptionId,
|
|
2117
2382
|
getErrorInfo,
|
|
2118
2383
|
ikToLKA,
|
|
2119
2384
|
isActionError,
|
|
2385
|
+
isActionEvent,
|
|
2120
2386
|
isComItem,
|
|
2121
2387
|
isComKey,
|
|
2122
2388
|
isComKeyEqual,
|
|
2123
2389
|
isComKeyEqualNormalized,
|
|
2124
2390
|
isCondition,
|
|
2391
|
+
isCreateEvent,
|
|
2392
|
+
isDeleteEvent,
|
|
2393
|
+
isEventSystemError,
|
|
2125
2394
|
isItemKey,
|
|
2126
2395
|
isItemKeyEqual,
|
|
2127
2396
|
isItemKeyEqualNormalized,
|
|
2397
|
+
isItemSubscription,
|
|
2128
2398
|
isLocKey,
|
|
2129
2399
|
isLocKeyEqual,
|
|
2130
2400
|
isLocKeyEqualNormalized,
|
|
2401
|
+
isLocationSubscription,
|
|
2131
2402
|
isComKey2 as isOperationComKey,
|
|
2132
2403
|
isPriKey2 as isOperationPriKey,
|
|
2133
2404
|
isPriItem,
|
|
@@ -2135,6 +2406,7 @@ export {
|
|
|
2135
2406
|
isPriKeyEqual,
|
|
2136
2407
|
isPriKeyEqualNormalized,
|
|
2137
2408
|
isQueryMatch,
|
|
2409
|
+
isUpdateEvent,
|
|
2138
2410
|
isValidComKey,
|
|
2139
2411
|
isValidItemKey,
|
|
2140
2412
|
isValidLocKey,
|
package/package.json
CHANGED
|
@@ -0,0 +1,247 @@
|
|
|
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>;
|