@olane/o-core 0.7.12-alpha.5 → 0.7.12-alpha.6

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 (31) hide show
  1. package/dist/src/core/lib/events/connection-events.d.ts +31 -0
  2. package/dist/src/core/lib/events/connection-events.d.ts.map +1 -0
  3. package/dist/src/core/lib/events/connection-events.js +46 -0
  4. package/dist/src/core/lib/events/hierarchy-events.d.ts +69 -0
  5. package/dist/src/core/lib/events/hierarchy-events.d.ts.map +1 -0
  6. package/dist/src/core/lib/events/hierarchy-events.js +100 -0
  7. package/dist/src/core/lib/events/index.d.ts +6 -0
  8. package/dist/src/core/lib/events/index.d.ts.map +1 -0
  9. package/dist/src/core/lib/events/index.js +5 -0
  10. package/dist/src/core/lib/events/node-events.d.ts +40 -0
  11. package/dist/src/core/lib/events/node-events.d.ts.map +1 -0
  12. package/dist/src/core/lib/events/node-events.js +58 -0
  13. package/dist/src/core/lib/events/o-notification-event.d.ts +26 -0
  14. package/dist/src/core/lib/events/o-notification-event.d.ts.map +1 -0
  15. package/dist/src/core/lib/events/o-notification-event.js +30 -0
  16. package/dist/src/core/lib/index.d.ts +4 -0
  17. package/dist/src/core/lib/index.d.ts.map +1 -1
  18. package/dist/src/core/lib/index.js +4 -0
  19. package/dist/src/core/lib/interfaces/notification-types.d.ts +49 -0
  20. package/dist/src/core/lib/interfaces/notification-types.d.ts.map +1 -0
  21. package/dist/src/core/lib/interfaces/notification-types.js +1 -0
  22. package/dist/src/core/lib/o-notification.manager.d.ts +58 -0
  23. package/dist/src/core/lib/o-notification.manager.d.ts.map +1 -0
  24. package/dist/src/core/lib/o-notification.manager.js +159 -0
  25. package/dist/src/core/lib/utils/event-filters.d.ts +38 -0
  26. package/dist/src/core/lib/utils/event-filters.d.ts.map +1 -0
  27. package/dist/src/core/lib/utils/event-filters.js +159 -0
  28. package/dist/src/core/o-core.d.ts +12 -0
  29. package/dist/src/core/o-core.d.ts.map +1 -1
  30. package/dist/src/core/o-core.js +26 -1
  31. package/package.json +3 -3
