@antelopejs/interface-core 0.1.0 → 0.2.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 (42) hide show
  1. package/dist/caller-binding.d.ts +11 -0
  2. package/dist/caller-binding.js +97 -0
  3. package/dist/caller-binding.js.map +1 -0
  4. package/dist/config.d.ts +15 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/errors.d.ts +1 -1
  7. package/dist/errors.js +1 -1
  8. package/dist/errors.js.map +1 -1
  9. package/dist/internal.d.ts +8 -10
  10. package/dist/internal.js +1 -2
  11. package/dist/internal.js.map +1 -1
  12. package/dist/modules.d.ts +7 -0
  13. package/dist/modules.js +14 -2
  14. package/dist/modules.js.map +1 -1
  15. package/dist/proxies.d.ts +17 -16
  16. package/dist/proxies.js +86 -174
  17. package/dist/proxies.js.map +1 -1
  18. package/dist/tests/caller-context.test.js +139 -0
  19. package/dist/tests/caller-context.test.js.map +1 -0
  20. package/dist/tests/generation-cleanup.test.js +0 -2
  21. package/dist/tests/generation-cleanup.test.js.map +1 -1
  22. package/dist/tests/provider-context.test.js +0 -8
  23. package/dist/tests/provider-context.test.js.map +1 -1
  24. package/dist/tests/queue-and-cleanup.test.js +20 -5
  25. package/dist/tests/queue-and-cleanup.test.js.map +1 -1
  26. package/dist/tests/release-owner.test.d.ts +1 -0
  27. package/dist/tests/release-owner.test.js +34 -0
  28. package/dist/tests/release-owner.test.js.map +1 -0
  29. package/dist/tests/responsible-module.test.js +2 -2
  30. package/dist/tests/responsible-module.test.js.map +1 -1
  31. package/dist/tests/runtime-protocol.test.js +8 -11
  32. package/dist/tests/runtime-protocol.test.js.map +1 -1
  33. package/dist/tests/single-provider.test.d.ts +1 -0
  34. package/dist/tests/single-provider.test.js +55 -0
  35. package/dist/tests/single-provider.test.js.map +1 -0
  36. package/docs/2.proxies.md +20 -7
  37. package/docs/5.modules.md +1 -3
  38. package/docs/7.configuration.md +10 -7
  39. package/package.json +2 -2
  40. package/dist/tests/provider-routing.test.js +0 -78
  41. package/dist/tests/provider-routing.test.js.map +0 -1
  42. /package/dist/tests/{provider-routing.test.d.ts → caller-context.test.d.ts} +0 -0
package/docs/2.proxies.md CHANGED
@@ -4,9 +4,11 @@
4
4
 
5
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
6
 
7
+ A proxy has a single provider and keeps its state on the proxy object itself. When a project has several providers of one interface, the core evaluates a separate instance of the interface package for each provider, so each instance's proxies reach exactly one provider; no call selects a provider at run time.
8
+
7
9
  ## `AsyncProxy`
8
10
 
9
- `AsyncProxy` wraps asynchronous function calls. It queues invocations when no callback is attached and flushes the queue once a callback becomes available.
11
+ `AsyncProxy` wraps asynchronous function calls. It queues invocations when no callback is attached and flushes the queue once a callback becomes available. The queue holds at most 1,000 pending calls: once it is full, further calls reject with `ProviderQueueFullError` until a callback attaches.
10
12
 
11
13
  ### Create and use an `AsyncProxy`
12
14
 
@@ -29,9 +31,9 @@ const greeting = await proxy.call("Bob"); // "Hello, Bob!"
29
31
 
30
32
  ### `onCall(callback, manualDetach?)`
31
33
 
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.
34
+ Attaches the provider's callback to the proxy, replacing any callback attached before, so a provider's new generation takes over from the old one. The proxy automatically tracks the calling module and detaches the callback when that module is unloaded; releasing an older generation never detaches a newer one. Pass `manualDetach: true` to disable automatic cleanup.
33
35
 
