ultravisor-beacon-capability 1.0.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.
Files changed (38) hide show
  1. package/README.md +106 -0
  2. package/docs/.nojekyll +0 -0
  3. package/docs/README.md +103 -0
  4. package/docs/_brand.json +18 -0
  5. package/docs/_cover.md +13 -0
  6. package/docs/_sidebar.md +31 -0
  7. package/docs/_topbar.md +5 -0
  8. package/docs/_version.json +7 -0
  9. package/docs/api/README.md +44 -0
  10. package/docs/api/action-convention.md +148 -0
  11. package/docs/api/add-action.md +68 -0
  12. package/docs/api/beacon-capability.md +89 -0
  13. package/docs/api/build-action-map.md +88 -0
  14. package/docs/api/connect.md +81 -0
  15. package/docs/api/disconnect.md +50 -0
  16. package/docs/api/is-connected.md +33 -0
  17. package/docs/api/lifecycle-hooks.md +115 -0
  18. package/docs/architecture.md +237 -0
  19. package/docs/css/docuserve.css +327 -0
  20. package/docs/examples/README.md +58 -0
  21. package/docs/examples/certificate-expiry-monitor.md +212 -0
  22. package/docs/examples/docker-container-management.md +265 -0
  23. package/docs/examples/log-archive-and-upload.md +214 -0
  24. package/docs/examples/log-file-cleanup.md +199 -0
  25. package/docs/examples/mysql-maintenance.md +253 -0
  26. package/docs/examples/postgresql-aggregation.md +247 -0
  27. package/docs/examples/rest-api-health-check.md +213 -0
  28. package/docs/examples/rest-endpoint-sync.md +240 -0
  29. package/docs/examples/server-metrics-collection.md +199 -0
  30. package/docs/examples/shell-commands.md +176 -0
  31. package/docs/index.html +39 -0
  32. package/docs/quickstart.md +199 -0
  33. package/docs/retold-catalog.json +85 -0
  34. package/docs/retold-keyword-index.json +10642 -0
  35. package/package.json +33 -0
  36. package/source/Ultravisor-Beacon-Capability-ActionMap.cjs +132 -0
  37. package/source/Ultravisor-Beacon-Capability.cjs +276 -0
  38. package/test/Ultravisor-Beacon-Capability_tests.js +744 -0
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ Ultravisor Beacon Capability
2
+ ============================
3
+
4
+ A convention-based base class for building Ultravisor beacon capabilities with minimal boilerplate. Extend the class, define action methods with the `action` prefix, and call `connect()` -- the module handles beacon registration, transport, and lifecycle automatically.
5
+
6
+ ## Features
7
+
8
+ - **Convention Over Configuration** -- Define actions as methods prefixed with `action`; schemas and descriptions as companion getters
9
+ - **Automatic Discovery** -- Actions are discovered by walking the prototype chain, including multi-level inheritance
10
+ - **Simplified Handler Signature** -- Settings are pre-extracted from work items so handlers receive `(pSettings, pWorkItem, fCallback, fReportProgress)`
11
+ - **Lifecycle Hooks** -- Override `onInitialize()` and `onShutdown()` for setup and teardown (database connections, service handles, etc.)
12
+ - **Explicit Registration Escape Hatch** -- Use `addAction()` for dynamic or runtime-generated actions alongside convention-based ones
13
+ - **Fable Ecosystem Integration** -- Extends `fable-serviceproviderbase`; composes `ultravisor-beacon` internally
14
+
15
+ ## Documentation
16
+
17
+ Comprehensive documentation is available in the [docs](./docs) folder:
18
+
19
+ - [Overview](./docs/README.md) -- Introduction and getting started
20
+ - [Quick Start](./docs/quickstart.md) -- Step-by-step setup guide
21
+ - [Architecture](./docs/architecture.md) -- System design and mermaid diagrams
22
+ - [API Reference](./docs/api/README.md) -- All classes and methods
23
+ - [Examples](./docs/examples/README.md) -- Real-world usage patterns
24
+
25
+ ## Install
26
+
27
+ ```sh
28
+ $ npm install ultravisor-beacon-capability
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```javascript
34
+ const libFable = require('fable');
35
+ const libBeaconCapability = require('ultravisor-beacon-capability');
36
+
37
+ class DiskCleanup extends libBeaconCapability
38
+ {
39
+ constructor(pFable, pOptions, pServiceHash)
40
+ {
41
+ super(pFable, pOptions, pServiceHash);
42
+ this.serviceType = 'DiskCleanup';
43
+ this.capabilityName = 'DiskCleanup';
44
+ }
45
+
46
+ get actionPurgeTempFiles_Description()
47
+ {
48
+ return 'Remove temporary files older than N days';
49
+ }
50
+
51
+ get actionPurgeTempFiles_Schema()
52
+ {
53
+ return [
54
+ { Name: 'Directory', DataType: 'String', Required: true },
55
+ { Name: 'MaxAgeDays', DataType: 'Integer', Required: true },
56
+ { Name: 'DryRun', DataType: 'Boolean', Required: false }
57
+ ];
58
+ }
59
+
60
+ actionPurgeTempFiles(pSettings, pWorkItem, fCallback)
61
+ {
62
+ let tmpCmd = `find ${pSettings.Directory} -type f -mtime +${pSettings.MaxAgeDays}`;
63
+ if (!pSettings.DryRun)
64
+ {
65
+ tmpCmd += ' -delete';
66
+ }
67
+ require('child_process').exec(tmpCmd, (pError, pStdOut) =>
68
+ {
69
+ if (pError) return fCallback(pError);
70
+ return fCallback(null, { Outputs: { Result: pStdOut, DryRun: !!pSettings.DryRun } });
71
+ });
72
+ }
73
+ }
74
+
75
+ let tmpFable = new libFable({ Product: 'DiskCleanup', ProductVersion: '1.0.0' });
76
+ tmpFable.addServiceType('DiskCleanup', DiskCleanup);
77
+ let tmpCleanup = tmpFable.instantiateServiceProvider('DiskCleanup');
78
+
79
+ tmpCleanup.connect(
80
+ {
81
+ ServerURL: 'http://ultravisor.local:54321',
82
+ Name: 'disk-cleanup-worker'
83
+ },
84
+ (pError, pBeaconInfo) =>
85
+ {
86
+ if (pError) throw pError;
87
+ console.log('Beacon online:', pBeaconInfo.BeaconID);
88
+ });
89
+ ```
90
+
91
+ Once connected, the Ultravisor server automatically creates a task type `beacon-diskcleanup-purgetempfiles` that can be triggered manually, scheduled, or wired into operation graphs.
92
+
93
+ ## Related Packages
94
+
95
+ - [ultravisor-beacon](https://github.com/stevenvelozo/ultravisor-beacon) -- Underlying beacon client and Fable service
96
+ - [ultravisor](https://github.com/stevenvelozo/ultravisor) -- Process supervision and orchestration server
97
+ - [fable](https://github.com/stevenvelozo/fable) -- Service dependency injection framework
98
+ - [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) -- Service provider base class
99
+
100
+ ## License
101
+
102
+ MIT
103
+
104
+ ## Contributing
105
+
106
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # Ultravisor Beacon Capability
2
+
3
+ > Convention-based base class for building Ultravisor beacon capabilities
4
+
5
+ Ultravisor Beacon Capability eliminates the boilerplate of wiring up an Ultravisor beacon. Instead of manually creating a beacon service, building capability descriptors, and managing the connection lifecycle, you extend a single base class, write action methods, and call `connect()`. The module discovers your actions by convention, builds the capability descriptor, registers with the Ultravisor server, and manages the full beacon lifecycle.
6
+
7
+ The Ultravisor server automatically creates task types (cards) for each action your capability exposes. These can be triggered on demand, scheduled for recurring execution, or composed into multi-step operation graphs -- turning ad-hoc scripts into managed, observable automation.
8
+
9
+ ## Features
10
+
11
+ - **Convention Over Configuration** -- Define actions as methods prefixed with `action`; schemas and descriptions as companion getters
12
+ - **Automatic Discovery** -- Actions are discovered by walking the prototype chain, including multi-level inheritance
13
+ - **Simplified Handler Signature** -- Settings are pre-extracted from work items so handlers receive `(pSettings, pWorkItem, fCallback, fReportProgress)`
14
+ - **Lifecycle Hooks** -- Override `onInitialize()` and `onShutdown()` for setup and teardown (database connections, service handles, etc.)
15
+ - **Explicit Registration Escape Hatch** -- Use `addAction()` for dynamic or runtime-generated actions alongside convention-based ones
16
+ - **Fable Ecosystem Integration** -- Extends `fable-serviceproviderbase`; composes `ultravisor-beacon` internally
17
+
18
+ ## Quick Start
19
+
20
+ ```javascript
21
+ const libFable = require('fable');
22
+ const libBeaconCapability = require('ultravisor-beacon-capability');
23
+
24
+ class HealthCheck extends libBeaconCapability
25
+ {
26
+ constructor(pFable, pOptions, pServiceHash)
27
+ {
28
+ super(pFable, pOptions, pServiceHash);
29
+ this.serviceType = 'HealthCheck';
30
+ this.capabilityName = 'HealthCheck';
31
+ }
32
+
33
+ get actionCheckDiskSpace_Description()
34
+ {
35
+ return 'Report available disk space on the host';
36
+ }
37
+
38
+ actionCheckDiskSpace(pSettings, pWorkItem, fCallback)
39
+ {
40
+ require('child_process').exec('df -h', (pError, pStdOut) =>
41
+ {
42
+ if (pError) return fCallback(pError);
43
+ return fCallback(null, { Outputs: { DiskUsage: pStdOut } });
44
+ });
45
+ }
46
+ }
47
+
48
+ let tmpFable = new libFable({ Product: 'HealthCheck' });
49
+ tmpFable.addServiceType('HealthCheck', HealthCheck);
50
+ let tmpCheck = tmpFable.instantiateServiceProvider('HealthCheck');
51
+
52
+ tmpCheck.connect({ ServerURL: 'http://ultravisor.local:54321' }, (pError) =>
53
+ {
54
+ if (pError) throw pError;
55
+ console.log('Health check beacon online');
56
+ });
57
+ ```
58
+
59
+ ## Installation
60
+
61
+ ```bash
62
+ npm install ultravisor-beacon-capability
63
+ ```
64
+
65
+ ## Core Concepts
66
+
67
+ ### The Action Convention
68
+
69
+ Actions are discovered by method name prefix. An action named `PurgeRecords` is defined by up to three members on your class:
70
+
71
+ | Member | Required | Purpose |
72
+ |--------|----------|---------|
73
+ | `actionPurgeRecords(pSettings, pWorkItem, fCallback, fReportProgress)` | Yes | The handler function |
74
+ | `get actionPurgeRecords_Schema()` | No | Returns a `SettingsSchema` array describing input parameters |
75
+ | `get actionPurgeRecords_Description()` | No | Returns a human-readable description string |
76
+
77
+ The handler receives `pSettings` pre-extracted from `pWorkItem.Settings` (defaulting to `{}` if absent), eliminating the universal boilerplate of `let tmpSettings = pWorkItem.Settings || {};`.
78
+
79
+ ### Server-Side Integration
80
+
81
+ When a beacon registers capabilities, the Ultravisor server's coordinator automatically creates task types for each `Capability:Action` pair. The task type hash follows the format `beacon-{capability}-{action}` (e.g. `beacon-healthcheck-checkdiskspace`). These task types appear as cards in the Ultravisor UI and can be:
82
+
83
+ - **Triggered manually** from the Ultravisor dashboard
84
+ - **Scheduled** for recurring execution
85
+ - **Composed** into operation graphs with other task types
86
+
87
+ ### Before and After
88
+
89
+ Without this module, registering a single capability requires approximately 60 lines of framework code (service type registration, beacon instantiation, descriptor building, lifecycle management). With this module, the same result requires approximately 5 lines of framework code -- one class declaration, one `capabilityName` assignment, and one `connect()` call.
90
+
91
+ ## Documentation
92
+
93
+ - [Quick Start](quickstart.md) -- Step-by-step setup
94
+ - [Architecture](architecture.md) -- System design with diagrams
95
+ - [API Reference](api/README.md) -- Complete class and method reference
96
+ - [Examples](examples/README.md) -- Real-world usage patterns
97
+
98
+ ## Related Packages
99
+
100
+ - [ultravisor-beacon](https://github.com/stevenvelozo/ultravisor-beacon) -- Underlying beacon client and Fable service
101
+ - [ultravisor](https://github.com/stevenvelozo/ultravisor) -- Process supervision and orchestration server
102
+ - [fable](https://github.com/stevenvelozo/fable) -- Service dependency injection framework
103
+ - [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) -- Service provider base class
@@ -0,0 +1,18 @@
1
+ {
2
+ "Hash": "ultravisor-beacon-capability",
3
+ "Name": "Ultravisor Beacon Capability",
4
+ "Tagline": "Convention-based base class for building Ultravisor beacon capabilities with minimal boilerplate",
5
+ "Palette": "mix",
6
+ "Icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-ultravisor-beacon-capability-filled-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#1dc3df\"/>\n\t\t<g clip-path=\"url(#frame-ultravisor-beacon-capability-filled-light)\"><rect x=\"20\" y=\"20\" width=\"56\" height=\"56\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/>\n\t\t\t\t\t<path d=\"M 48 30 L 70 48 L 48 66 L 26 48 Z\" fill=\"#f043d4\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"28\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">UBC</text>\n\t</svg>",
7
+ "IconType": "svg",
8
+ "Favicon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-ultravisor-beacon-capability-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#1dc3df\"/>\n\t\t<g clip-path=\"url(#fav-ultravisor-beacon-capability-light)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">U</text>\n\t</svg>",
9
+ "FaviconDark": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-ultravisor-beacon-capability-dark\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#71d6e7\"/>\n\t\t<g clip-path=\"url(#fav-ultravisor-beacon-capability-dark)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">U</text>\n\t</svg>",
10
+ "Colors": {
11
+ "Primary": "#1dc3df",
12
+ "Secondary": "#f043d4",
13
+ "PrimaryLight": "#1dc3df",
14
+ "PrimaryDark": "#71d6e7",
15
+ "SecondaryLight": "#f043d4",
16
+ "SecondaryDark": "#f49ce5"
17
+ }
18
+ }
package/docs/_cover.md ADDED
@@ -0,0 +1,13 @@
1
+ # Ultravisor Beacon Capability
2
+
3
+ > Convention-based base class for building Ultravisor beacon capabilities
4
+
5
+ - Define actions as methods with the `action` prefix
6
+ - Automatic discovery via prototype chain walking
7
+ - Simplified handler signature with pre-extracted settings
8
+ - Full Fable ecosystem integration
9
+
10
+ [Get Started](quickstart.md)
11
+ [API Reference](api/README.md)
12
+ [Examples](examples/README.md)
13
+ [GitHub](https://github.com/stevenvelozo/ultravisor-beacon-capability)
@@ -0,0 +1,31 @@
1
+ - Getting Started
2
+
3
+ - [Introduction](/)
4
+ - [Quick Start](quickstart.md)
5
+ - [Architecture](architecture.md)
6
+
7
+ - API Reference
8
+
9
+ - [Overview](api/README.md)
10
+ - [UltravisorBeaconCapability](api/beacon-capability.md)
11
+ - [Action Convention](api/action-convention.md)
12
+ - [buildActionMap](api/build-action-map.md)
13
+ - [connect](api/connect.md)
14
+ - [disconnect](api/disconnect.md)
15
+ - [addAction](api/add-action.md)
16
+ - [onInitialize / onShutdown](api/lifecycle-hooks.md)
17
+ - [isConnected](api/is-connected.md)
18
+
19
+ - Examples
20
+
21
+ - [Overview](examples/README.md)
22
+ - [Shell Commands](examples/shell-commands.md)
23
+ - [MySQL Maintenance](examples/mysql-maintenance.md)
24
+ - [PostgreSQL Aggregation](examples/postgresql-aggregation.md)
25
+ - [REST API Health Check](examples/rest-api-health-check.md)
26
+ - [REST Endpoint Sync](examples/rest-endpoint-sync.md)
27
+ - [Log File Cleanup](examples/log-file-cleanup.md)
28
+ - [Log Archive and Upload](examples/log-archive-and-upload.md)
29
+ - [Server Metrics Collection](examples/server-metrics-collection.md)
30
+ - [Certificate Expiry Monitor](examples/certificate-expiry-monitor.md)
31
+ - [Docker Container Management](examples/docker-container-management.md)
@@ -0,0 +1,5 @@
1
+ [Home](/)
2
+ [Quick Start](quickstart.md)
3
+ [API Reference](api/README.md)
4
+ [Examples](examples/README.md)
5
+ [GitHub](https://github.com/stevenvelozo/ultravisor-beacon-capability)
@@ -0,0 +1,7 @@
1
+ {
2
+ "Name": "ultravisor-beacon-capability",
3
+ "Version": "0.0.1",
4
+ "Description": "Convention-based base class for building Ultravisor beacon capabilities with minimal boilerplate",
5
+ "GeneratedAt": "2026-04-10T17:19:46.865Z",
6
+ "GitCommit": "e8589f3"
7
+ }
@@ -0,0 +1,44 @@
1
+ # API Reference
2
+
3
+ > Complete reference for ultravisor-beacon-capability
4
+
5
+ ## Module Export
6
+
7
+ ```javascript
8
+ const libBeaconCapability = require('ultravisor-beacon-capability');
9
+ ```
10
+
11
+ The module exports `UltravisorBeaconCapability`, a class that extends `fable-serviceproviderbase`. You extend this class to define your capability.
12
+
13
+ ## Classes
14
+
15
+ | Class | Description |
16
+ |-------|-------------|
17
+ | [UltravisorBeaconCapability](beacon-capability.md) | Base class -- extend to define capabilities with action methods |
18
+
19
+ ## Convention
20
+
21
+ | Reference | Description |
22
+ |-----------|-------------|
23
+ | [Action Convention](action-convention.md) | How actions are discovered via the `action` prefix |
24
+
25
+ ## Methods
26
+
27
+ | Method | Description |
28
+ |--------|-------------|
29
+ | [connect()](connect.md) | Connect to an Ultravisor server, register actions, begin accepting work |
30
+ | [disconnect()](disconnect.md) | Disconnect from the Ultravisor server |
31
+ | [addAction()](add-action.md) | Explicitly register an action (escape hatch for dynamic actions) |
32
+ | [isConnected()](is-connected.md) | Check whether the beacon is currently connected |
33
+
34
+ ## Lifecycle Hooks
35
+
36
+ | Hook | Description |
37
+ |------|-------------|
38
+ | [onInitialize() / onShutdown()](lifecycle-hooks.md) | Setup and teardown hooks for resource management |
39
+
40
+ ## Internal
41
+
42
+ | Function | Description |
43
+ |----------|-------------|
44
+ | [buildActionMap()](build-action-map.md) | Discovers action methods on a capability instance's prototype chain |
@@ -0,0 +1,148 @@
1
+ # Action Convention
2
+
3
+ Actions are discovered automatically by examining method names on your class. Any method starting with `action` (and longer than just the word "action") is treated as an action handler. Companion getters provide metadata.
4
+
5
+ ## Defining an Action
6
+
7
+ An action named `DoSomething` consists of up to three members:
8
+
9
+ ### Handler (required)
10
+
11
+ ```javascript
12
+ actionDoSomething(pSettings, pWorkItem, fCallback, fReportProgress)
13
+ {
14
+ // pSettings -- pre-extracted from pWorkItem.Settings (defaults to {} if missing)
15
+ // pWorkItem -- the full work item object from Ultravisor
16
+ // fCallback -- function(pError, pResult) where pResult = { Outputs: {...}, Log: [...] }
17
+ // fReportProgress -- optional function({ Percent, Message, Step, TotalSteps })
18
+
19
+ return fCallback(null, { Outputs: { Result: 'done' } });
20
+ }
21
+ ```
22
+
23
+ ### Schema (optional)
24
+
25
+ ```javascript
26
+ get actionDoSomething_Schema()
27
+ {
28
+ return [
29
+ { Name: 'InputFile', DataType: 'String', Required: true },
30
+ { Name: 'OutputFormat', DataType: 'String', Required: false },
31
+ { Name: 'MaxRows', DataType: 'Integer', Required: false }
32
+ ];
33
+ }
34
+ ```
35
+
36
+ The schema is an array of field definitions. Each field has:
37
+
38
+ | Property | Type | Description |
39
+ |----------|------|-------------|
40
+ | `Name` | `string` | Parameter name |
41
+ | `DataType` | `string` | Type: `String`, `Integer`, `Boolean`, `Object`, `Array`, `DateTime` |
42
+ | `Required` | `boolean` | Whether the parameter is required |
43
+ | `Default` | `any` | Optional default value |
44
+ | `Description` | `string` | Optional human-readable description |
45
+
46
+ ### Description (optional)
47
+
48
+ ```javascript
49
+ get actionDoSomething_Description()
50
+ {
51
+ return 'Process an input file and produce output in the specified format';
52
+ }
53
+ ```
54
+
55
+ ## Handler Signature
56
+
57
+ The convention handler signature differs from the raw `ultravisor-beacon` handler:
58
+
59
+ | Parameter | Convention | Raw beacon |
60
+ |-----------|-----------|------------|
61
+ | 1st | `pSettings` (pre-extracted) | `pWorkItem` |
62
+ | 2nd | `pWorkItem` (full object) | `pContext` |
63
+ | 3rd | `fCallback` | `fCallback` |
64
+ | 4th | `fReportProgress` | `fReportProgress` |
65
+
66
+ The base class wraps your method so that `ultravisor-beacon` receives the raw signature it expects.
67
+
68
+ ## Result Format
69
+
70
+ The callback expects:
71
+
72
+ ```javascript
73
+ // Success
74
+ fCallback(null, {
75
+ Outputs: { Key: 'value', AnotherKey: 123 },
76
+ Log: ['Step 1 complete', 'Step 2 complete']
77
+ });
78
+
79
+ // Error
80
+ fCallback(new Error('Something went wrong'));
81
+ ```
82
+
83
+ - `Outputs` -- key-value pairs available as task state outputs on the Ultravisor server
84
+ - `Log` -- array of log strings recorded with the work item result
85
+
86
+ ## Progress Reporting
87
+
88
+ For long-running actions, use `fReportProgress`:
89
+
90
+ ```javascript
91
+ actionLongTask(pSettings, pWorkItem, fCallback, fReportProgress)
92
+ {
93
+ fReportProgress({ Percent: 0, Message: 'Starting...', Step: 1, TotalSteps: 3 });
94
+
95
+ // ... do step 1 ...
96
+
97
+ fReportProgress({ Percent: 33, Message: 'Step 1 complete', Step: 2, TotalSteps: 3 });
98
+
99
+ // ... do step 2 ...
100
+
101
+ fReportProgress({ Percent: 66, Message: 'Step 2 complete', Step: 3, TotalSteps: 3 });
102
+
103
+ // ... do step 3 ...
104
+
105
+ return fCallback(null, { Outputs: { Result: 'all done' } });
106
+ }
107
+ ```
108
+
109
+ ## Discovery Rules
110
+
111
+ 1. Method name must start with `action` and be longer than 6 characters
112
+ 2. Methods ending with `_Schema` or `_Description` are companions, not actions
113
+ 3. Only actual functions are considered (not getters or plain properties)
114
+ 4. The prototype chain is walked from the derived class up to (but not including) `Object.prototype`
115
+ 5. If a method name appears on both a derived and base class, the derived version wins
116
+ 6. Missing `_Schema` defaults to `[]`; missing `_Description` defaults to `''`
117
+
118
+ ## `this` Context
119
+
120
+ Action methods are bound to the capability instance. You have full access to:
121
+
122
+ ```javascript
123
+ actionQuery(pSettings, pWorkItem, fCallback)
124
+ {
125
+ // Access Fable services
126
+ this.fable.services.SomeService.doWork();
127
+
128
+ // Access the logger
129
+ this.log.info('Processing query...');
130
+
131
+ // Access instance state set in onInitialize
132
+ this._DatabaseConnection.query(pSettings.SQL, (pError, pRows) =>
133
+ {
134
+ if (pError) return fCallback(pError);
135
+ return fCallback(null, { Outputs: { Rows: pRows } });
136
+ });
137
+ }
138
+ ```
139
+
140
+ ## Naming Conventions
141
+
142
+ The action name is derived by stripping the `action` prefix. The casing is preserved:
143
+
144
+ | Method Name | Action Name | Task Type Hash |
145
+ |-------------|-------------|----------------|
146
+ | `actionPurgeRecords` | `PurgeRecords` | `beacon-{cap}-purgerecords` |
147
+ | `actionRunBackup` | `RunBackup` | `beacon-{cap}-runbackup` |
148
+ | `actionSyncData` | `SyncData` | `beacon-{cap}-syncdata` |
@@ -0,0 +1,68 @@
1
+ # addAction()
2
+
3
+ Explicitly register an action. Use this as an escape hatch for actions that cannot be expressed via the convention (e.g. dynamically generated actions, actions loaded from configuration, or actions with closures over external state).
4
+
5
+ ## Signature
6
+
7
+ ```javascript
8
+ addAction(pName, pDefinition)
9
+ ```
10
+
11
+ ### Parameters
12
+
13
+ | Parameter | Type | Description |
14
+ |-----------|------|-------------|
15
+ | `pName` | `string` | Action name (e.g. `'ProcessData'`) |
16
+ | `pDefinition` | `object` | Action definition (see below) |
17
+
18
+ ### Definition
19
+
20
+ | Property | Type | Required | Description |
21
+ |----------|------|----------|-------------|
22
+ | `Handler` | `function` | Yes | `function(pWorkItem, pContext, fCallback, fReportProgress)` -- uses the **raw** beacon handler signature |
23
+ | `Description` | `string` | No | Human-readable description |
24
+ | `SettingsSchema` | `array` | No | Array of field definitions |
25
+
26
+ **Important:** The `Handler` uses the raw `ultravisor-beacon` signature, not the simplified convention signature. This means `pWorkItem` is the first parameter (not `pSettings`).
27
+
28
+ ## Behavior
29
+
30
+ - Stores the action in an internal map
31
+ - Explicit actions are merged with convention-discovered actions when `connect()` is called
32
+ - If an explicit action has the same name as a convention-discovered action, the explicit one wins
33
+ - Validation: rejects calls with missing/empty `pName` or missing `Handler` function
34
+
35
+ ## Example
36
+
37
+ ```javascript
38
+ let tmpFable = new libFable({});
39
+ let tmpCap = new MyCapability(tmpFable, {}, 'cap');
40
+
41
+ // Register a dynamic action
42
+ tmpCap.addAction('ImportCSV',
43
+ {
44
+ Description: 'Import data from a CSV file',
45
+ SettingsSchema: [
46
+ { Name: 'FilePath', DataType: 'String', Required: true },
47
+ { Name: 'Delimiter', DataType: 'String', Required: false }
48
+ ],
49
+ Handler: function (pWorkItem, pContext, fCallback)
50
+ {
51
+ let tmpSettings = pWorkItem.Settings || {};
52
+ // ... process CSV ...
53
+ return fCallback(null, { Outputs: { RowsImported: 42 } });
54
+ }
55
+ });
56
+
57
+ tmpCap.connect({ ServerURL: 'http://ultravisor:54321' }, (pError) => { });
58
+ ```
59
+
60
+ ## When to Use
61
+
62
+ | Scenario | Use Convention | Use addAction |
63
+ |----------|---------------|---------------|
64
+ | Standard action with known schema | Yes | -- |
65
+ | Action generated from config at runtime | -- | Yes |
66
+ | Action wrapping an external library callback | Either | Yes (simpler) |
67
+ | Action that needs the raw `pContext` parameter | -- | Yes |
68
+ | Multiple capabilities sharing a common action | -- | Yes |
@@ -0,0 +1,89 @@
1
+ # UltravisorBeaconCapability
2
+
3
+ The base class for all convention-based beacon capabilities. Extend this class, set `capabilityName`, define action methods with the `action` prefix, and call `connect()`.
4
+
5
+ ## Import
6
+
7
+ ```javascript
8
+ const libBeaconCapability = require('ultravisor-beacon-capability');
9
+ ```
10
+
11
+ ## Constructor
12
+
13
+ ```javascript
14
+ class MyCapability extends libBeaconCapability
15
+ {
16
+ constructor(pFable, pOptions, pServiceHash)
17
+ {
18
+ super(pFable, pOptions, pServiceHash);
19
+ this.serviceType = 'MyCapability';
20
+ this.capabilityName = 'MyCapability';
21
+ this.providerName = 'MyCapabilityProvider'; // optional
22
+ }
23
+ }
24
+ ```
25
+
26
+ ### Parameters
27
+
28
+ | Parameter | Type | Description |
29
+ |-----------|------|-------------|
30
+ | `pFable` | `Fable` | Fable instance (provided by the framework) |
31
+ | `pOptions` | `object` | Service options (provided by the framework) |
32
+ | `pServiceHash` | `string` | Service hash identifier (provided by the framework) |
33
+
34
+ ### Properties
35
+
36
+ | Property | Type | Default | Description |
37
+ |----------|------|---------|-------------|
38
+ | `capabilityName` | `string` | `''` | **Required.** The capability name registered with Ultravisor. Must be set before calling `connect()`. |
39
+ | `providerName` | `string` | `''` | Optional display name. Defaults to `{capabilityName}Provider` if not set. |
40
+ | `serviceType` | `string` | `'UltravisorBeaconCapability'` | Fable service type identifier. Set to your class name. |
41
+
42
+ ## Methods
43
+
44
+ | Method | Description |
45
+ |--------|-------------|
46
+ | [`connect(pBeaconConfig, fCallback)`](connect.md) | Connect to Ultravisor server |
47
+ | [`disconnect(fCallback)`](disconnect.md) | Disconnect from Ultravisor server |
48
+ | [`addAction(pName, pDefinition)`](add-action.md) | Register an explicit action |
49
+ | [`isConnected()`](is-connected.md) | Check connection status |
50
+
51
+ ## Lifecycle Hooks
52
+
53
+ | Hook | Description |
54
+ |------|-------------|
55
+ | [`onInitialize(fCallback)`](lifecycle-hooks.md) | Called after beacon connects, before polling |
56
+ | [`onShutdown(fCallback)`](lifecycle-hooks.md) | Called when beacon disconnects |
57
+
58
+ ## Usage with Fable
59
+
60
+ ```javascript
61
+ const libFable = require('fable');
62
+
63
+ let tmpFable = new libFable({ Product: 'MyApp' });
64
+
65
+ // Register the service type
66
+ tmpFable.addServiceType('MyCapability', MyCapability);
67
+
68
+ // Instantiate
69
+ let tmpCap = tmpFable.instantiateServiceProvider('MyCapability');
70
+
71
+ // Connect
72
+ tmpCap.connect({ ServerURL: 'http://ultravisor:54321' }, (pError) =>
73
+ {
74
+ if (pError) throw pError;
75
+ console.log('Connected');
76
+ });
77
+ ```
78
+
79
+ ## Inheritance
80
+
81
+ `UltravisorBeaconCapability` extends `fable-serviceproviderbase`, which means your capability instance has access to all standard Fable service features:
82
+
83
+ - `this.fable` -- the Fable instance
84
+ - `this.log` -- the Fable logger (`this.log.info()`, `this.log.error()`, etc.)
85
+ - `this.options` -- the service options
86
+ - `this.fable.settings` -- application settings
87
+ - `this.fable.services` -- other registered services
88
+
89
+ Multi-level inheritance is supported. Actions defined on base classes are discovered alongside those on derived classes, with derived classes taking precedence on name collision.