@bernierllc/flow-lifecycle-events 0.0.1 → 0.1.0

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.
@@ -0,0 +1,40 @@
1
+ import type { FlowLifecycleEventMap, FlowLifecycleEventName } from './types';
2
+ /**
3
+ * Type-safe listener function for a specific flow lifecycle event.
4
+ */
5
+ export type FlowLifecycleListener<K extends FlowLifecycleEventName> = (payload: FlowLifecycleEventMap[K]) => void;
6
+ /**
7
+ * Typed lifecycle event emitter for flow engine observability.
8
+ *
9
+ * Wraps Node.js `EventEmitter` to provide a type-safe API for all flow
10
+ * lifecycle events: item operations, definition management, and engine status.
11
+ *
12
+ * This emitter is for internal observability only — it is distinct from
13
+ * Nevar triggers which drive business logic.
14
+ */
15
+ export declare class FlowLifecycleEmitter {
16
+ private readonly emitter;
17
+ constructor();
18
+ /**
19
+ * Subscribe to a lifecycle event with a typed listener.
20
+ */
21
+ on<K extends FlowLifecycleEventName>(event: K, listener: FlowLifecycleListener<K>): void;
22
+ /**
23
+ * Unsubscribe a listener from a lifecycle event.
24
+ */
25
+ off<K extends FlowLifecycleEventName>(event: K, listener: FlowLifecycleListener<K>): void;
26
+ /**
27
+ * Emit a lifecycle event with a typed payload.
28
+ *
29
+ * Wraps errors thrown by listeners in `FlowLifecycleError` with cause chaining.
30
+ */
31
+ emit<K extends FlowLifecycleEventName>(event: K, payload: FlowLifecycleEventMap[K]): void;
32
+ /**
33
+ * Remove all listeners for a specific event, or all listeners if no event is specified.
34
+ */
35
+ removeAllListeners(event?: FlowLifecycleEventName): void;
36
+ /**
37
+ * Get the number of listeners for a lifecycle event.
38
+ */
39
+ listenerCount(event: FlowLifecycleEventName): number;
40
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FlowLifecycleEmitter = void 0;
11
+ const node_events_1 = require("node:events");
12
+ const errors_1 = require("./errors");
13
+ /**
14
+ * Typed lifecycle event emitter for flow engine observability.
15
+ *
16
+ * Wraps Node.js `EventEmitter` to provide a type-safe API for all flow
17
+ * lifecycle events: item operations, definition management, and engine status.
18
+ *
19
+ * This emitter is for internal observability only — it is distinct from
20
+ * Nevar triggers which drive business logic.
21
+ */
22
+ class FlowLifecycleEmitter {
23
+ emitter;
24
+ constructor() {
25
+ this.emitter = new node_events_1.EventEmitter();
26
+ }
27
+ /**
28
+ * Subscribe to a lifecycle event with a typed listener.
29
+ */
30
+ on(event, listener) {
31
+ this.emitter.on(event, listener);
32
+ }
33
+ /**
34
+ * Unsubscribe a listener from a lifecycle event.
35
+ */
36
+ off(event, listener) {
37
+ this.emitter.off(event, listener);
38
+ }
39
+ /**
40
+ * Emit a lifecycle event with a typed payload.
41
+ *
42
+ * Wraps errors thrown by listeners in `FlowLifecycleError` with cause chaining.
43
+ */
44
+ emit(event, payload) {
45
+ try {
46
+ this.emitter.emit(event, payload);
47
+ }
48
+ catch (error) {
49
+ throw new errors_1.FlowLifecycleError(`Failed to emit lifecycle event: ${event}`, {
50
+ cause: error instanceof Error ? error : new Error(String(error)),
51
+ code: 'LIFECYCLE_EMIT_ERROR',
52
+ context: { event },
53
+ });
54
+ }
55
+ }
56
+ /**
57
+ * Remove all listeners for a specific event, or all listeners if no event is specified.
58
+ */
59
+ removeAllListeners(event) {
60
+ if (event) {
61
+ this.emitter.removeAllListeners(event);
62
+ }
63
+ else {
64
+ this.emitter.removeAllListeners();
65
+ }
66
+ }
67
+ /**
68
+ * Get the number of listeners for a lifecycle event.
69
+ */
70
+ listenerCount(event) {
71
+ return this.emitter.listenerCount(event);
72
+ }
73
+ }
74
+ exports.FlowLifecycleEmitter = FlowLifecycleEmitter;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Error class for flow lifecycle event operations.
3
+ */
4
+ export declare class FlowLifecycleError extends Error {
5
+ readonly code: string;
6
+ readonly context?: Record<string, unknown>;
7
+ constructor(message: string, options?: {
8
+ cause?: Error;
9
+ code?: string;
10
+ context?: Record<string, unknown>;
11
+ });
12
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FlowLifecycleError = void 0;
11
+ /**
12
+ * Error class for flow lifecycle event operations.
13
+ */
14
+ class FlowLifecycleError extends Error {
15
+ code;
16
+ context;
17
+ constructor(message, options) {
18
+ super(message, { cause: options?.cause });
19
+ this.name = 'FlowLifecycleError';
20
+ this.code = options?.code ?? 'FLOW_LIFECYCLE_ERROR';
21
+ this.context = options?.context;
22
+ }
23
+ }
24
+ exports.FlowLifecycleError = FlowLifecycleError;
@@ -0,0 +1,8 @@
1
+ export { FlowLifecycleEmitter } from './emitter';
2
+ export type { FlowLifecycleListener } from './emitter';
3
+ export type { FlowLifecycleEventMap, FlowLifecycleEventName, FlowDefinitionCreatedPayload, FlowDefinitionUpdatedPayload, FlowDefinitionDeletedPayload, FlowEngineStartedPayload, FlowEngineStoppedPayload, FlowEngineErrorPayload, } from './types';
4
+ export { FlowLifecycleError } from './errors';
5
+ /**
6
+ * All flow lifecycle event names as a readonly array, useful for iteration and validation.
7
+ */
8
+ export declare const FLOW_LIFECYCLE_EVENT_NAMES: readonly ["flow.item.created", "flow.item.transitioned", "flow.item.entered_stage", "flow.item.exited_stage", "flow.item.assigned", "flow.item.completed", "flow.item.stale", "flow.definition.created", "flow.definition.updated", "flow.definition.deleted", "flow.engine.started", "flow.engine.stopped", "flow.engine.error"];
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FLOW_LIFECYCLE_EVENT_NAMES = exports.FlowLifecycleError = exports.FlowLifecycleEmitter = void 0;
11
+ var emitter_1 = require("./emitter");
12
+ Object.defineProperty(exports, "FlowLifecycleEmitter", { enumerable: true, get: function () { return emitter_1.FlowLifecycleEmitter; } });
13
+ var errors_1 = require("./errors");
14
+ Object.defineProperty(exports, "FlowLifecycleError", { enumerable: true, get: function () { return errors_1.FlowLifecycleError; } });
15
+ /**
16
+ * All flow lifecycle event names as a readonly array, useful for iteration and validation.
17
+ */
18
+ exports.FLOW_LIFECYCLE_EVENT_NAMES = [
19
+ 'flow.item.created',
20
+ 'flow.item.transitioned',
21
+ 'flow.item.entered_stage',
22
+ 'flow.item.exited_stage',
23
+ 'flow.item.assigned',
24
+ 'flow.item.completed',
25
+ 'flow.item.stale',
26
+ 'flow.definition.created',
27
+ 'flow.definition.updated',
28
+ 'flow.definition.deleted',
29
+ 'flow.engine.started',
30
+ 'flow.engine.stopped',
31
+ 'flow.engine.error',
32
+ ];
@@ -0,0 +1,44 @@
1
+ import type { FlowItemCreatedPayload, FlowItemTransitionedPayload, FlowItemEnteredStagePayload, FlowItemExitedStagePayload, FlowItemAssignedPayload, FlowItemCompletedPayload, FlowItemStalePayload } from '@bernierllc/flow-types';
2
+ export interface FlowDefinitionCreatedPayload {
3
+ flowId: string;
4
+ name: string;
5
+ }
6
+ export interface FlowDefinitionUpdatedPayload {
7
+ flowId: string;
8
+ changes: string[];
9
+ }
10
+ export interface FlowDefinitionDeletedPayload {
11
+ flowId: string;
12
+ }
13
+ export interface FlowEngineStartedPayload {
14
+ timestamp: Date;
15
+ }
16
+ export interface FlowEngineStoppedPayload {
17
+ timestamp: Date;
18
+ }
19
+ export interface FlowEngineErrorPayload {
20
+ error: Error;
21
+ context: string;
22
+ }
23
+ /**
24
+ * Type-safe mapping of all flow lifecycle event names to their payload types.
25
+ */
26
+ export interface FlowLifecycleEventMap {
27
+ 'flow.item.created': FlowItemCreatedPayload;
28
+ 'flow.item.transitioned': FlowItemTransitionedPayload;
29
+ 'flow.item.entered_stage': FlowItemEnteredStagePayload;
30
+ 'flow.item.exited_stage': FlowItemExitedStagePayload;
31
+ 'flow.item.assigned': FlowItemAssignedPayload;
32
+ 'flow.item.completed': FlowItemCompletedPayload;
33
+ 'flow.item.stale': FlowItemStalePayload;
34
+ 'flow.definition.created': FlowDefinitionCreatedPayload;
35
+ 'flow.definition.updated': FlowDefinitionUpdatedPayload;
36
+ 'flow.definition.deleted': FlowDefinitionDeletedPayload;
37
+ 'flow.engine.started': FlowEngineStartedPayload;
38
+ 'flow.engine.stopped': FlowEngineStoppedPayload;
39
+ 'flow.engine.error': FlowEngineErrorPayload;
40
+ }
41
+ /**
42
+ * Union type of all flow lifecycle event names.
43
+ */
44
+ export type FlowLifecycleEventName = keyof FlowLifecycleEventMap;
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,10 +1,56 @@
1
1
  {
2
2
  "name": "@bernierllc/flow-lifecycle-events",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @bernierllc/flow-lifecycle-events",
3
+ "version": "0.1.0",
4
+ "description": "Typed lifecycle event emitter for flow engine observability",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist/**/*",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
5
12
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
13
+ "flow-engine",
14
+ "lifecycle",
15
+ "events",
16
+ "observability",
17
+ "typed-emitter"
18
+ ],
19
+ "author": "Bernier LLC",
20
+ "license": "SEE LICENSE IN LICENSE",
21
+ "publishConfig": {
22
+ "access": "public",
23
+ "registry": "https://registry.npmjs.org/"
24
+ },
25
+ "engines": {
26
+ "node": ">=16.0.0"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/bernierllc/tools.git",
31
+ "directory": "packages/service/flow-lifecycle-events"
32
+ },
33
+ "dependencies": {
34
+ "@bernierllc/flow-types": "0.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/jest": "^29.5.0",
38
+ "@types/node": "^20.0.0",
39
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
40
+ "@typescript-eslint/parser": "^6.0.0",
41
+ "eslint": "^8.0.0",
42
+ "jest": "^29.5.0",
43
+ "rimraf": "^5.0.0",
44
+ "ts-jest": "^29.1.0",
45
+ "typescript": "^5.0.0"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc",
49
+ "prebuild": "npm run clean",
50
+ "clean": "rimraf dist",
51
+ "test": "jest",
52
+ "test:run": "jest",
53
+ "test:coverage": "jest --coverage",
54
+ "lint": "eslint src __tests__ --ext .ts"
55
+ }
56
+ }
package/README.md DELETED
@@ -1,45 +0,0 @@
1
- # @bernierllc/flow-lifecycle-events
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@bernierllc/flow-lifecycle-events`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**