34
- When attachment occurs inside `RunWithModuleContext`, calls execute in the captured provider context rather than the consumer context. The captured module, owner generation, provider, and provider routes remain available across nested calls and `await`. Calls reject with `ModuleContextInvalidatedError` if the captured owner has been destroyed.
36
+ When attachment occurs inside `RunWithModuleContext`, calls execute in the captured provider context rather than the consumer context. The captured module and owner generation remain available across nested calls and `await`. Calls reject with `ModuleContextInvalidatedError` if the captured owner has been destroyed.
35
37
 
36
38
  ```ts
37
39
  // Automatic cleanup (default) - detaches when the module unloads
@@ -88,7 +90,7 @@ onUserCreated.emit("u-1", "Alice");
88
90
 
89
91
  ### `register(func)`
90
92
 
91
- 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.
93
+ 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. The handler runs in the context of the module that registered it, whichever module emits the event.
92
94
 
93
95
  ### `emit(...args)`
94
96
 
@@ -100,7 +102,7 @@ Removes a specific handler by function reference.
100
102
 
101
103
  ## `RegisteringProxy`
102
104
 
103
- `RegisteringProxy` manages a register/unregister pair. It tracks registered entries by a unique identifier and supports queuing registrations until the callbacks are attached.
105
+ `RegisteringProxy` manages a register/unregister pair. It tracks registered entries by a unique identifier and keeps every entry so it can replay them when callbacks attach. This registry is not capped: registering entries without an attached provider never throws `ProviderQueueFullError`.
104
106
 
105
107
  ### Create and use a `RegisteringProxy`
106
108
 
@@ -152,6 +154,15 @@ Removes the entry with the given identifier and calls the unregister callback if
152
154
 
153
155
  Manually removes both the register and unregister callbacks. Registered entries remain stored.
154
156
 
157
+ ## Functions passed through a proxy
158
+
159
+ A function a module hands to a proxy runs as that module's work, whoever invokes it later:
160
+
161
+ - an event handler runs in the context of the module that registered it;
162
+ - a function passed as an argument to `AsyncProxy.call` or `RegisteringProxy.register`, or held in a plain object or array passed that way, runs in the context of the module that made the call.
163
+
164
+ Inside such a function, `GetModuleContext` and `GetResponsibleModule` report the module that passed it, and what it registers is owned by that module. Once that module's generation is destroyed, invoking the function throws `ModuleContextInvalidatedError`. Plain data, class instances and proxies cross unchanged; a function passed twice reaches the provider as the same value, and a function passed on by another module keeps its original context.
165
+
155
166
  ## `ImplementInterface`
156
167
 
157
168
  `ImplementInterface` connects an interface declaration to its implementation. It iterates over the declaration object and wires up each proxy to the corresponding implementation function.
@@ -228,17 +239,19 @@ const connections = GetInterfaceInstances("database");
228
239
  const primary = GetInterfaceInstance("database", "primary");
229
240
  ```
230
241
 
231
- Each `InterfaceConnection` includes the provider module ID and whether that provider is selected for unqualified calls:
242
+ Each `InterfaceConnection` includes the path to `require()` for the interface instance bound to that connection, the provider module ID (absent for a connection to a self-hosted interface), and whether it is the connection a plain import reaches:
232
243
 
233
244
  ```ts
234
245
  interface InterfaceConnection {
235
246
  id?: string;
236
247
  path: string;
237
- provider: string;
248
+ provider?: string;
238
249
  selected: boolean;
239
250
  }
240
251
  ```
241
252
 
253
+ Requiring a connection's `path` (or a subpath of it) gives the interface bound to that connection's provider, and the objects built from it stay bound to that provider wherever they are used.
254
+
242
255
  ## `GetResponsibleModule`
243
256
 
