@antelopejs/interface-core 0.0.6 → 0.0.8
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/errors.d.ts +20 -0
- package/dist/errors.js +46 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/proxies.js +3 -4
- package/dist/proxies.js.map +1 -1
- package/dist/tests/stub-mode.test.js +34 -3
- package/dist/tests/stub-mode.test.js.map +1 -1
- package/docs/1.introduction.md +69 -0
- package/docs/2.proxies.md +226 -0
- package/docs/3.decorators.md +169 -0
- package/docs/4.metadata.md +107 -0
- package/docs/5.modules.md +180 -0
- package/docs/6.logging.md +106 -0
- package/docs/7.configuration.md +182 -0
- package/docs/8.runtime.md +60 -0
- package/package.json +8 -3
- package/skills/core-interface/SKILL.md +98 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const MISSING_PROVIDER_CODE = "ERR_NO_PROVIDER";
|
|
2
|
+
/**
|
|
3
|
+
* Error emitted when a proxy is used without an attached provider in test
|
|
4
|
+
* stub mode.
|
|
5
|
+
*
|
|
6
|
+
* The detection contract is the type and the stable `code` property, not the
|
|
7
|
+
* message text: use `instanceof MissingProviderError` or, across duplicated
|
|
8
|
+
* copies of this package, {@link isMissingProviderError}.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MissingProviderError extends Error {
|
|
11
|
+
readonly code = "ERR_NO_PROVIDER";
|
|
12
|
+
constructor(detail?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Type guard for {@link MissingProviderError}.
|
|
16
|
+
*
|
|
17
|
+
* Checks the stable `code` property instead of `instanceof`, so detection
|
|
18
|
+
* survives realm boundaries and duplicated copies of this package.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isMissingProviderError(error: unknown): error is MissingProviderError;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MissingProviderError = exports.MISSING_PROVIDER_CODE = void 0;
|
|
4
|
+
exports.isMissingProviderError = isMissingProviderError;
|
|
5
|
+
exports.MISSING_PROVIDER_CODE = "ERR_NO_PROVIDER";
|
|
6
|
+
const MISSING_PROVIDER_MESSAGE = "Interface function called without implementation in test environment. " +
|
|
7
|
+
"Ensure the required module is loaded in your test config.";
|
|
8
|
+
/**
|
|
9
|
+
* Error emitted when a proxy is used without an attached provider in test
|
|
10
|
+
* stub mode.
|
|
11
|
+
*
|
|
12
|
+
* The detection contract is the type and the stable `code` property, not the
|
|
13
|
+
* message text: use `instanceof MissingProviderError` or, across duplicated
|
|
14
|
+
* copies of this package, {@link isMissingProviderError}.
|
|
15
|
+
*/
|
|
16
|
+
class MissingProviderError extends Error {
|
|
17
|
+
code = exports.MISSING_PROVIDER_CODE;
|
|
18
|
+
constructor(detail) {
|
|
19
|
+
super(detail ?? MISSING_PROVIDER_MESSAGE);
|
|
20
|
+
this.name = "MissingProviderError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.MissingProviderError = MissingProviderError;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the value is an error, including one built in another realm.
|
|
26
|
+
*
|
|
27
|
+
* `instanceof Error` is realm-bound: an error crossing a vm context, worker or
|
|
28
|
+
* iframe boundary carries a different `Error.prototype` and fails it. The brand
|
|
29
|
+
* check holds across realms while still rejecting plain objects; `instanceof`
|
|
30
|
+
* covers the reverse case of an object created from `Error.prototype`.
|
|
31
|
+
*/
|
|
32
|
+
function isError(value) {
|
|
33
|
+
return (Object.prototype.toString.call(value) === "[object Error]" ||
|
|
34
|
+
value instanceof Error);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Type guard for {@link MissingProviderError}.
|
|
38
|
+
*
|
|
39
|
+
* Checks the stable `code` property instead of `instanceof`, so detection
|
|
40
|
+
* survives realm boundaries and duplicated copies of this package.
|
|
41
|
+
*/
|
|
42
|
+
function isMissingProviderError(error) {
|
|
43
|
+
return (isError(error) &&
|
|
44
|
+
error.code === exports.MISSING_PROVIDER_CODE);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AA4CA,wDAOC;AAnDY,QAAA,qBAAqB,GAAG,iBAAiB,CAAC;AAEvD,MAAM,wBAAwB,GAC5B,wEAAwE;IACxE,2DAA2D,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAa,oBAAqB,SAAQ,KAAK;IAC7B,IAAI,GAAG,6BAAqB,CAAC;IAE7C,YAAmB,MAAe;QAChC,KAAK,CAAC,MAAM,IAAI,wBAAwB,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAPD,oDAOC;AAED;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,gBAAgB;QAC1D,KAAK,YAAY,KAAK,CACvB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,KAAc;IAEd,OAAO,CACL,OAAO,CAAC,KAAK,CAAC;QACb,KAA8B,CAAC,IAAI,KAAK,6BAAqB,CAC/D,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import type { Class } from "./decorators";
|
|
3
3
|
import { EventProxy, RegisteringProxy } from "./proxies";
|
|
4
|
+
export * from "./errors";
|
|
4
5
|
export { AsyncProxy, EventProxy, GetResponsibleModule, RegisteringProxy, } from "./proxies";
|
|
5
6
|
/**
|
|
6
7
|
* Gets metadata for a target object using the specified metadata class.
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.RegisteringProxy = exports.GetResponsibleModule = exports.EventProxy = exports.AsyncProxy = void 0;
|
|
4
18
|
exports.GetMetadata = GetMetadata;
|
|
@@ -10,6 +24,7 @@ require("reflect-metadata");
|
|
|
10
24
|
const internal_1 = require("./internal");
|
|
11
25
|
const logging_1 = require("./logging");
|
|
12
26
|
const proxies_1 = require("./proxies");
|
|
27
|
+
__exportStar(require("./errors"), exports);
|
|
13
28
|
var proxies_2 = require("./proxies");
|
|
14
29
|
Object.defineProperty(exports, "AsyncProxy", { enumerable: true, get: function () { return proxies_2.AsyncProxy; } });
|
|
15
30
|
Object.defineProperty(exports, "EventProxy", { enumerable: true, get: function () { return proxies_2.EventProxy; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/proxies.js
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EventProxy = exports.RegisteringProxy = exports.AsyncProxy = void 0;
|
|
4
4
|
exports.GetResponsibleModule = GetResponsibleModule;
|
|
5
|
+
const errors_1 = require("./errors");
|
|
5
6
|
const internal_1 = require("./internal");
|
|
6
7
|
const responsible_module_1 = require("./responsible-module");
|
|
7
|
-
const STUB_NOT_IMPLEMENTED = "Interface function called without implementation in test environment. " +
|
|
8
|
-
"Ensure the required module is loaded in your test config.";
|
|
9
8
|
/**
|
|
10
9
|
* Proxy for an asynchronous function.
|
|
11
10
|
*
|
|
@@ -65,7 +64,7 @@ class AsyncProxy {
|
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
if (internal_1.internal.testStubMode) {
|
|
68
|
-
return Promise.reject(new
|
|
67
|
+
return Promise.reject(new errors_1.MissingProviderError());
|
|
69
68
|
}
|
|
70
69
|
return new Promise((resolve, reject) => this.queue.push({ args, resolve, reject }));
|
|
71
70
|
}
|
|
@@ -136,7 +135,7 @@ class RegisteringProxy {
|
|
|
136
135
|
*/
|
|
137
136
|
register(id, ...args) {
|
|
138
137
|
if (!this.registerCallback && internal_1.internal.testStubMode) {
|
|
139
|
-
throw new
|
|
138
|
+
throw new errors_1.MissingProviderError();
|
|
140
139
|
}
|
|
141
140
|
const module = GetResponsibleModule();
|
|
142
141
|
this.registered.set(id, { module, args });
|
package/dist/proxies.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"proxies.js","sourceRoot":"","sources":["../src/proxies.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_vm_1 = require("node:vm");
|
|
3
4
|
const chai_1 = require("chai");
|
|
4
5
|
const __1 = require("..");
|
|
5
6
|
const internal_1 = require("../internal");
|
|
@@ -18,7 +19,8 @@ describe("test stub mode", () => {
|
|
|
18
19
|
catch (error) {
|
|
19
20
|
thrown = error;
|
|
20
21
|
}
|
|
21
|
-
(0, chai_1.expect)(thrown).to.be.instanceOf(
|
|
22
|
+
(0, chai_1.expect)(thrown).to.be.instanceOf(__1.MissingProviderError);
|
|
23
|
+
(0, chai_1.expect)(thrown.code).to.equal(__1.MISSING_PROVIDER_CODE);
|
|
22
24
|
(0, chai_1.expect)(thrown.message).to.include("without implementation");
|
|
23
25
|
});
|
|
24
26
|
it("still queues calls when stub mode is off", () => {
|
|
@@ -35,10 +37,18 @@ describe("test stub mode", () => {
|
|
|
35
37
|
});
|
|
36
38
|
});
|
|
37
39
|
describe("RegisteringProxy", () => {
|
|
38
|
-
it("throws when registering without callback in stub mode", () => {
|
|
40
|
+
it("throws MissingProviderError when registering without callback in stub mode", () => {
|
|
39
41
|
internal_1.internal.testStubMode = true;
|
|
40
42
|
const proxy = new __1.RegisteringProxy();
|
|
41
|
-
|
|
43
|
+
let thrown;
|
|
44
|
+
try {
|
|
45
|
+
proxy.register("id1");
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
thrown = error;
|
|
49
|
+
}
|
|
50
|
+
(0, chai_1.expect)(thrown).to.be.instanceOf(__1.MissingProviderError);
|
|
51
|
+
(0, chai_1.expect)(thrown.code).to.equal(__1.MISSING_PROVIDER_CODE);
|
|
42
52
|
});
|
|
43
53
|
it("still queues registration when stub mode is off", () => {
|
|
44
54
|
const proxy = new __1.RegisteringProxy();
|
|
@@ -53,5 +63,26 @@ describe("test stub mode", () => {
|
|
|
53
63
|
(0, chai_1.expect)(registered).to.deep.equal(["id1"]);
|
|
54
64
|
});
|
|
55
65
|
});
|
|
66
|
+
describe("isMissingProviderError", () => {
|
|
67
|
+
it("accepts a MissingProviderError instance", () => {
|
|
68
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)(new __1.MissingProviderError())).to.equal(true);
|
|
69
|
+
});
|
|
70
|
+
it("accepts an error carrying the code from a duplicated package copy", () => {
|
|
71
|
+
const foreignCopy = Object.assign(new Error("other wording"), {
|
|
72
|
+
code: __1.MISSING_PROVIDER_CODE,
|
|
73
|
+
});
|
|
74
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)(foreignCopy)).to.equal(true);
|
|
75
|
+
});
|
|
76
|
+
it("accepts an error carrying the code from another realm", () => {
|
|
77
|
+
const foreignRealmError = (0, node_vm_1.runInNewContext)("Object.assign(new Error('other realm'), { code })", { code: __1.MISSING_PROVIDER_CODE });
|
|
78
|
+
(0, chai_1.expect)(foreignRealmError instanceof Error).to.equal(false);
|
|
79
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)(foreignRealmError)).to.equal(true);
|
|
80
|
+
});
|
|
81
|
+
it("rejects unrelated errors and non-errors", () => {
|
|
82
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)(new Error("boom"))).to.equal(false);
|
|
83
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)({ code: __1.MISSING_PROVIDER_CODE })).to.equal(false);
|
|
84
|
+
(0, chai_1.expect)((0, __1.isMissingProviderError)(undefined)).to.equal(false);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
56
87
|
});
|
|
57
88
|
//# sourceMappingURL=stub-mode.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-mode.test.js","sourceRoot":"","sources":["../../src/tests/stub-mode.test.ts"],"names":[],"mappings":";;AAAA,+BAA8B;AAC9B,
|
|
1
|
+
{"version":3,"file":"stub-mode.test.js","sourceRoot":"","sources":["../../src/tests/stub-mode.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Interface Core Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`@antelopejs/interface-core` provides the foundational building blocks for the AntelopeJS interface system. It defines the core primitives that enable type-safe, module-aware communication between decoupled components.
|
|
6
|
+
|
|
7
|
+
The package exports several key categories of functionality:
|
|
8
|
+
|
|
9
|
+
- **Proxies** - `AsyncProxy`, `EventProxy`, and `RegisteringProxy` manage cross-module function calls, events, and registrations with automatic cleanup when modules are unloaded.
|
|
10
|
+
- **Interface functions** - `InterfaceFunction` and `ImplementInterface` wire up interface declarations to their concrete implementations.
|
|
11
|
+
- **Decorator factories** - Utilities for building type-safe TypeScript decorators that target classes, properties, methods, and parameters.
|
|
12
|
+
- **Metadata** - `GetMetadata` provides reflection-based metadata retrieval with inheritance support.
|
|
13
|
+
- **Module lifecycle** - Events and functions for managing module construction, startup, shutdown, and destruction.
|
|
14
|
+
- **Logging** - A structured, channel-based logging system with multiple severity levels.
|
|
15
|
+
- **Configuration** - TypeScript types and helpers for defining AntelopeJS project configurations.
|
|
16
|
+
|
|
17
|
+
## Import paths
|
|
18
|
+
|
|
19
|
+
The package exposes several entry points:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Main entry - proxies, InterfaceFunction, GetMetadata, ImplementInterface, GetInterfaceInstances
|
|
23
|
+
import { AsyncProxy, InterfaceFunction, GetMetadata } from "@antelopejs/interface-core";
|
|
24
|
+
|
|
25
|
+
// Decorator factories
|
|
26
|
+
import { MakeClassDecorator, MakeMethodDecorator } from "@antelopejs/interface-core/decorators";
|
|
27
|
+
|
|
28
|
+
// Module lifecycle events and management
|
|
29
|
+
import { Events, ListModules, LoadModule } from "@antelopejs/interface-core/modules";
|
|
30
|
+
|
|
31
|
+
// Logging system
|
|
32
|
+
import { Logging } from "@antelopejs/interface-core/logging";
|
|
33
|
+
|
|
34
|
+
// Configuration types and helpers
|
|
35
|
+
import { defineConfig } from "@antelopejs/interface-core/config";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## How interfaces work
|
|
39
|
+
|
|
40
|
+
AntelopeJS interfaces act as contracts between modules. One module declares an interface using proxy objects and `InterfaceFunction`, while another module provides the implementation using `ImplementInterface`. The proxy layer handles queuing, lifecycle management, and automatic cleanup.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// Declaration side: define what the interface looks like
|
|
44
|
+
import { InterfaceFunction, EventProxy } from "@antelopejs/interface-core";
|
|
45
|
+
|
|
46
|
+
export const GetUser = InterfaceFunction<(id: string) => { name: string }>();
|
|
47
|
+
export const OnUserCreated = new EventProxy<(userId: string) => void>();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// Implementation side: provide the concrete behavior
|
|
52
|
+
import { ImplementInterface } from "@antelopejs/interface-core";
|
|
53
|
+
import * as UserInterface from "./declaration";
|
|
54
|
+
|
|
55
|
+
ImplementInterface(UserInterface, {
|
|
56
|
+
GetUser(id: string) {
|
|
57
|
+
return { name: "Alice" };
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The proxy system ensures that calls to `GetUser` before the implementation is attached are automatically queued and resolved once the implementation becomes available. When the implementing module is unloaded, the proxy detaches and resumes queuing.
|
|
63
|
+
|
|
64
|
+
## Next steps
|
|
65
|
+
|
|
66
|
+
- [Proxies](./2.proxies.md) - Deep dive into `AsyncProxy`, `EventProxy`, and `RegisteringProxy`
|
|
67
|
+
- [Decorators](./3.decorators.md) - Build type-safe decorator factories
|
|
68
|
+
- [Modules](./5.modules.md) - Understand module lifecycle events
|
|
69
|
+
- [Logging](./6.logging.md) - Use the structured logging system
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Proxies
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Proxies are the backbone of cross-module communication in AntelopeJS. They provide module-aware abstractions for function calls, event handling, and registration patterns. Each proxy type automatically tracks the module that attaches callbacks and detaches them when that module is unloaded, preventing memory leaks and dangling references.
|
|
6
|
+
|
|
7
|
+
## `AsyncProxy`
|
|
8
|
+
|
|
9
|
+
`AsyncProxy` wraps asynchronous function calls. It queues invocations when no callback is attached and flushes the queue once a callback becomes available.
|
|
10
|
+
|
|
11
|
+
### Create and use an `AsyncProxy`
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { AsyncProxy } from "@antelopejs/interface-core";
|
|
15
|
+
|
|
16
|
+
const proxy = new AsyncProxy<(name: string) => string>();
|
|
17
|
+
|
|
18
|
+
// Calls made before attachment are queued
|
|
19
|
+
const result = proxy.call("Alice"); // returns Promise<string>
|
|
20
|
+
|
|
21
|
+
// Attach an implementation - queued calls resolve immediately
|
|
22
|
+
proxy.onCall((name: string) => {
|
|
23
|
+
return `Hello, ${name}!`;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Subsequent calls execute directly
|
|
27
|
+
const greeting = await proxy.call("Bob"); // "Hello, Bob!"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### `onCall(callback, manualDetach?)`
|
|
31
|
+
|
|
32
|
+
Attaches a callback function to the proxy. The proxy automatically tracks the calling module and detaches the callback when that module is unloaded. Pass `manualDetach: true` to disable automatic cleanup.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// Automatic cleanup (default) - detaches when the module unloads
|
|
36
|
+
proxy.onCall(myHandler);
|
|
37
|
+
|
|
38
|
+
// Manual cleanup - you are responsible for calling detach()
|
|
39
|
+
proxy.onCall(myHandler, true);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `call(...args)`
|
|
43
|
+
|
|
44
|
+
Invokes the attached callback. If no callback is attached, the call returns a `Promise` that resolves once a callback is provided. In test stub mode, unattached calls reject with a [`MissingProviderError`](#missingprovidererror).
|
|
45
|
+
|
|
46
|
+
### `detach()`
|
|
47
|
+
|
|
48
|
+
Manually removes the attached callback. After detaching, subsequent calls are queued again.
|
|
49
|
+
|
|
50
|
+
## `InterfaceFunction`
|
|
51
|
+
|
|
52
|
+
`InterfaceFunction` is a convenience wrapper that creates an `AsyncProxy` and returns a callable function. This is the primary way to declare interface functions.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { InterfaceFunction } from "@antelopejs/interface-core";
|
|
56
|
+
|
|
57
|
+
// Declare a typed interface function
|
|
58
|
+
const GetUser = InterfaceFunction<(id: string) => { name: string; email: string }>();
|
|
59
|
+
|
|
60
|
+
// Call it like a regular async function
|
|
61
|
+
const user = await GetUser("user-123");
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The returned function has a `.proxy` property that exposes the underlying `AsyncProxy` for direct access when needed.
|
|
65
|
+
|
|
66
|
+
## `EventProxy`
|
|
67
|
+
|
|
68
|
+
`EventProxy` manages a list of event handlers with module-aware automatic cleanup. Unlike `AsyncProxy`, it supports multiple registered handlers and does not queue emissions.
|
|
69
|
+
|
|
70
|
+
### Create and use an `EventProxy`
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { EventProxy } from "@antelopejs/interface-core";
|
|
74
|
+
|
|
75
|
+
const onUserCreated = new EventProxy<(userId: string, name: string) => void>();
|
|
76
|
+
|
|
77
|
+
// Register a handler
|
|
78
|
+
onUserCreated.register((userId, name) => {
|
|
79
|
+
console.log(`User created: ${name} (${userId})`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Emit the event - all registered handlers are called
|
|
83
|
+
onUserCreated.emit("u-1", "Alice");
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `register(func)`
|
|
87
|
+
|
|
88
|
+
Registers a handler for the event. Duplicate handlers (same function reference) are ignored. The proxy tracks the calling module and removes the handler when that module is unloaded.
|
|
89
|
+
|
|
90
|
+
### `emit(...args)`
|
|
91
|
+
|
|
92
|
+
Calls all registered handlers with the provided arguments.
|
|
93
|
+
|
|
94
|
+
### `unregister(func)`
|
|
95
|
+
|
|
96
|
+
Removes a specific handler by function reference.
|
|
97
|
+
|
|
98
|
+
## `RegisteringProxy`
|
|
99
|
+
|
|
100
|
+
`RegisteringProxy` manages a register/unregister pair. It tracks registered entries by a unique identifier and supports queuing registrations until the callbacks are attached.
|
|
101
|
+
|
|
102
|
+
### Create and use a `RegisteringProxy`
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { RegisteringProxy } from "@antelopejs/interface-core";
|
|
106
|
+
|
|
107
|
+
const routeRegistry = new RegisteringProxy<(id: string, path: string, handler: Function) => void>();
|
|
108
|
+
|
|
109
|
+
// Register entries - queued if no callback is attached yet
|
|
110
|
+
routeRegistry.register("home", "/", homeHandler);
|
|
111
|
+
routeRegistry.register("about", "/about", aboutHandler);
|
|
112
|
+
|
|
113
|
+
// Attach callbacks - queued registrations replay immediately
|
|
114
|
+
routeRegistry.onRegister((id, path, handler) => {
|
|
115
|
+
router.addRoute(path, handler);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
routeRegistry.onUnregister((id) => {
|
|
119
|
+
router.removeRoute(id);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Unregister by ID
|
|
123
|
+
routeRegistry.unregister("about");
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `onRegister(callback, manualDetach?)`
|
|
127
|
+
|
|
128
|
+
Attaches the register callback. Any previously registered entries replay through this callback immediately. Automatic module-aware detachment applies unless `manualDetach` is `true`.
|
|
129
|
+
|
|
130
|
+
### `onUnregister(callback)`
|
|
131
|
+
|
|
132
|
+
Attaches the unregister callback. This callback is detached at the same time as the register callback.
|
|
133
|
+
|
|
134
|
+
### `register(id, ...args)`
|
|
135
|
+
|
|
136
|
+
Registers an entry with the given identifier. If a register callback is attached, it executes immediately. Otherwise, the entry is stored and replayed when a callback is attached. The calling module is tracked for automatic cleanup.
|
|
137
|
+
|
|
138
|
+
### `unregister(id)`
|
|
139
|
+
|
|
140
|
+
Removes the entry with the given identifier and calls the unregister callback if one is attached.
|
|
141
|
+
|
|
142
|
+
### `detach()`
|
|
143
|
+
|
|
144
|
+
Manually removes both the register and unregister callbacks. Registered entries remain stored.
|
|
145
|
+
|
|
146
|
+
## `ImplementInterface`
|
|
147
|
+
|
|
148
|
+
`ImplementInterface` connects an interface declaration to its implementation. It iterates over the declaration object and wires up each proxy to the corresponding implementation function.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { InterfaceFunction, EventProxy, RegisteringProxy, ImplementInterface } from "@antelopejs/interface-core";
|
|
152
|
+
|
|
153
|
+
// Declaration
|
|
154
|
+
const GetItem = InterfaceFunction<(id: string) => { name: string }>();
|
|
155
|
+
const OnItemAdded = new EventProxy<(id: string) => void>();
|
|
156
|
+
const ItemRegistry = new RegisteringProxy<(id: string, data: any) => void>();
|
|
157
|
+
|
|
158
|
+
const ItemInterface = { GetItem, OnItemAdded, ItemRegistry };
|
|
159
|
+
|
|
160
|
+
// Implementation
|
|
161
|
+
ImplementInterface(ItemInterface, {
|
|
162
|
+
GetItem(id: string) {
|
|
163
|
+
return { name: `Item ${id}` };
|
|
164
|
+
},
|
|
165
|
+
ItemRegistry: {
|
|
166
|
+
register(id: string, data: any) {
|
|
167
|
+
store.set(id, data);
|
|
168
|
+
},
|
|
169
|
+
unregister(id: string) {
|
|
170
|
+
store.delete(id);
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`EventProxy` entries in the declaration are skipped during implementation wiring, as they are emitted from the declaring side, not implemented.
|
|
177
|
+
|
|
178
|
+
## `MissingProviderError`
|
|
179
|
+
|
|
180
|
+
In test stub mode, using a proxy that has no provider attached fails with a `MissingProviderError`: `AsyncProxy.call` rejects with it and `RegisteringProxy.register` throws it.
|
|
181
|
+
|
|
182
|
+
This error is the supported way to detect the "no provider" condition. The contract is the type and its stable `code` property (`"ERR_NO_PROVIDER"`, exported as `MISSING_PROVIDER_CODE`) - never the message text, which may change between versions.
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { isMissingProviderError, MissingProviderError } from "@antelopejs/interface-core";
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
registry.register("my-entry", data);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
if (!isMissingProviderError(error)) throw error;
|
|
191
|
+
// Tolerate the missing provider
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Prefer the `isMissingProviderError` guard over `instanceof`: it checks the `code` property, so detection keeps working across realm boundaries and duplicated copies of the package where `instanceof` fails.
|
|
196
|
+
|
|
197
|
+
## `GetInterfaceInstances` and `GetInterfaceInstance`
|
|
198
|
+
|
|
199
|
+
These functions retrieve information about active interface connections for the current module.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { GetInterfaceInstances, GetInterfaceInstance } from "@antelopejs/interface-core";
|
|
203
|
+
|
|
204
|
+
// Get all connections for an interface
|
|
205
|
+
const connections = GetInterfaceInstances("database");
|
|
206
|
+
|
|
207
|
+
// Get a specific connection by ID
|
|
208
|
+
const primary = GetInterfaceInstance("database", "primary");
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## `GetResponsibleModule`
|
|
212
|
+
|
|
213
|
+
`GetResponsibleModule` inspects the call stack to determine which module is responsible for the current execution. The proxy classes use this internally for automatic cleanup tracking.
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import { GetResponsibleModule } from "@antelopejs/interface-core";
|
|
217
|
+
|
|
218
|
+
const moduleId = GetResponsibleModule();
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> **Warning:** Calling `GetResponsibleModule` from within an async context (such as `setTimeout` or `setInterval`) breaks hot reloading. The system logs an error when this is detected.
|
|
222
|
+
|
|
223
|
+
## Next steps
|
|
224
|
+
|
|
225
|
+
- [Decorators](./3.decorators.md) - Build type-safe decorator factories
|
|
226
|
+
- [Metadata](./4.metadata.md) - Reflection-based metadata retrieval
|