@@ -0,0 +1,31 @@
1
+ import { oAddress } from '../../../router/o-address.js';
2
+ import { oNotificationEvent } from './o-notification-event.js';
3
+ /**
4
+ * Emitted when a connection becomes degraded (some pings failing)
5
+ */
6
+ export declare class ConnectionDegradedEvent extends oNotificationEvent {
7
+ readonly targetAddress: oAddress;
8
+ readonly role: 'parent' | 'child';
9
+ readonly consecutiveFailures: number;
10
+ constructor(config: {
11
+ source: oAddress;
12
+ targetAddress: oAddress;
13
+ role: 'parent' | 'child';
14
+ consecutiveFailures: number;
15
+ });
16
+ protected getEventData(): Record<string, any>;
17
+ }
18
+ /**
19
+ * Emitted when a degraded connection recovers
20
+ */
21
+ export declare class ConnectionRecoveredEvent extends oNotificationEvent {
22
+ readonly targetAddress: oAddress;
23
+ readonly role: 'parent' | 'child';
24
+ constructor(config: {
25
+ source: oAddress;
26
+ targetAddress: oAddress;
27
+ role: 'parent' | 'child';
28
+ });
29
+ protected getEventData(): Record<string, any>;
30
+ }
31
+ //# sourceMappingURL=connection-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-events.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/events/connection-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAEnB,MAAM,2BAA2B,CAAC;AAEnC;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;gBAEzB,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,aAAa,EAAE,QAAQ,CAAC;QACxB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QACzB,mBAAmB,EAAE,MAAM,CAAC;KAC7B;IAcD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAO9C;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,kBAAkB;IAC9D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;gBAEtB,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,aAAa,EAAE,QAAQ,CAAC;QACxB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;KAC1B;IAUD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C"}
@@ -0,0 +1,46 @@
1
+ import { oNotificationEvent, } from './o-notification-event.js';
2
+ /**
3
+ * Emitted when a connection becomes degraded (some pings failing)
4
+ */
5
+ export class ConnectionDegradedEvent extends oNotificationEvent {
6
+ constructor(config) {
7
+ super({
8
+ type: 'connection:degraded',
9
+ source: config.source,
10
+ metadata: {
11
+ role: config.role,
12
+ consecutiveFailures: config.consecutiveFailures,
13
+ },
14
+ });
15
+ this.targetAddress = config.targetAddress;
16
+ this.role = config.role;
17
+ this.consecutiveFailures = config.consecutiveFailures;
18
+ }
19
+ getEventData() {
20
+ return {
21
+ targetAddress: this.targetAddress.toString(),
22
+ role: this.role,
23
+ consecutiveFailures: this.consecutiveFailures,
24
+ };
25
+ }
26
+ }
27
+ /**
28
+ * Emitted when a degraded connection recovers
29
+ */
30
+ export class ConnectionRecoveredEvent extends oNotificationEvent {
31
+ constructor(config) {
32
+ super({
33
+ type: 'connection:recovered',
34
+ source: config.source,
35
+ metadata: { role: config.role },
36
+ });
37
+ this.targetAddress = config.targetAddress;
38
+ this.role = config.role;
39
+ }
40
+ getEventData() {
41
+ return {
42
+ targetAddress: this.targetAddress.toString(),
43
+ role: this.role,
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,69 @@
1
+ import { oAddress } from '../../../router/o-address.js';
2
+ import { oNotificationEvent } from './o-notification-event.js';
3
+ /**
4
+ * Emitted when a child node joins the hierarchy (registers with parent)
5
+ */
6
+ export declare class ChildJoinedEvent extends oNotificationEvent {
7
+ readonly childAddress: oAddress;
8
+ readonly parentAddress: oAddress;
9
+ constructor(config: {
10
+ source: oAddress;
11
+ childAddress: oAddress;
12
+ parentAddress: oAddress;
13
+ });
14
+ protected getEventData(): Record<string, any>;
15
+ }
16
+ /**
17
+ * Emitted when a child node leaves the hierarchy (unregisters or disconnects)
18
+ */
19
+ export declare class ChildLeftEvent extends oNotificationEvent {
20
+ readonly childAddress: oAddress;
21
+ readonly parentAddress: oAddress;
22
+ readonly reason?: string;
23
+ constructor(config: {
24
+ source: oAddress;
25
+ childAddress: oAddress;
26
+ parentAddress: oAddress;
27
+ reason?: string;
28
+ });
29
+ protected getEventData(): Record<string, any>;
30
+ }
31
+ /**
32
+ * Emitted when a parent connection is established
33
+ */
34
+ export declare class ParentConnectedEvent extends oNotificationEvent {
35
+ readonly parentAddress: oAddress;
36
+ constructor(config: {
37
+ source: oAddress;
38
+ parentAddress: oAddress;
39
+ });
40
+ protected getEventData(): Record<string, any>;
41
+ }
42
+ /**
43
+ * Emitted when a parent connection is lost
44
+ */
45
+ export declare class ParentDisconnectedEvent extends oNotificationEvent {
46
+ readonly parentAddress: oAddress;
47
+ readonly reason?: string;
48
+ constructor(config: {
49
+ source: oAddress;
50
+ parentAddress: oAddress;
51
+ reason?: string;
52
+ });
53
+ protected getEventData(): Record<string, any>;
54
+ }
55
+ /**
56
+ * Emitted when connection to leader is lost (CRITICAL)
57
+ * This is a catastrophic failure - node cannot function without leader
58
+ */
59
+ export declare class LeaderDisconnectedEvent extends oNotificationEvent {
60
+ readonly leaderAddress: oAddress;
61
+ readonly reason?: string;
62
+ constructor(config: {
63
+ source: oAddress;
64
+ leaderAddress: oAddress;
65
+ reason?: string;
66
+ });
67
+ protected getEventData(): Record<string, any>;
68
+ }
69
+ //# sourceMappingURL=hierarchy-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy-events.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/events/hierarchy-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAEnB,MAAM,2BAA2B,CAAC;AAEnC;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;gBAErB,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,YAAY,EAAE,QAAQ,CAAC;QACvB,aAAa,EAAE,QAAQ,CAAC;KACzB;IASD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,kBAAkB;IACpD,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,YAAY,EAAE,QAAQ,CAAC;QACvB,aAAa,EAAE,QAAQ,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAWD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAO9C;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,kBAAkB;IAC1D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;gBAErB,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,aAAa,EAAE,QAAQ,CAAA;KAAE;IAQjE,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAK9C;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,aAAa,EAAE,QAAQ,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAUD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,kBAAkB;IAC7D,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,aAAa,EAAE,QAAQ,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAUD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C"}
@@ -0,0 +1,100 @@
1
+ import { oNotificationEvent, } from './o-notification-event.js';
2
+ /**
3
+ * Emitted when a child node joins the hierarchy (registers with parent)
4
+ */
5
+ export class ChildJoinedEvent extends oNotificationEvent {
6
+ constructor(config) {
7
+ super({
8
+ type: 'child:joined',
9
+ source: config.source,
10
+ });
11
+ this.childAddress = config.childAddress;
12
+ this.parentAddress = config.parentAddress;
13
+ }
14
+ getEventData() {
15
+ return {
16
+ childAddress: this.childAddress.toString(),
17
+ parentAddress: this.parentAddress.toString(),
18
+ };
19
+ }
20
+ }
21
+ /**
22
+ * Emitted when a child node leaves the hierarchy (unregisters or disconnects)
23
+ */
24
+ export class ChildLeftEvent extends oNotificationEvent {
25
+ constructor(config) {
26
+ super({
27
+ type: 'child:left',
28
+ source: config.source,
29
+ metadata: { reason: config.reason },
30
+ });
31
+ this.childAddress = config.childAddress;
32
+ this.parentAddress = config.parentAddress;
33
+ this.reason = config.reason;
34
+ }
35
+ getEventData() {
36
+ return {
37
+ childAddress: this.childAddress.toString(),
38
+ parentAddress: this.parentAddress.toString(),
39
+ reason: this.reason,
40
+ };
41
+ }
42
+ }
43
+ /**
44
+ * Emitted when a parent connection is established
45
+ */
46
+ export class ParentConnectedEvent extends oNotificationEvent {
47
+ constructor(config) {
48
+ super({
49
+ type: 'parent:connected',
50
+ source: config.source,
51
+ });
52
+ this.parentAddress = config.parentAddress;
53
+ }
54
+ getEventData() {
55
+ return {
56
+ parentAddress: this.parentAddress.toString(),
57
+ };
58
+ }
59
+ }
60
+ /**
61
+ * Emitted when a parent connection is lost
62
+ */
63
+ export class ParentDisconnectedEvent extends oNotificationEvent {
64
+ constructor(config) {
65
+ super({
66
+ type: 'parent:disconnected',
67
+ source: config.source,
68
+ metadata: { reason: config.reason },
69
+ });
70
+ this.parentAddress = config.parentAddress;
71
+ this.reason = config.reason;
72
+ }
73
+ getEventData() {
74
+ return {
75
+ parentAddress: this.parentAddress.toString(),
76
+ reason: this.reason,
77
+ };
78
+ }
79
+ }
80
+ /**
81
+ * Emitted when connection to leader is lost (CRITICAL)
82
+ * This is a catastrophic failure - node cannot function without leader
83
+ */
84
+ export class LeaderDisconnectedEvent extends oNotificationEvent {
85
+ constructor(config) {
86
+ super({
87
+ type: 'leader:disconnected',
88
+ source: config.source,
89
+ metadata: { reason: config.reason },
90
+ });
91
+ this.leaderAddress = config.leaderAddress;
92
+ this.reason = config.reason;
93
+ }
94
+ getEventData() {
95
+ return {
96
+ leaderAddress: this.leaderAddress.toString(),
97
+ reason: this.reason,
98
+ };
99
+ }
100
+ }
@@ -0,0 +1,6 @@
1
+ export * from './o-notification-event.js';
2
+ export * from './node-events.js';
3
+ export * from './hierarchy-events.js';
4
+ export * from './connection-events.js';
5
+ export * from '../interfaces/notification-types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qCAAqC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './o-notification-event.js';
2
+ export * from './node-events.js';
3
+ export * from './hierarchy-events.js';
4
+ export * from './connection-events.js';
5
+ export * from '../interfaces/notification-types.js';
@@ -0,0 +1,40 @@
1
+ import { oAddress } from '../../../router/o-address.js';
2
+ import { oNotificationEvent } from './o-notification-event.js';
3
+ /**
4
+ * Emitted when a node establishes a connection (transport-agnostic)
5
+ */
6
+ export declare class NodeConnectedEvent extends oNotificationEvent {
7
+ readonly nodeAddress: oAddress;
8
+ readonly connectionMetadata: Record<string, any>;
9
+ constructor(config: {
10
+ source: oAddress;
11
+ nodeAddress: oAddress;
12
+ connectionMetadata?: Record<string, any>;
13
+ });
14
+ protected getEventData(): Record<string, any>;
15
+ }
16
+ /**
17
+ * Emitted when a node disconnects (transport-agnostic)
18
+ */
19
+ export declare class NodeDisconnectedEvent extends oNotificationEvent {
20
+ readonly nodeAddress: oAddress;
21
+ readonly reason?: string;
22
+ constructor(config: {
23
+ source: oAddress;
24
+ nodeAddress: oAddress;
25
+ reason?: string;
26
+ });
27
+ protected getEventData(): Record<string, any>;
28
+ }
29
+ /**
30
+ * Emitted when a node is discovered but not yet connected
31
+ */
32
+ export declare class NodeDiscoveredEvent extends oNotificationEvent {
33
+ readonly nodeAddress: oAddress;
34
+ constructor(config: {
35
+ source: oAddress;
36
+ nodeAddress: oAddress;
37
+ });
38
+ protected getEventData(): Record<string, any>;
39
+ }
40
+ //# sourceMappingURL=node-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-events.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/events/node-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAEnB,MAAM,2BAA2B,CAAC;AAEnC;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,kBAAkB;IACxD,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAErC,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,WAAW,EAAE,QAAQ,CAAC;QACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC1C;IAUD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,kBAAkB;IAC3D,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,WAAW,EAAE,QAAQ,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAUD,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAM9C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB;IACzD,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC;gBAEnB,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,WAAW,EAAE,QAAQ,CAAA;KAAE;IAQ/D,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAK9C"}
@@ -0,0 +1,58 @@
1
+ import { oNotificationEvent, } from './o-notification-event.js';
2
+ /**
3
+ * Emitted when a node establishes a connection (transport-agnostic)
4
+ */
5
+ export class NodeConnectedEvent extends oNotificationEvent {
6
+ constructor(config) {
7
+ super({
8
+ type: 'node:connected',
9
+ source: config.source,
10
+ metadata: config.connectionMetadata || {},
11
+ });
12
+ this.nodeAddress = config.nodeAddress;
13
+ this.connectionMetadata = config.connectionMetadata || {};
14
+ }
15
+ getEventData() {
16
+ return {
17
+ nodeAddress: this.nodeAddress.toString(),
18
+ connectionMetadata: this.connectionMetadata,
19
+ };
20
+ }
21
+ }
22
+ /**
23
+ * Emitted when a node disconnects (transport-agnostic)
24
+ */
25
+ export class NodeDisconnectedEvent extends oNotificationEvent {
26
+ constructor(config) {
27
+ super({
28
+ type: 'node:disconnected',
29
+ source: config.source,
30
+ metadata: { reason: config.reason },
31
+ });
32
+ this.nodeAddress = config.nodeAddress;
33
+ this.reason = config.reason;
34
+ }
35
+ getEventData() {
36
+ return {
37
+ nodeAddress: this.nodeAddress.toString(),
38
+ reason: this.reason,
39
+ };
40
+ }
41
+ }
42
+ /**
43
+ * Emitted when a node is discovered but not yet connected
44
+ */
45
+ export class NodeDiscoveredEvent extends oNotificationEvent {
46
+ constructor(config) {
47
+ super({
48
+ type: 'node:discovered',
49
+ source: config.source,
50
+ });
51
+ this.nodeAddress = config.nodeAddress;
52
+ }
53
+ getEventData() {
54
+ return {
55
+ nodeAddress: this.nodeAddress.toString(),
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,26 @@
1
+ import { oAddress } from '../../../router/o-address.js';
2
+ export interface oNotificationEventConfig {
3
+ type: string;
4
+ source: oAddress;
5
+ metadata?: Record<string, any>;
6
+ }
7
+ /**
8
+ * Base class for all notification events in the Olane system.
9
+ * Transport-agnostic - contains only Olane concepts, no libp2p/HTTP/etc dependencies.
10
+ */
11
+ export declare abstract class oNotificationEvent {
12
+ readonly type: string;
13
+ readonly timestamp: Date;
14
+ readonly source: oAddress;
15
+ readonly metadata: Record<string, any>;
16
+ constructor(config: oNotificationEventConfig);
17
+ /**
18
+ * Serialize event to JSON for transmission
19
+ */
20
+ toJSON(): Record<string, any>;
21
+ /**
22
+ * Subclasses override to provide event-specific data
23
+ */
24
+ protected getEventData(): Record<string, any>;
25
+ }
26
+ //# sourceMappingURL=o-notification-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-notification-event.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/events/o-notification-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,8BAAsB,kBAAkB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAE3B,MAAM,EAAE,wBAAwB;IAO5C;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAU7B;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAG9C"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Base class for all notification events in the Olane system.
3
+ * Transport-agnostic - contains only Olane concepts, no libp2p/HTTP/etc dependencies.
4
+ */
5
+ export class oNotificationEvent {
6
+ constructor(config) {
7
+ this.type = config.type;
8
+ this.source = config.source;
9
+ this.metadata = config.metadata || {};
10
+ this.timestamp = new Date();
11
+ }
12
+ /**
13
+ * Serialize event to JSON for transmission
14
+ */
15
+ toJSON() {
16
+ return {
17
+ type: this.type,
18
+ timestamp: this.timestamp.toISOString(),
19
+ source: this.source.toString(),
20
+ metadata: this.metadata,
21
+ ...this.getEventData(),
22
+ };
23
+ }
24
+ /**
25
+ * Subclasses override to provide event-specific data
26
+ */
27
+ getEventData() {
28
+ return {};
29
+ }
30
+ }
@@ -1,4 +1,8 @@
1
1
  export * from './o-hierarchy.manager.js';
2
2
  export * from './o-metrics.js';
3
3
  export * from './o-request.manager.js';
4
+ export * from './o-notification.manager.js';
5
+ export * from './events/index.js';
6
+ export * from './interfaces/notification-types.js';
7
+ export * from './utils/event-filters.js';
4
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,oCAAoC,CAAC;AACnD,cAAc,0BAA0B,CAAC"}
@@ -1,3 +1,7 @@
1
1
  export * from './o-hierarchy.manager.js';
2
2
  export * from './o-metrics.js';
3
3
  export * from './o-request.manager.js';
4
+ export * from './o-notification.manager.js';
5
+ export * from './events/index.js';
6
+ export * from './interfaces/notification-types.js';
7
+ export * from './utils/event-filters.js';
@@ -0,0 +1,49 @@
1
+ import { oNotificationEvent } from '../events/o-notification-event.js';
2
+ /**
3
+ * Handler function for notification events
4
+ */
5
+ export type NotificationHandler = (event: oNotificationEvent) => void | Promise<void>;
6
+ /**
7
+ * Filter for event subscriptions
8
+ */
9
+ export interface EventFilter {
10
+ /**
11
+ * Match events from nodes matching this address pattern
12
+ * Supports wildcards: e.g., "o://leader/children/*"
13
+ */
14
+ addressPattern?: string;
15
+ /**
16
+ * Only match these specific event types
17
+ */
18
+ eventTypes?: string[];
19
+ /**
20
+ * Custom filter function
21
+ */
22
+ customFilter?: (event: oNotificationEvent) => boolean;
23
+ }
24
+ /**
25
+ * Subscription handle returned when subscribing to events
26
+ */
27
+ export interface Subscription {
28
+ /**
29
+ * Unique subscription ID
30
+ */
31
+ id: string;
32
+ /**
33
+ * Event type subscribed to
34
+ */
35
+ eventType: string;
36
+ /**
37
+ * Handler function
38
+ */
39
+ handler: NotificationHandler;
40
+ /**
41
+ * Optional filter
42
+ */
43
+ filter?: EventFilter;
44
+ /**
45
+ * Unsubscribe from this event
46
+ */
47
+ unsubscribe(): void;
48
+ }
49
+ //# sourceMappingURL=notification-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-types.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/interfaces/notification-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,kBAAkB,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,mBAAmB,CAAC;IAE7B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;OAEG;IACH,WAAW,IAAI,IAAI,CAAC;CACrB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import { oObject } from '../o-object.js';
2
+ import { oNotificationEvent } from './events/o-notification-event.js';
3
+ import { EventFilter, NotificationHandler, Subscription } from './interfaces/notification-types.js';
4
+ /**
5
+ * Abstract notification manager - transport agnostic
6
+ * NO dependencies on libp2p, HTTP, or any specific transport
7
+ *
8
+ * Subclasses implement setupListeners() to wire up transport-specific events
9
+ */
10
+ export declare abstract class oNotificationManager extends oObject {
11
+ private eventTarget;
12
+ private subscriptions;
13
+ constructor();
14
+ /**
15
+ * Subscribe to a notification event
16
+ *
17
+ * @param eventType - The event type to subscribe to (e.g., "node:connected", "child:joined")
18
+ * @param handler - The handler function to call when event is emitted
19
+ * @param filter - Optional filter to apply to events
20
+ * @returns Subscription handle
21
+ */
22
+ on(eventType: string, handler: NotificationHandler, filter?: EventFilter): Subscription;
23
+ /**
24
+ * Unsubscribe from a notification event
25
+ */
26
+ off(subscription: Subscription): void;
27
+ /**
28
+ * Emit a notification event
29
+ */
30
+ emit(event: oNotificationEvent): void;
31
+ /**
32
+ * Check if an event matches a filter
33
+ */
34
+ protected matchesFilter(event: oNotificationEvent, filter: EventFilter): boolean;
35
+ /**
36
+ * Get all active subscriptions for an event type
37
+ */
38
+ getSubscriptions(eventType?: string): Subscription[];
39
+ /**
40
+ * Get count of active subscriptions
41
+ */
42
+ getSubscriptionCount(eventType?: string): number;
43
+ /**
44
+ * Subclasses must implement this to wire up transport-specific listeners
45
+ * This is where libp2p/HTTP/WebSocket events get connected
46
+ */
47
+ protected abstract setupListeners(): void | Promise<void>;
48
+ /**
49
+ * Initialize the notification manager
50
+ * Calls setupListeners() to wire up transport events
51
+ */
52
+ initialize(): Promise<void>;
53
+ /**
54
+ * Cleanup all subscriptions
55
+ */
56
+ teardown(): Promise<void>;
57
+ }
58
+ //# sourceMappingURL=o-notification.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-notification.manager.d.ts","sourceRoot":"","sources":["../../../../src/core/lib/o-notification.manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,YAAY,EACb,MAAM,oCAAoC,CAAC;AAG5C;;;;;GAKG;AACH,8BAAsB,oBAAqB,SAAQ,OAAO;IACxD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAiC;;IAQtD;;;;;;;OAOG;IACH,EAAE,CACA,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,YAAY;IAoDf;;OAEG;IACH,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IA6BrC;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAUrC;;OAEG;IACH,SAAS,CAAC,aAAa,CACrB,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO;IAyBV;;OAEG;IACH,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE;IAcpD;;OAEG;IACH,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAIhD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzD;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC"}
@@ -0,0 +1,159 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { oObject } from '../o-object.js';
3
+ import { EventFilters } from './utils/event-filters.js';
4
+ /**
5
+ * Abstract notification manager - transport agnostic
6
+ * NO dependencies on libp2p, HTTP, or any specific transport
7
+ *
8
+ * Subclasses implement setupListeners() to wire up transport-specific events
9
+ */
10
+ export class oNotificationManager extends oObject {
11
+ constructor() {
12
+ super();
13
+ this.eventTarget = new EventTarget();
14
+ this.subscriptions = new Map();
15
+ }
16
+ /**
17
+ * Subscribe to a notification event
18
+ *
19
+ * @param eventType - The event type to subscribe to (e.g., "node:connected", "child:joined")
20
+ * @param handler - The handler function to call when event is emitted
21
+ * @param filter - Optional filter to apply to events
22
+ * @returns Subscription handle
23
+ */
24
+ on(eventType, handler, filter) {
25
+ const subscriptionId = uuidv4();
26
+ const subscription = {
27
+ id: subscriptionId,
28
+ eventType,
29
+ handler,
30
+ filter,
31
+ unsubscribe: () => {
32
+ this.off(subscription);
33
+ },
34
+ };
35
+ // Add to subscriptions map
36
+ if (!this.subscriptions.has(eventType)) {
37
+ this.subscriptions.set(eventType, new Set());
38
+ }
39
+ this.subscriptions.get(eventType).add(subscription);
40
+ // Add DOM event listener
41
+ const wrappedHandler = async (event) => {
42
+ if (!(event instanceof CustomEvent)) {
43
+ return;
44
+ }
45
+ const notificationEvent = event.detail;
46
+ // Apply filter if provided
47
+ if (filter && !this.matchesFilter(notificationEvent, filter)) {
48
+ return;
49
+ }
50
+ try {
51
+ await handler(notificationEvent);
52
+ }
53
+ catch (error) {
54
+ this.logger.error(`Error in notification handler for ${eventType}:`, error);
55
+ }
56
+ };
57
+ // Store wrapped handler for later removal
58
+ subscription._wrappedHandler = wrappedHandler;
59
+ this.eventTarget.addEventListener(eventType, wrappedHandler);
60
+ this.logger.debug(`Subscribed to ${eventType} with ID ${subscriptionId}`);
61
+ return subscription;
62
+ }
63
+ /**
64
+ * Unsubscribe from a notification event
65
+ */
66
+ off(subscription) {
67
+ const subscriptionsForType = this.subscriptions.get(subscription.eventType);
68
+ if (!subscriptionsForType) {
69
+ return;
70
+ }
71
+ // Remove from subscriptions set
72
+ subscriptionsForType.delete(subscription);
73
+ // Remove DOM event listener
74
+ const wrappedHandler = subscription._wrappedHandler;
75
+ if (wrappedHandler) {
76
+ this.eventTarget.removeEventListener(subscription.eventType, wrappedHandler);
77
+ }
78
+ // Clean up empty sets
79
+ if (subscriptionsForType.size === 0) {
80
+ this.subscriptions.delete(subscription.eventType);
81
+ }
82
+ this.logger.debug(`Unsubscribed from ${subscription.eventType} with ID ${subscription.id}`);
83
+ }
84
+ /**
85
+ * Emit a notification event
86
+ */
87
+ emit(event) {
88
+ this.logger.debug(`Emitting event: ${event.type}`, event.toJSON());
89
+ const customEvent = new CustomEvent(event.type, {
90
+ detail: event,
91
+ });
92
+ this.eventTarget.dispatchEvent(customEvent);
93
+ }
94
+ /**
95
+ * Check if an event matches a filter
96
+ */
97
+ matchesFilter(event, filter) {
98
+ // Check event type filter
99
+ if (filter.eventTypes && !filter.eventTypes.includes(event.type)) {
100
+ return false;
101
+ }
102
+ // Check address pattern filter
103
+ if (filter.addressPattern) {
104
+ const eventAddress = EventFilters.getEventAddress(event);
105
+ if (!eventAddress ||
106
+ !EventFilters.addressMatches(eventAddress, filter.addressPattern)) {
107
+ return false;
108
+ }
109
+ }
110
+ // Check custom filter
111
+ if (filter.customFilter && !filter.customFilter(event)) {
112
+ return false;
113
+ }
114
+ return true;
115
+ }
116
+ /**
117
+ * Get all active subscriptions for an event type
118
+ */
119
+ getSubscriptions(eventType) {
120
+ if (eventType) {
121
+ const subs = this.subscriptions.get(eventType);
122
+ return subs ? Array.from(subs) : [];
123
+ }
124
+ // Return all subscriptions
125
+ const allSubs = [];
126
+ for (const subs of this.subscriptions.values()) {
127
+ allSubs.push(...Array.from(subs));
128
+ }
129
+ return allSubs;
130
+ }
131
+ /**
132
+ * Get count of active subscriptions
133
+ */
134
+ getSubscriptionCount(eventType) {
135
+ return this.getSubscriptions(eventType).length;
136
+ }
137
+ /**
138
+ * Initialize the notification manager
139
+ * Calls setupListeners() to wire up transport events
140
+ */
141
+ async initialize() {
142
+ this.logger.debug('Initializing notification manager...');
143
+ await this.setupListeners();
144
+ this.logger.debug('Notification manager initialized');
145
+ }
146
+ /**
147
+ * Cleanup all subscriptions
148
+ */
149
+ async teardown() {
150
+ this.logger.debug('Tearing down notification manager...');
151
+ // Unsubscribe all
152
+ const allSubs = this.getSubscriptions();
153
+ for (const sub of allSubs) {
154
+ this.off(sub);
155
+ }
156
+ this.subscriptions.clear();
157
+ this.logger.debug('Notification manager torn down');
158
+ }
159
+ }
@@ -0,0 +1,38 @@
1
+ import { oAddress } from '../../../router/o-address.js';
2
+ import { oNotificationEvent } from '../events/o-notification-event.js';
3
+ /**
4
+ * Utility functions for filtering notification events
5
+ */
6
+ export declare class EventFilters {
7
+ /**
8
+ * Check if an address matches a pattern
9
+ * Supports:
10
+ * - Regex patterns: any string starting with '/' or containing regex special chars
11
+ * - Wildcards: * for single segment, ** for multiple segments
12
+ *
13
+ * Examples:
14
+ * Wildcards:
15
+ * - "o://leader/*" matches "o://leader/child1" but not "o://leader/child1/grandchild"
16
+ * - "o://leader/**" matches "o://leader/child1" and "o://leader/child1/grandchild"
17
+ * - "o://leader/tools/*" matches "o://leader/tools/calculator"
18
+ *
19
+ * Regex (use standard regex patterns with / delimiters):
20
+ * - /^o:\/\/leader\/.*\/ matches any path starting with o://leader/
21
+ * - /tool-\d+/ matches paths with tool-1, tool-99, etc.
22
+ * - /o:\/\/leader\/(analytics|reporting)\// matches analytics or reporting paths
23
+ */
24
+ static addressMatches(address: oAddress, pattern: string): boolean;
25
+ /**
26
+ * Filter events to only include direct children of a parent address
27
+ */
28
+ static childrenOnly(event: oNotificationEvent, parentAddress: oAddress): boolean;
29
+ /**
30
+ * Filter events to only include descendants (children, grandchildren, etc.) of an ancestor address
31
+ */
32
+ static descendantsOnly(event: oNotificationEvent, ancestorAddress: oAddress): boolean;
33
+ /**
34
+ * Get the address from an event based on its type
35
+ */
36
+ static getEventAddress(event: oNotificationEvent): oAddress | null;
37
+ }
38
+ //# sourceMappingURL=event-filters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-filters.d.ts","sourceRoot":"","sources":["../../../../../src/core/lib/utils/event-filters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAUvE;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAiElE;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,KAAK,EAAE,kBAAkB,EACzB,aAAa,EAAE,QAAQ,GACtB,OAAO;IAiCV;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,KAAK,EAAE,kBAAkB,EACzB,eAAe,EAAE,QAAQ,GACxB,OAAO;IAgDV;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,QAAQ,GAAG,IAAI;CAcnE"}
@@ -0,0 +1,159 @@
1
+ import { ChildJoinedEvent, ChildLeftEvent, } from '../events/hierarchy-events.js';
2
+ import { NodeConnectedEvent, NodeDisconnectedEvent, } from '../events/node-events.js';
3
+ /**
4
+ * Utility functions for filtering notification events
5
+ */
6
+ export class EventFilters {
7
+ /**
8
+ * Check if an address matches a pattern
9
+ * Supports:
10
+ * - Regex patterns: any string starting with '/' or containing regex special chars
11
+ * - Wildcards: * for single segment, ** for multiple segments
12
+ *
13
+ * Examples:
14
+ * Wildcards:
15
+ * - "o://leader/*" matches "o://leader/child1" but not "o://leader/child1/grandchild"
16
+ * - "o://leader/**" matches "o://leader/child1" and "o://leader/child1/grandchild"
17
+ * - "o://leader/tools/*" matches "o://leader/tools/calculator"
18
+ *
19
+ * Regex (use standard regex patterns with / delimiters):
20
+ * - /^o:\/\/leader\/.*\/ matches any path starting with o://leader/
21
+ * - /tool-\d+/ matches paths with tool-1, tool-99, etc.
22
+ * - /o:\/\/leader\/(analytics|reporting)\// matches analytics or reporting paths
23
+ */
24
+ static addressMatches(address, pattern) {
25
+ const addressStr = address.toString();
26
+ // Check if pattern is a regex (starts with / or contains regex special chars like ^, $, [], (), |)
27
+ const isRegex = pattern.startsWith('/') || /[\^\$\[\]\(\)\|]/.test(pattern);
28
+ if (isRegex) {
29
+ try {
30
+ // Extract regex pattern and flags if format is /pattern/flags
31
+ let regexPattern = pattern;
32
+ let flags = '';
33
+ if (pattern.startsWith('/')) {
34
+ const lastSlash = pattern.lastIndexOf('/');
35
+ if (lastSlash > 0) {
36
+ regexPattern = pattern.slice(1, lastSlash);
37
+ flags = pattern.slice(lastSlash + 1);
38
+ }
39
+ }
40
+ const regex = new RegExp(regexPattern, flags);
41
+ return regex.test(addressStr);
42
+ }
43
+ catch (e) {
44
+ // If regex compilation fails, fall back to exact match
45
+ console.warn(`Invalid regex pattern: ${pattern}`, e);
46
+ return addressStr === pattern;
47
+ }
48
+ }
49
+ // Handle wildcard patterns (backward compatibility)
50
+ const addressPaths = address.paths;
51
+ const patternPaths = pattern.replace('o://', '').split('/').filter(Boolean);
52
+ // Handle exact match
53
+ if (addressStr === pattern) {
54
+ return true;
55
+ }
56
+ // Handle wildcard patterns
57
+ for (let i = 0; i < patternPaths.length; i++) {
58
+ const patternSegment = patternPaths[i];
59
+ // ** matches rest of path
60
+ if (patternSegment === '**') {
61
+ return true;
62
+ }
63
+ // * matches single segment
64
+ if (patternSegment === '*') {
65
+ if (i >= addressPaths.length) {
66
+ return false;
67
+ }
68
+ continue;
69
+ }
70
+ // Exact segment match
71
+ if (addressPaths[i] !== patternSegment) {
72
+ return false;
73
+ }
74
+ }
75
+ // Pattern must match full address length (unless ended with **)
76
+ return addressPaths.length === patternPaths.length;
77
+ }
78
+ /**
79
+ * Filter events to only include direct children of a parent address
80
+ */
81
+ static childrenOnly(event, parentAddress) {
82
+ // Check if event is a hierarchy event
83
+ if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
84
+ return event.parentAddress.toString() === parentAddress.toString();
85
+ }
86
+ // For node events, check if the node is a direct child
87
+ if (event instanceof NodeConnectedEvent ||
88
+ event instanceof NodeDisconnectedEvent) {
89
+ const nodeAddr = event.nodeAddress;
90
+ const parentPaths = parentAddress.paths;
91
+ const nodePaths = nodeAddr.paths;
92
+ // Direct child has exactly one more path segment
93
+ if (nodePaths.length !== parentPaths.length + 1) {
94
+ return false;
95
+ }
96
+ // Check all parent segments match
97
+ for (let i = 0; i < parentPaths.length; i++) {
98
+ if (parentPaths[i] !== nodePaths[i]) {
99
+ return false;
100
+ }
101
+ }
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+ /**
107
+ * Filter events to only include descendants (children, grandchildren, etc.) of an ancestor address
108
+ */
109
+ static descendantsOnly(event, ancestorAddress) {
110
+ // Check if event is a hierarchy event
111
+ if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
112
+ // Check if parent is a descendant of or equal to ancestor
113
+ const parentPaths = event.parentAddress.paths;
114
+ const ancestorPaths = ancestorAddress.paths;
115
+ if (parentPaths.length < ancestorPaths.length) {
116
+ return false;
117
+ }
118
+ // Check all ancestor segments match
119
+ for (let i = 0; i < ancestorPaths.length; i++) {
120
+ if (ancestorPaths[i] !== parentPaths[i]) {
121
+ return false;
122
+ }
123
+ }
124
+ return true;
125
+ }
126
+ // For node events, check if the node is a descendant
127
+ if (event instanceof NodeConnectedEvent ||
128
+ event instanceof NodeDisconnectedEvent) {
129
+ const nodeAddr = event.nodeAddress;
130
+ const nodePaths = nodeAddr.paths;
131
+ const ancestorPaths = ancestorAddress.paths;
132
+ // Descendant must have more path segments
133
+ if (nodePaths.length <= ancestorPaths.length) {
134
+ return false;
135
+ }
136
+ // Check all ancestor segments match
137
+ for (let i = 0; i < ancestorPaths.length; i++) {
138
+ if (ancestorPaths[i] !== nodePaths[i]) {
139
+ return false;
140
+ }
141
+ }
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * Get the address from an event based on its type
148
+ */
149
+ static getEventAddress(event) {
150
+ if (event instanceof NodeConnectedEvent ||
151
+ event instanceof NodeDisconnectedEvent) {
152
+ return event.nodeAddress;
153
+ }
154
+ if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
155
+ return event.childAddress;
156
+ }
157
+ return null;
158
+ }
159
+ }
@@ -14,6 +14,8 @@ import { oRequestManager } from './lib/o-request.manager.js';
14
14
  import { oTransport } from '../transports/o-transport.js';
15
15
  import { oRouter } from '../router/o-router.js';
16
16
  import { oRequest } from '../connection/o-request.js';
17
+ import { oNotificationManager } from './lib/o-notification.manager.js';
18
+ import { oNotificationEvent, EventFilter, NotificationHandler, Subscription } from './lib/events/index.js';
17
19
  export declare abstract class oCore extends oObject {
18
20
  readonly config: oCoreConfig;
19
21
  address: oAddress;
@@ -24,6 +26,7 @@ export declare abstract class oCore extends oObject {
24
26
  metrics: oMetrics;
25
27
  requestManager: oRequestManager;
26
28
  router: oRouter;
29
+ notificationManager: oNotificationManager;
27
30
  private heartbeatInterval?;
28
31
  constructor(config: oCoreConfig);
29
32
  get isLeader(): boolean;
@@ -110,6 +113,15 @@ export declare abstract class oCore extends oObject {
110
113
  abstract initializeRouter(): void;
111
114
  abstract unregister(): Promise<void>;
112
115
  abstract register(): Promise<void>;
116
+ protected abstract createNotificationManager(): oNotificationManager;
117
+ /**
118
+ * Emit a notification event
119
+ */
120
+ protected notify(event: oNotificationEvent): void;
121
+ /**
122
+ * Subscribe to notification events
123
+ */
124
+ protected onNotification(eventType: string, handler: NotificationHandler, filter?: EventFilter): Subscription;
113
125
  initialize(): Promise<void>;
114
126
  get isRunning(): boolean;
115
127
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"o-core.d.ts","sourceRoot":"","sources":["../../../src/core/o-core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"o-core.d.ts","sourceRoot":"","sources":["../../../src/core/o-core.ts"],"names":[],"mappings":"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"}
@@ -183,8 +183,29 @@ export class oCore extends oObject {
183
183
  removeChildNode(node) {
184
184
  this.hierarchyManager.removeChild(node.address);
185
185
  }
186
+ /**
187
+ * Emit a notification event
188
+ */
189
+ notify(event) {
190
+ if (this.notificationManager) {
191
+ this.notificationManager.emit(event);
192
+ }
193
+ }
194
+ /**
195
+ * Subscribe to notification events
196
+ */
197
+ onNotification(eventType, handler, filter) {
198
+ if (!this.notificationManager) {
199
+ throw new Error('Notification manager not initialized');
200
+ }
201
+ return this.notificationManager.on(eventType, handler, filter);
202
+ }
186
203
  // initialize
187
- async initialize() { }
204
+ async initialize() {
205
+ // Create and initialize notification manager
206
+ this.notificationManager = this.createNotificationManager();
207
+ await this.notificationManager.initialize();
208
+ }
188
209
  get isRunning() {
189
210
  return (this.state === NodeState.RUNNING ||
190
211
  this.state === NodeState.STOPPING ||
@@ -318,6 +339,10 @@ export class oCore extends oObject {
318
339
  this.logger.debug('Child stopped: ' + child.toString());
319
340
  }
320
341
  this.hierarchyManager.clear();
342
+ // Teardown notification manager
343
+ if (this.notificationManager) {
344
+ await this.notificationManager.teardown();
345
+ }
321
346
  }
322
347
  get dependencies() {
323
348
  return this.config.dependencies?.map((d) => new oDependency(d)) || [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-core",
3
- "version": "0.7.12-alpha.5",
3
+ "version": "0.7.12-alpha.6",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -55,11 +55,11 @@
55
55
  "typescript": "^5.8.3"
56
56
  },
57
57
  "dependencies": {
58
- "@olane/o-protocol": "0.7.12-alpha.5",
58
+ "@olane/o-protocol": "0.7.12-alpha.6",
59
59
  "chalk": "^5.4.1",
60
60
  "debug": "^4.4.1",
61
61
  "dotenv": "^16.5.0",
62
62
  "multiformats": "^13.3.7"
63
63
  },
64
- "gitHead": "5c45d9050148c0596b4adeea3d66647c37577a8c"
64
+ "gitHead": "fad0400ec59d38b163bd996d967cd46c6a5a9e0a"
65
65
  }