244
257
  `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.
package/docs/5.modules.md CHANGED
@@ -37,7 +37,7 @@ loaded -> constructed -> active -> constructed -> loaded
37
37
 
38
38
  ## Module execution context
39
39
 
40
- `RunWithModuleContext` propagates module ownership and provider routing through synchronous and asynchronous work:
40
+ `RunWithModuleContext` propagates module ownership through synchronous and asynchronous work:
41
41
 
42
42
  ```ts
43
43
  import { RunWithModuleContext } from "@antelopejs/interface-core/modules";
@@ -46,8 +46,6 @@ await RunWithModuleContext(
46
46
  {
47
47
  module: "search-provider",
48
48
  owner: "search-provider#42",
49
- provider: "search-provider",
50
- providerRoutes: routes,
51
49
  },
52
50
  () => constructModule(),
53
51
  );
@@ -154,13 +154,16 @@ Like the local source, `local-folder` also accepts an optional `reloadCommand` t
154
154
 
155
155
  Full module configuration within the project config.
156
156
 
157
- | Property | Type | Description |
158
- | ----------------- | -------------------------------------------- | ----------------------------------------------------- |
159
- | `version` | `string` | Optional version constraint |
160
- | `source` | `ModuleSource*` | Source definition (local, git, package, local-folder) |
161
- | `config` | `unknown` | Optional runtime configuration |
162
- | `importOverrides` | `ImportOverride[] \| Record<string, string>` | Optional import path redirections |
163
- | `disabledExports` | `string[]` | Optional list of exports to disable |
157
+ | Property | Type | Description |
158
+ | ----------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
159
+ | `version` | `string` | Optional version constraint |
160
+ | `source` | `ModuleSource*` | Source definition (local, git, package, local-folder) |
161
+ | `config` | `unknown` | Optional runtime configuration |
162
+ | `importOverrides` | `ImportOverride[] \| Record<string, string>` | Optional providers pinned for the interfaces the module uses, and named connections |
163
+ | `disabledExports` | `string[]` | Optional list of exports to disable |
164
+ | `exportPriority` | `Record<string, number>` | Optional priority of this module as the default provider of each interface it implements (default 0; highest wins) |
165
+
166
+ An `ImportOverride` is `{ interface, source?, id? }`. The first entry for an interface pins it to the `source` module; further entries are connections reached through `GetInterfaceInstance(interface, id)`. An entry for a standalone interface may omit `source`, declaring a connection to that self-hosted interface.
164
167
 
165
168
  ## `AntelopeLogging`
166
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/interface-core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "AntelopeJS core interface primitives - proxies, decorators, interface functions, and logging",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -90,7 +90,7 @@
90
90
  "reflect-metadata": "^0.2.2"
91
91
  },
