@antelopejs/interface-core 0.0.10 → 0.0.12

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,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chai_1 = require("chai");
4
+ const __1 = require("..");
5
+ const modules_1 = require("../modules");
6
+ function observeContext() {
7
+ const context = (0, modules_1.GetModuleContext)();
8
+ return {
9
+ module: context?.module,
10
+ owner: context?.owner,
11
+ provider: context?.provider,
12
+ };
13
+ }
14
+ describe("provider callback context", () => {
15
+ it("restores async provider context across awaits and nested calls", async () => {
16
+ const nested = new __1.AsyncProxy("context.nested");
17
+ const outer = new __1.AsyncProxy("context.outer");
18
+ const nestedIdentity = (0, __1.GetInterfaceProxyIdentity)(nested);
19
+ const outerIdentity = (0, __1.GetInterfaceProxyIdentity)(outer);
20
+ (0, modules_1.RunWithModuleContext)({ module: "nested-owner", owner: "nested#1", provider: "nested" }, () => nested.onCall(() => `${observeContext().owner}:value`));
21
+ (0, modules_1.RunWithModuleContext)({
22
+ module: "provider-owner",
23
+ owner: "provider-owner#1",
24
+ provider: "provider-a",
25
+ providerRoutes: { [nestedIdentity]: "nested" },
26
+ }, () => outer.onCall(async () => {
27
+ const beforeAwait = observeContext();
28
+ await Promise.resolve();
29
+ const afterAwait = observeContext();
30
+ (0, chai_1.expect)(await nested.call()).to.equal("nested#1:value");
31
+ return [beforeAwait, afterAwait, observeContext()];
32
+ }));
33
+ const observations = await (0, modules_1.RunWithModuleContext)({
34
+ module: "consumer",
35
+ owner: "consumer#1",
36
+ providerRoutes: { [outerIdentity]: "provider-a" },
37
+ }, () => outer.call());
38
+ (0, chai_1.expect)(observations).to.deep.equal(Array.from({ length: 3 }, () => ({
39
+ module: "provider-owner",
40
+ owner: "provider-owner#1",
41
+ provider: "provider-a",
42
+ })));
43
+ });
44
+ it("restores registering context for replay, register and unregister", () => {
45
+ const proxy = new __1.RegisteringProxy("context.registering");
46
+ const identity = (0, __1.GetInterfaceProxyIdentity)(proxy);
47
+ const observations = [];
48
+ (0, modules_1.RunWithModuleContext)({ module: "consumer", owner: "consumer#1" }, () => {
49
+ proxy.register("queued");
50
+ });
51
+ (0, modules_1.RunWithModuleContext)({ module: "provider-owner", owner: "provider#1", provider: "provider" }, () => {
52
+ proxy.onHandlers((id) => observations.push({
53
+ operation: `register:${id}`,
54
+ context: observeContext(),
55
+ }), (id) => observations.push({
56
+ operation: `unregister:${id}`,
57
+ context: observeContext(),
58
+ }));
59
+ });
60
+ (0, modules_1.RunWithModuleContext)({
61
+ module: "consumer",
62
+ owner: "consumer#1",
63
+ providerRoutes: { [identity]: "provider" },
64
+ }, () => {
65
+ proxy.register("direct");
66
+ proxy.unregister("queued");
67
+ proxy.unregister("direct");
68
+ });
69
+ (0, chai_1.expect)(observations.map(({ operation }) => operation)).to.deep.equal([
70
+ "register:queued",
71
+ "register:direct",
72
+ "unregister:queued",
73
+ "unregister:direct",
74
+ ]);
75
+ (0, chai_1.expect)(observations.map(({ context }) => context)).to.deep.equal(Array.from({ length: 4 }, () => ({
76
+ module: "provider-owner",
77
+ owner: "provider#1",
78
+ provider: "provider",
79
+ })));
80
+ });
81
+ it("preserves synchronous registering callback throws", () => {
82
+ const proxy = new __1.RegisteringProxy("context.registering-throw");
83
+ const failure = new Error("register failed");
84
+ (0, modules_1.RunWithModuleContext)({ module: "provider", owner: "provider-throw#1", provider: "provider" }, () => proxy.onHandlers(() => {
85
+ (0, chai_1.expect)(observeContext().owner).to.equal("provider-throw#1");
86
+ throw failure;
87
+ }, () => undefined));
88
+ (0, chai_1.expect)(() => proxy.register("item")).to.throw(failure);
89
+ });
90
+ it("rejects callbacks captured from an invalidated owner", async () => {
91
+ const proxy = new __1.AsyncProxy("context.invalidated");
92
+ const identity = (0, __1.GetInterfaceProxyIdentity)(proxy);
93
+ (0, modules_1.RunWithModuleContext)({ module: "provider", owner: "provider-old#1", provider: "provider" }, () => {
94
+ proxy.onCall(() => "stale", true);
95
+ modules_1.Events.ModuleDestroyed.emit("provider");
96
+ });
97
+ const error = await (0, modules_1.RunWithModuleContext)({
98
+ module: "consumer",
99
+ owner: "consumer#1",
100
+ providerRoutes: { [identity]: "provider" },
101
+ }, () => proxy.call().then(() => undefined, (reason) => reason));
102
+ (0, chai_1.expect)(error).to.be.instanceOf(__1.ModuleContextInvalidatedError);
103
+ });
104
+ it("rejects registering handlers captured from an invalidated owner", () => {
105
+ const proxy = new __1.RegisteringProxy("context.invalidated-registering");
106
+ (0, modules_1.RunWithModuleContext)({
107
+ module: "provider",
108
+ owner: "provider-register#old",
109
+ provider: "provider",
110
+ }, () => {
111
+ proxy.onHandlers(() => undefined, () => undefined, true);
112
+ modules_1.Events.ModuleDestroyed.emit("provider");
113
+ });
114
+ (0, chai_1.expect)(() => proxy.register("item")).to.throw(__1.ModuleContextInvalidatedError);
115
+ });
116
+ });
117
+ //# sourceMappingURL=provider-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-context.test.js","sourceRoot":"","sources":["../../src/tests/provider-context.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,94 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const node_child_process_1 = require("node:child_process");
37
+ const node_path_1 = require("node:path");
38
+ const chai_1 = require("chai");
39
+ const declarations = __importStar(require(".."));
40
+ const modules = __importStar(require("../modules"));
41
+ const runtime = __importStar(require("../runtime"));
42
+ const PACKAGE_ROOT = (0, node_path_1.resolve)(__dirname, "..", "..");
43
+ const FRESH_PROCESS_CONTRACT = `
44
+ const assert = require("node:assert/strict");
45
+ const path = require("node:path");
46
+ const root = process.env.INTERFACE_CORE_ROOT;
47
+ const entries = {
48
+ root: path.join(root, "dist"),
49
+ modules: path.join(root, "dist", "modules.js"),
50
+ runtime: path.join(root, "dist", "runtime.js"),
51
+ };
52
+ const loaded = Object.fromEntries(
53
+ process.env.INTERFACE_CORE_ORDER.split(",").map((entry) => [entry, require(entries[entry])]),
54
+ );
55
+ const core = loaded.root;
56
+ const modules = loaded.modules;
57
+ const runtime = loaded.runtime;
58
+ assert.equal(core.Events, modules.Events);
59
+ assert.equal(core.ListModules, modules.ListModules);
60
+ assert.equal(core.GetModuleInfo, modules.GetModuleInfo);
61
+ assert.equal(core.GetRuntimeInfo, runtime.GetRuntimeInfo);
62
+ assert.equal(core.RegisterDevServer, runtime.RegisterDevServer);
63
+ assert.equal(core.IsInterfaceProxy(core.ListModules.proxy), true);
64
+ assert.equal(core.IsInterfaceProxy(core.GetRuntimeInfo.proxy), true);
65
+ assert.equal(core.GetInterfaceProxyIdentity(core.ListModules.proxy), "async:modules.ListModules");
66
+ assert.equal(core.GetInterfaceProxyIdentity(core.GetRuntimeInfo.proxy), "async:runtime.GetRuntimeInfo");
67
+ `;
68
+ function runFreshProcess(order) {
69
+ (0, node_child_process_1.execFileSync)(process.execPath, ["-e", FRESH_PROCESS_CONTRACT], {
70
+ env: {
71
+ ...process.env,
72
+ INTERFACE_CORE_ORDER: order,
73
+ INTERFACE_CORE_ROOT: PACKAGE_ROOT,
74
+ },
75
+ });
76
+ }
77
+ describe("root interface declarations", () => {
78
+ it("exports the canonical runtime proxies", () => {
79
+ (0, chai_1.expect)(declarations.GetRuntimeInfo).to.equal(runtime.GetRuntimeInfo);
80
+ (0, chai_1.expect)(declarations.RegisterDevServer).to.equal(runtime.RegisterDevServer);
81
+ });
82
+ it("exports the canonical module proxies", () => {
83
+ (0, chai_1.expect)(declarations.Events).to.equal(modules.Events);
84
+ (0, chai_1.expect)(declarations.ListModules).to.equal(modules.ListModules);
85
+ (0, chai_1.expect)(declarations.GetModuleInfo).to.equal(modules.GetModuleInfo);
86
+ });
87
+ it("loads complete canonical declarations when the root loads first", () => {
88
+ runFreshProcess("root,runtime,modules");
89
+ });
90
+ it("loads complete canonical declarations when subpaths load first", () => {
91
+ runFreshProcess("modules,runtime,root");
92
+ });
93
+ });
94
+ //# sourceMappingURL=root-declarations.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-declarations.test.js","sourceRoot":"","sources":["../../src/tests/root-declarations.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2DAAkD;AAClD,yCAAoC;AACpC,+BAA8B;AAC9B,iDAAmC;AACnC,oDAAsC;AACtC,oDAAsC;AAEtC,MAAM,YAAY,GAAG,IAAA,mBAAO,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACpD,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwB9B,CAAC;AAEF,SAAS,eAAe,CAAC,KAAa;IACpC,IAAA,iCAAY,EAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE;QAC7D,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,oBAAoB,EAAE,KAAK;YAC3B,mBAAmB,EAAE,YAAY;SAClC;KACF,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,IAAA,aAAM,EAAC,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACrE,IAAA,aAAM,EAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,IAAA,aAAM,EAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAA,aAAM,EAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAA,aAAM,EAAC,YAAY,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -5,6 +5,7 @@ const node_fs_1 = require("node:fs");
5
5
  const node_path_1 = require("node:path");
6
6
  const chai_1 = require("chai");
7
7
  const __1 = require("..");
8
+ const modules_1 = require("../modules");
8
9
  describe("global runtime protocol", () => {
9
10
  let copyPath;
10
11
  afterEach(() => {
@@ -18,16 +19,19 @@ describe("global runtime protocol", () => {
18
19
  copyPath = (0, node_path_1.join)(temporary, "dist");
19
20
  (0, node_fs_1.cpSync)((0, node_path_1.join)(__dirname, ".."), copyPath, { recursive: true });
20
21
  const foreign = require((0, node_path_1.join)(copyPath, "index.js"));
22
+ const foreignModules = require((0, node_path_1.join)(copyPath, "modules.js"));
21
23
  const localProxy = new __1.AsyncProxy("test.cross-copy");
22
24
  const foreignProxy = new foreign.AsyncProxy("test.cross-copy");
23
25
  (0, chai_1.expect)(foreignProxy).not.to.be.instanceOf(__1.AsyncProxy);
24
26
  (0, chai_1.expect)((0, __1.RunWithResponsibleModule)("shared-owner", () => foreign.GetResponsibleModule())).to.equal("shared-owner");
25
- foreign.ImplementInterface({ proxy: localProxy }, { proxy: () => "shared" });
26
- (0, chai_1.expect)(await foreignProxy.call()).to.equal("shared");
27
- (0, __1.ImplementInterface)({ proxy: foreignProxy }, {
28
- proxy: () => "local",
29
- });
30
- (0, chai_1.expect)(await localProxy.call()).to.equal("local");
27
+ (0, modules_1.RunWithModuleContext)({ module: "provider", owner: "provider#copy", provider: "provider" }, () => foreign.ImplementInterface({ proxy: localProxy }, {
28
+ proxy: () => foreignModules.GetModuleContext()?.owner ?? "missing",
29
+ }));
30
+ (0, chai_1.expect)(await (0, modules_1.RunWithModuleContext)({
31
+ module: "consumer",
32
+ owner: "consumer#copy",
33
+ providerRoutes: { "async:test.cross-copy": "provider" },
34
+ }, () => foreignProxy.call())).to.equal("provider#copy");
31
35
  });
32
36
  it("fails clearly when a realm already contains an incompatible protocol", () => {
33
37
  const internalPath = (0, node_path_1.join)(__dirname, "..", "internal.js");
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-protocol.test.js","sourceRoot":"","sources":["../../src/tests/runtime-protocol.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-protocol.test.js","sourceRoot":"","sources":["../../src/tests/runtime-protocol.test.ts"],"names":[],"mappings":"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"}
package/docs/2.proxies.md CHANGED
@@ -31,6 +31,8 @@ const greeting = await proxy.call("Bob"); // "Hello, Bob!"
31
31
 
32
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
33
 
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.
35
+
34
36
  ```ts
35
37
  // Automatic cleanup (default) - detaches when the module unloads
36
38
  proxy.onCall(myHandler);
@@ -127,10 +129,14 @@ routeRegistry.unregister("about");
127
129
 
128
130
  Attaches the register callback. Any previously registered entries replay through this callback immediately. Automatic module-aware detachment applies unless `manualDetach` is `true`.
129
131
 
132
+ Register replay and direct registration execute in the provider context captured when the callback attaches.
133
+
130
134
  ### `onUnregister(callback)`
131
135
 
132
136
  Attaches the unregister callback. This callback is detached at the same time as the register callback.
133
137
 
138
+ Unregistration executes in the context captured when this callback attaches.
139
+
134
140
  ### `register(id, ...args)`
135
141
 
136
142
  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.
@@ -208,6 +214,17 @@ const connections = GetInterfaceInstances("database");
208
214
  const primary = GetInterfaceInstance("database", "primary");
209
215
  ```
210
216
 
217
+ Each `InterfaceConnection` includes the provider module ID and whether that provider is selected for unqualified calls:
218
+
219
+ ```ts
220
+ interface InterfaceConnection {
221
+ id?: string;
222
+ path: string;
223
+ provider: string;
224
+ selected: boolean;
225
+ }
226
+ ```
227
+
211
228
  ## `GetResponsibleModule`
212
229
 
213
230
  `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.
@@ -235,7 +252,7 @@ await RunWithResponsibleModule("my-module", async () => {
235
252
 
236
253
  The module loader should wrap known module-owned entry points, including module evaluation and lifecycle hooks. Existing callers need no migration: outside an explicit context, `GetResponsibleModule` retains stack-based resolution as a backward-compatible fallback. Automatic proxy detachment and registration cleanup use the resolved module in both paths.
237
254
 
238
- Ownership contexts are scoped to a loaded module generation. `ModuleDestroyed` invalidates that generation before cleanup, so detached asynchronous work cannot add stale providers or handlers afterward. Such work receives a `ModuleContextInvalidatedError`. A later invocation for the same module ID creates a fresh generation without reactivating older contexts.
255
+ Ownership contexts are scoped to a loaded module generation. Loaders that can overlap old and replacement instances should use `RunWithModuleContext` and provide a unique `owner` for every generation. `ModuleDestroyed` invalidates and cleans only the active event context's owner while preserving the existing module ID event contract. Detached asynchronous work from that owner then receives a `ModuleContextInvalidatedError`.
239
256
 
240
257
  ## Next steps
241
258
 
package/docs/5.modules.md CHANGED
@@ -35,6 +35,26 @@ loaded -> constructed -> active -> constructed -> loaded
35
35
  | `active` | Module is fully started and providing services |
36
36
  | `unknown` | Module status cannot be determined |
37
37
 
38
+ ## Module execution context
39
+
40
+ `RunWithModuleContext` propagates module ownership and provider routing through synchronous and asynchronous work:
41
+
42
+ ```ts
43
+ import { RunWithModuleContext } from "@antelopejs/interface-core/modules";
44
+
45
+ await RunWithModuleContext(
46
+ {
47
+ module: "search-provider",
48
+ owner: "search-provider#42",
49
+ provider: "search-provider",
50
+ providerRoutes: routes,
51
+ },
52
+ () => constructModule(),
53
+ );
54
+ ```
55
+
56
+ `module` remains the stable public module ID. `owner` identifies one lifecycle generation and should be unique when old and replacement instances can overlap. Providers capture this full context when attaching callbacks. `GetModuleContext` returns the active context and throws `ModuleContextInvalidatedError` after its owner is destroyed.
57
+
38
58
  ## Lifecycle events
39
59
 
40
60
  The `Events` namespace exposes four `EventProxy` instances that fire during module lifecycle transitions.
@@ -81,6 +101,8 @@ Events.ModuleDestroyed.register((moduleId: string) => {
81
101
  });
82
102
  ```
83
103
 
104
+ The event signature remains the module ID. When emitted inside `RunWithModuleContext`, cleanup targets that context's `owner`; without an explicit owner it retains the module-level behavior used by earlier releases.
105
+
84
106
  ## Management functions
85
107
 
86
108
  These functions are declared as `InterfaceFunction` proxies. They are available once the core runtime provides their implementation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/interface-core",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "AntelopeJS core interface primitives - proxies, decorators, interface functions, and logging",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -78,7 +78,8 @@
78
78
  "lint": "biome check .",
79
79
  "prepack": "pnpm run build",
80
80
  "release": "pnpm run lint && pnpm run prepack && release-it",
81
- "test": "pnpm run build && ajs module test ."
81
+ "test": "pnpm run build && ajs module test .",
82
+ "test:package": "node test/package-consumer.mjs"
82
83
  },
83
84
  "antelopeJs": {
84
85
  "test": "src/antelope.test.ts",