92
92
  "devDependencies": {
93
- "@antelopejs/tooling-configs": "^0.0.4",
93
+ "@antelopejs/tooling-configs": "^0.0.6",
94
94
  "@types/chai": "^4.3.20",
95
95
  "@types/mocha": "^10.0.10",
96
96
  "@types/node": "^22.19.15",
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const chai_1 = require("chai");
4
- const modules_1 = require("../modules");
5
- const __1 = require("..");
6
- describe("provider routing and leases", () => {
7
- it("routes providers through async module execution context", async () => {
8
- const proxy = new __1.AsyncProxy("test.provider-routing");
9
- (0, modules_1.RunWithModuleContext)({ module: "owner-a", provider: "provider-a" }, () => {
10
- proxy.onCall(() => "a");
11
- });
12
- (0, modules_1.RunWithModuleContext)({ module: "owner-b", provider: "provider-b" }, () => {
13
- proxy.onCall(() => "b");
14
- });
15
- (0, chai_1.expect)(await (0, modules_1.RunWithModuleContext)({ module: "consumer", provider: "provider-a" }, () => proxy.call())).to.equal("a");
16
- (0, chai_1.expect)(await (0, modules_1.RunWithModuleContext)({ module: "consumer", provider: "provider-b" }, () => proxy.call())).to.equal("b");
17
- const error = await proxy.call().then(() => undefined, (reason) => reason);
18
- (0, chai_1.expect)(error).to.be.instanceOf(__1.AmbiguousProviderError);
19
- });
20
- it("rejects an explicit route that has no attached provider", async () => {
21
- const proxy = new __1.AsyncProxy("test.missing-route");
22
- (0, modules_1.RunWithModuleContext)({ module: "owner", provider: "available" }, () => {
23
- proxy.onCall(() => "ok");
24
- });
25
- const result = (0, modules_1.RunWithModuleContext)({ module: "consumer", provider: "missing" }, () => proxy.call());
26
- const error = await result.then(() => undefined, (reason) => reason);
27
- (0, chai_1.expect)(error).to.be.instanceOf(__1.MissingProviderError);
28
- });
29
- it("supports per-proxy provider bindings in one module context", async () => {
30
- const first = new __1.AsyncProxy("test.route-map.first");
31
- const second = new __1.AsyncProxy("test.route-map.second");
32
- (0, modules_1.RunWithModuleContext)({ module: "owner-a", provider: "provider-a" }, () => {
33
- first.onCall(() => "first-a");
34
- second.onCall(() => "second-a");
35
- });
36
- (0, modules_1.RunWithModuleContext)({ module: "owner-b", provider: "provider-b" }, () => {
37
- first.onCall(() => "first-b");
38
- second.onCall(() => "second-b");
39
- });
40
- const firstIdentity = (0, __1.GetInterfaceProxyIdentity)(first);
41
- const secondIdentity = (0, __1.GetInterfaceProxyIdentity)(second);
42
- const values = await (0, modules_1.RunWithModuleContext)({
43
- module: "consumer",
44
- providerRoutes: {
45
- [firstIdentity]: "provider-a",
46
- [secondIdentity]: "provider-b",
47
- },
48
- }, () => Promise.all([first.call(), second.call()]));
49
- (0, chai_1.expect)(values).to.deep.equal(["first-a", "second-b"]);
50
- });
51
- it("routes registrations and unregisters to the bound provider", () => {
52
- const proxy = new __1.RegisteringProxy("test.registering-routes");
53
- const calls = [];
54
- (0, modules_1.RunWithModuleContext)({ module: "owner-a", provider: "provider-a" }, () => {
55
- proxy.onHandlers((id) => calls.push(`register-a:${id}`), (id) => calls.push(`unregister-a:${id}`));
56
- });
57
- (0, modules_1.RunWithModuleContext)({ module: "owner-b", provider: "provider-b" }, () => {
58
- proxy.onHandlers((id) => calls.push(`register-b:${id}`), (id) => calls.push(`unregister-b:${id}`));
59
- });
60
- (0, modules_1.RunWithModuleContext)({ module: "consumer", provider: "provider-b" }, () => {
61
- proxy.register("item");
62
- proxy.unregister("item");
63
- });
64
- (0, chai_1.expect)(calls).to.deep.equal(["register-b:item", "unregister-b:item"]);
65
- });
66
- it("does not let an old owner lease detach a newer provider generation", async () => {
67
- const proxy = new __1.AsyncProxy("test.provider-lease");
68
- (0, modules_1.RunWithModuleContext)({ module: "owner-a", provider: "shared" }, () => {
69
- proxy.onCall(() => "old");
70
- });
71
- (0, modules_1.RunWithModuleContext)({ module: "owner-b", provider: "shared" }, () => {
72
- proxy.onCall(() => "new");
73
- });
74
- modules_1.Events.ModuleDestroyed.emit("owner-a");
75
- (0, chai_1.expect)(await (0, modules_1.RunWithModuleContext)({ module: "consumer", provider: "shared" }, () => proxy.call())).to.equal("new");
76
- });
77
- });
78
- //# sourceMappingURL=provider-routing.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"provider-routing.test.js","sourceRoot":"","sources":["../../src/tests/provider-routing.test.ts"],"names":[],"mappings":"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"}