@adobe/data-rpc 0.10.11

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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/dist/arg-async.test.d.ts +1 -0
  4. package/dist/arg-async.test.js +147 -0
  5. package/dist/arg-async.test.js.map +1 -0
  6. package/dist/arg-marshal.d.ts +34 -0
  7. package/dist/arg-marshal.js +90 -0
  8. package/dist/arg-marshal.js.map +1 -0
  9. package/dist/arg-observe.test.d.ts +1 -0
  10. package/dist/arg-observe.test.js +114 -0
  11. package/dist/arg-observe.test.js.map +1 -0
  12. package/dist/consume/caller-context.d.ts +47 -0
  13. package/dist/consume/caller-context.js +3 -0
  14. package/dist/consume/caller-context.js.map +1 -0
  15. package/dist/consume/make-generator.d.ts +16 -0
  16. package/dist/consume/make-generator.js +75 -0
  17. package/dist/consume/make-generator.js.map +1 -0
  18. package/dist/consume/make-observe.d.ts +16 -0
  19. package/dist/consume/make-observe.js +29 -0
  20. package/dist/consume/make-observe.js.map +1 -0
  21. package/dist/consume/make-promise.d.ts +12 -0
  22. package/dist/consume/make-promise.js +32 -0
  23. package/dist/consume/make-promise.js.map +1 -0
  24. package/dist/consume/make-void.d.ts +12 -0
  25. package/dist/consume/make-void.js +17 -0
  26. package/dist/consume/make-void.js.map +1 -0
  27. package/dist/consume/reconstruct-error.d.ts +7 -0
  28. package/dist/consume/reconstruct-error.js +14 -0
  29. package/dist/consume/reconstruct-error.js.map +1 -0
  30. package/dist/consume/synthesize-service.d.ts +10 -0
  31. package/dist/consume/synthesize-service.js +77 -0
  32. package/dist/consume/synthesize-service.js.map +1 -0
  33. package/dist/create-endpoint.d.ts +8 -0
  34. package/dist/create-endpoint.js +462 -0
  35. package/dist/create-endpoint.js.map +1 -0
  36. package/dist/endpoint.d.ts +64 -0
  37. package/dist/endpoint.js +3 -0
  38. package/dist/endpoint.js.map +1 -0
  39. package/dist/host/host-context.d.ts +28 -0
  40. package/dist/host/host-context.js +3 -0
  41. package/dist/host/host-context.js.map +1 -0
  42. package/dist/host/marshal-error.d.ts +8 -0
  43. package/dist/host/marshal-error.js +15 -0
  44. package/dist/host/marshal-error.js.map +1 -0
  45. package/dist/host/register-service.d.ts +10 -0
  46. package/dist/host/register-service.js +169 -0
  47. package/dist/host/register-service.js.map +1 -0
  48. package/dist/id.d.ts +7 -0
  49. package/dist/id.js +12 -0
  50. package/dist/id.js.map +1 -0
  51. package/dist/index.d.ts +7 -0
  52. package/dist/index.js +7 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/nested.test.d.ts +1 -0
  55. package/dist/nested.test.js +128 -0
  56. package/dist/nested.test.js.map +1 -0
  57. package/dist/protocol.d.ts +157 -0
  58. package/dist/protocol.js +18 -0
  59. package/dist/protocol.js.map +1 -0
  60. package/dist/review-fixes.test.d.ts +1 -0
  61. package/dist/review-fixes.test.js +200 -0
  62. package/dist/review-fixes.test.js.map +1 -0
  63. package/dist/rpc.test.d.ts +1 -0
  64. package/dist/rpc.test.js +250 -0
  65. package/dist/rpc.test.js.map +1 -0
  66. package/dist/transport.d.ts +32 -0
  67. package/dist/transport.js +3 -0
  68. package/dist/transport.js.map +1 -0
  69. package/dist/transports/loopback-transport.d.ts +13 -0
  70. package/dist/transports/loopback-transport.js +102 -0
  71. package/dist/transports/loopback-transport.js.map +1 -0
  72. package/dist/transports/loopback-transport.test.d.ts +1 -0
  73. package/dist/transports/loopback-transport.test.js +42 -0
  74. package/dist/transports/loopback-transport.test.js.map +1 -0
  75. package/dist/transports/message-port-transport.d.ts +14 -0
  76. package/dist/transports/message-port-transport.js +63 -0
  77. package/dist/transports/message-port-transport.js.map +1 -0
  78. package/dist/transports/message-port-transport.test.d.ts +1 -0
  79. package/dist/transports/message-port-transport.test.js +49 -0
  80. package/dist/transports/message-port-transport.test.js.map +1 -0
  81. package/dist/transports/window-transport.d.ts +20 -0
  82. package/dist/transports/window-transport.js +69 -0
  83. package/dist/transports/window-transport.js.map +1 -0
  84. package/dist/transports/window-transport.test.d.ts +1 -0
  85. package/dist/transports/window-transport.test.js +47 -0
  86. package/dist/transports/window-transport.test.js.map +1 -0
  87. package/package.json +38 -0
@@ -0,0 +1,200 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ // Red tests pinning the PR #197 review findings. Each fails before its fix.
3
+ import { describe, it, expect } from "vitest";
4
+ import { Observe } from "@adobe/data/observe";
5
+ import { createRpcEndpoint } from "./create-endpoint.js";
6
+ import { createRpcLoopbackTransport } from "./transports/loopback-transport.js";
7
+ const flush = async (times = 12) => {
8
+ for (let i = 0; i < times; i++)
9
+ await new Promise((r) => setTimeout(r, 0));
10
+ };
11
+ const ignoreSchema = {
12
+ type: "object",
13
+ properties: {
14
+ ignoreArg: { type: "function", signature: { parameters: [{ type: "promise", value: { type: "number" } }], returns: { type: "promise" } } },
15
+ },
16
+ required: ["ignoreArg"],
17
+ additionalProperties: false,
18
+ };
19
+ describe("B1 — rejecting promise arg ignored by the member", () => {
20
+ it("does not raise an unhandled rejection", async () => {
21
+ const rejections = [];
22
+ const onUnhandled = (r) => rejections.push(r);
23
+ process.on("unhandledRejection", onUnhandled);
24
+ try {
25
+ const { a, b } = createRpcLoopbackTransport();
26
+ const ea = createRpcEndpoint(a);
27
+ const eb = createRpcEndpoint(b);
28
+ const service = {
29
+ serviceName: "ignore",
30
+ schema: Observe.fromConstant(ignoreSchema),
31
+ ignoreArg: async () => undefined, // never touches the promise arg
32
+ };
33
+ ea.expose("ignore", service, ignoreSchema);
34
+ const svc = eb.consume("ignore", ignoreSchema);
35
+ await svc.ignoreArg(Promise.reject(new Error("boom")));
36
+ await flush();
37
+ await new Promise((r) => setTimeout(r, 30)); // let any unhandledRejection fire
38
+ expect(rejections).toEqual([]);
39
+ ea.close();
40
+ eb.close();
41
+ }
42
+ finally {
43
+ process.off("unhandledRejection", onUnhandled);
44
+ }
45
+ });
46
+ });
47
+ const lateSchema = {
48
+ type: "object",
49
+ properties: {
50
+ lateAwait: { type: "function", signature: { parameters: [{ type: "promise", value: { type: "number" } }], returns: { type: "promise" } } },
51
+ result: { type: "observe", value: { type: "string" } },
52
+ lateDrain: { type: "function", signature: { parameters: [{ type: "generator", value: { type: "number" } }], returns: { type: "promise" } } },
53
+ drained: { type: "observe", value: { type: "string" } },
54
+ },
55
+ required: ["lateAwait", "result", "lateDrain", "drained"],
56
+ additionalProperties: false,
57
+ };
58
+ function makeLate() {
59
+ const [result, setResult] = Observe.createState("pending");
60
+ const [drained, setDrained] = Observe.createState("pending");
61
+ return {
62
+ serviceName: "late",
63
+ schema: Observe.fromConstant(lateSchema),
64
+ result,
65
+ drained,
66
+ lateAwait: async (p) => {
67
+ // Return immediately; consume the arg later, in the background.
68
+ void p.then((v) => setResult(`resolved:${v}`), (e) => setResult(`rejected:${e.message}`));
69
+ },
70
+ lateDrain: async (g) => {
71
+ void (async () => {
72
+ let sum = 0;
73
+ try {
74
+ for await (const n of g)
75
+ sum += n;
76
+ setDrained(`done:${sum}`);
77
+ }
78
+ catch (e) {
79
+ setDrained(`err:${e.message}`);
80
+ }
81
+ })();
82
+ },
83
+ };
84
+ }
85
+ describe("S1 — arg consumed after the call completes", () => {
86
+ it("settles a promise arg instead of hanging the callee", async () => {
87
+ const { a, b } = createRpcLoopbackTransport();
88
+ const ea = createRpcEndpoint(a);
89
+ const eb = createRpcEndpoint(b);
90
+ ea.expose("late", makeLate(), lateSchema);
91
+ const svc = eb.consume("late", lateSchema);
92
+ const seen = [];
93
+ svc.result((v) => seen.push(v));
94
+ let resolveArg;
95
+ const arg = new Promise((r) => (resolveArg = r));
96
+ await svc.lateAwait(arg); // call resolves before the arg is consumed
97
+ resolveArg(42);
98
+ await flush();
99
+ expect(seen.at(-1)).not.toBe("pending"); // callee's arg promise must settle
100
+ ea.close();
101
+ eb.close();
102
+ });
103
+ it("terminates a generator arg instead of hanging the callee", async () => {
104
+ const { a, b } = createRpcLoopbackTransport();
105
+ const ea = createRpcEndpoint(a);
106
+ const eb = createRpcEndpoint(b);
107
+ ea.expose("late", makeLate(), lateSchema);
108
+ const svc = eb.consume("late", lateSchema);
109
+ const seen = [];
110
+ svc.drained((v) => seen.push(v));
111
+ async function* nums() {
112
+ yield 1;
113
+ yield 2;
114
+ yield 3;
115
+ }
116
+ await svc.lateDrain(nums());
117
+ await flush();
118
+ expect(seen.at(-1)).not.toBe("pending"); // callee's for-await must terminate
119
+ ea.close();
120
+ eb.close();
121
+ });
122
+ });
123
+ const greetSchema = {
124
+ type: "object",
125
+ properties: { greet: { type: "function", signature: { returns: { type: "promise", value: { type: "string" } } } } },
126
+ required: ["greet"],
127
+ additionalProperties: false,
128
+ };
129
+ describe("S2 — prototype-chain path traversal", () => {
130
+ it("rejects path ['constructor'] rather than invoking Object", async () => {
131
+ const { a, b } = createRpcLoopbackTransport();
132
+ const ea = createRpcEndpoint(a);
133
+ const service = {
134
+ serviceName: "greet",
135
+ schema: Observe.fromConstant(greetSchema),
136
+ greet: async () => "hi",
137
+ };
138
+ ea.expose("greet", service, greetSchema);
139
+ const responses = [];
140
+ b.onMessage((m) => responses.push(m));
141
+ b.send({ kind: "call", id: 999, service: "greet", path: ["constructor"], args: [] });
142
+ await flush();
143
+ const resp = responses.find((m) => "id" in m && m.id === 999);
144
+ expect(resp?.kind).toBe("reject"); // not a resolve from calling Object()
145
+ ea.close();
146
+ });
147
+ });
148
+ const voidArgSchema = {
149
+ type: "object",
150
+ properties: {
151
+ logObs: { type: "function", signature: { parameters: [{ type: "observe", value: { type: "number" } }] } },
152
+ },
153
+ required: ["logObs"],
154
+ additionalProperties: false,
155
+ };
156
+ describe("S4 — constructor arg on a void member", () => {
157
+ it("throws rather than silently leaking a provider", async () => {
158
+ const { a, b } = createRpcLoopbackTransport();
159
+ const ea = createRpcEndpoint(a);
160
+ const eb = createRpcEndpoint(b);
161
+ const service = {
162
+ serviceName: "voidarg",
163
+ schema: Observe.fromConstant(voidArgSchema),
164
+ logObs: () => undefined,
165
+ };
166
+ ea.expose("voidarg", service, voidArgSchema);
167
+ const svc = eb.consume("voidarg", voidArgSchema);
168
+ expect(() => svc.logObs(Observe.fromConstant(1))).toThrowError(/void member/i);
169
+ ea.close();
170
+ eb.close();
171
+ });
172
+ });
173
+ const awaitSchema = {
174
+ type: "object",
175
+ properties: {
176
+ awaitIt: { type: "function", signature: { parameters: [{ type: "promise", value: { type: "number" } }], returns: { type: "promise", value: { type: "number" } } } },
177
+ },
178
+ required: ["awaitIt"],
179
+ additionalProperties: false,
180
+ };
181
+ describe("N2 — raw value at a constructor position", () => {
182
+ it("passes a bare number through instead of treating it as a ref", async () => {
183
+ const { a, b } = createRpcLoopbackTransport();
184
+ const ea = createRpcEndpoint(a);
185
+ const eb = createRpcEndpoint(b, { defaultTimeoutMs: 250 });
186
+ const service = {
187
+ serviceName: "await",
188
+ schema: Observe.fromConstant(awaitSchema),
189
+ awaitIt: async (p) => await p,
190
+ };
191
+ ea.expose("await", service, awaitSchema);
192
+ const svc = eb.consume("await", awaitSchema);
193
+ // Caller misuse: a raw number where the schema says `promise`.
194
+ const untyped = svc;
195
+ expect(await untyped.awaitIt(5)).toBe(5);
196
+ ea.close();
197
+ eb.close();
198
+ });
199
+ });
200
+ //# sourceMappingURL=review-fixes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-fixes.test.js","sourceRoot":"","sources":["../src/review-fixes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,250 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { describe, it, expect, vi } from "vitest";
3
+ import { Observe } from "@adobe/data/observe";
4
+ import { createRpcEndpoint } from "./create-endpoint.js";
5
+ import { createRpcLoopbackTransport } from "./transports/loopback-transport.js";
6
+ var DemoService;
7
+ (function (DemoService) {
8
+ DemoService.schema = {
9
+ type: "object",
10
+ properties: {
11
+ value: { type: "observe", value: { type: "number" } },
12
+ tracked: { type: "observe", value: { type: "number" } },
13
+ selectDouble: { type: "function", signature: { parameters: [{ type: "number" }], returns: { type: "observe", value: { type: "number" } } } },
14
+ add: { type: "function", signature: { parameters: [{ type: "number" }, { type: "number" }], returns: { type: "promise", value: { type: "number" } } } },
15
+ fail: { type: "function", signature: { parameters: [{ type: "string" }], returns: { type: "promise", value: { type: "number" } } } },
16
+ countUp: { type: "function", signature: { parameters: [{ type: "number" }], returns: { type: "generator", value: { type: "number" } } } },
17
+ explode: { type: "function", signature: { parameters: [{ type: "number" }], returns: { type: "generator", value: { type: "number" } } } },
18
+ bump: { type: "function" },
19
+ boom: { type: "function" },
20
+ },
21
+ required: ["value", "tracked", "selectDouble", "add", "fail", "countUp", "explode", "bump", "boom"],
22
+ additionalProperties: false,
23
+ };
24
+ })(DemoService || (DemoService = {}));
25
+ function makeDemo(seed) {
26
+ const [value, setValue] = Observe.createState(seed);
27
+ let current = seed;
28
+ let activeObservers = 0;
29
+ const stats = { countUpFinally: 0, explodeFinally: 0, get activeObservers() { return activeObservers; } };
30
+ // A hand-written observe so we can prove the host unsubscribes on unsubscribe/close.
31
+ const tracked = (notify) => {
32
+ activeObservers++;
33
+ notify(seed);
34
+ return () => { activeObservers--; };
35
+ };
36
+ const service = {
37
+ serviceName: `demo-${seed}`,
38
+ schema: Observe.fromConstant(DemoService.schema),
39
+ value,
40
+ tracked,
41
+ selectDouble: (n) => Observe.fromConstant(n * 2),
42
+ add: async (a, b) => a + b,
43
+ fail: async (message) => { throw new Error(message); },
44
+ countUp: async function* (to) {
45
+ try {
46
+ for (let i = 1; i <= to; i++)
47
+ yield i;
48
+ }
49
+ finally {
50
+ stats.countUpFinally++;
51
+ }
52
+ },
53
+ explode: async function* (to) {
54
+ try {
55
+ for (let i = 1; i <= to; i++)
56
+ yield i;
57
+ throw new Error("explode");
58
+ }
59
+ finally {
60
+ stats.explodeFinally++;
61
+ }
62
+ },
63
+ bump: () => { current += 1; setValue(current); },
64
+ boom: () => { throw new Error("boom"); },
65
+ };
66
+ return { service, stats };
67
+ }
68
+ const flush = async (times = 8) => {
69
+ for (let i = 0; i < times; i++)
70
+ await new Promise((r) => setTimeout(r, 0));
71
+ };
72
+ function setup(opts) {
73
+ const { a, b } = createRpcLoopbackTransport();
74
+ const demoA = makeDemo(10);
75
+ const demoB = makeDemo(20);
76
+ const ea = createRpcEndpoint(a, opts?.a);
77
+ const eb = createRpcEndpoint(b, opts?.b);
78
+ const unExposeA = ea.expose("A", demoA.service, DemoService.schema);
79
+ const unExposeB = eb.expose("B", demoB.service, DemoService.schema);
80
+ const aToB = ea.consume("B", DemoService.schema); // A consumes B's service
81
+ const bToA = eb.consume("A", DemoService.schema); // B consumes A's service
82
+ return { ea, eb, demoA, demoB, aToB, bToA, unExposeA, unExposeB };
83
+ }
84
+ describe("promise members (both directions)", () => {
85
+ it("resolves across the wire in both directions", async () => {
86
+ const { aToB, bToA } = setup();
87
+ expect(await aToB.add(2, 3)).toBe(5);
88
+ expect(await bToA.add(10, 1)).toBe(11);
89
+ });
90
+ it("propagates a rejection with reconstructed name/message", async () => {
91
+ const { aToB } = setup();
92
+ await expect(aToB.fail("kaboom")).rejects.toThrowError("kaboom");
93
+ });
94
+ it("keeps ids independent per originator (bidirectional, both id=1)", async () => {
95
+ const { aToB, bToA } = setup();
96
+ const [r1, r2] = await Promise.all([aToB.add(1, 2), bToA.add(3, 4)]);
97
+ expect(r1).toBe(3);
98
+ expect(r2).toBe(7);
99
+ });
100
+ });
101
+ describe("observe members (both directions)", () => {
102
+ it("streams the initial value asynchronously and reacts to a void mutation", async () => {
103
+ const { aToB, demoB } = setup();
104
+ const seen = [];
105
+ const un = aToB.value((v) => seen.push(v));
106
+ // First value is a round-trip → NOT synchronous (unlike a local Observe).
107
+ expect(seen).toEqual([]);
108
+ await flush();
109
+ expect(seen).toEqual([20]);
110
+ aToB.bump(); // void member, other direction of the same channel
111
+ await flush();
112
+ expect(seen).toEqual([20, 21]);
113
+ expect(demoB.stats.activeObservers).toBe(0); // value uses createState, tracked is separate
114
+ un();
115
+ });
116
+ it("fn:observe forwards args and streams the derived value", async () => {
117
+ const { bToA } = setup();
118
+ const seen = [];
119
+ const un = bToA.selectDouble(21)((v) => seen.push(v));
120
+ await flush();
121
+ expect(seen).toEqual([42]);
122
+ un();
123
+ });
124
+ it("drops an in-flight next after unsubscribe", async () => {
125
+ const { aToB } = setup();
126
+ const seen = [];
127
+ const un = aToB.value((v) => seen.push(v));
128
+ un(); // unsubscribe before the first (async) next can arrive
129
+ await flush();
130
+ expect(seen).toEqual([]);
131
+ });
132
+ it("releases the host subscription on unsubscribe", async () => {
133
+ const { aToB, demoB } = setup();
134
+ const un = aToB.tracked(() => undefined);
135
+ await flush();
136
+ expect(demoB.stats.activeObservers).toBe(1);
137
+ un();
138
+ await flush();
139
+ expect(demoB.stats.activeObservers).toBe(0);
140
+ });
141
+ });
142
+ describe("generator members (both directions)", () => {
143
+ it("streams pull-based values in both directions", async () => {
144
+ const { aToB, bToA } = setup();
145
+ const collect = async (gen) => {
146
+ const out = [];
147
+ for await (const n of gen)
148
+ out.push(n);
149
+ return out;
150
+ };
151
+ expect(await collect(aToB.countUp(3))).toEqual([1, 2, 3]);
152
+ expect(await collect(bToA.countUp(2))).toEqual([1, 2]);
153
+ });
154
+ it("propagates a generator throw to the consumer", async () => {
155
+ const { aToB } = setup();
156
+ const gen = aToB.explode(2);
157
+ expect((await gen.next()).value).toBe(1);
158
+ expect((await gen.next()).value).toBe(2);
159
+ await expect(gen.next()).rejects.toThrowError("explode");
160
+ });
161
+ it("runs host finally on early return / dispose", async () => {
162
+ const { aToB, demoB } = setup();
163
+ const gen = aToB.countUp(100);
164
+ expect((await gen.next()).value).toBe(1);
165
+ await gen.return(undefined);
166
+ await flush();
167
+ expect(demoB.stats.countUpFinally).toBe(1);
168
+ expect((await gen.next()).done).toBe(true);
169
+ });
170
+ });
171
+ describe("void members", () => {
172
+ it("routes a host-handler throw to onError (no wire reply)", async () => {
173
+ const onError = vi.fn();
174
+ const { aToB } = setup({ b: { onError } });
175
+ aToB.boom();
176
+ await flush();
177
+ expect(onError).toHaveBeenCalledOnce();
178
+ expect(onError.mock.calls[0][0].message).toBe("boom");
179
+ });
180
+ });
181
+ describe("schema discovery", () => {
182
+ it("consumes with a runtime-fetched schema (after expose)", async () => {
183
+ const { eb } = setup();
184
+ const svc = (await eb.consume("A"));
185
+ expect(await svc.add(4, 5)).toBe(9);
186
+ });
187
+ it("supports consume-before-expose ordering", async () => {
188
+ const { a, b } = createRpcLoopbackTransport();
189
+ const ea = createRpcEndpoint(a);
190
+ const eb = createRpcEndpoint(b);
191
+ const pending = eb.consume("late"); // not yet exposed
192
+ const demo = makeDemo(7);
193
+ ea.expose("late", demo.service, DemoService.schema);
194
+ const svc = (await pending);
195
+ expect(await svc.add(1, 1)).toBe(2);
196
+ });
197
+ it("republishes the schema on the projected service's observable slot", async () => {
198
+ const { aToB } = setup();
199
+ let seen;
200
+ aToB.schema?.((s) => { seen = s; });
201
+ expect(seen).toEqual(DemoService.schema);
202
+ });
203
+ });
204
+ describe("trust boundary", () => {
205
+ it("rejects a call denied by canInvoke", async () => {
206
+ const { aToB } = setup({ b: { canInvoke: (_svc, member) => member !== "add" } });
207
+ await expect(aToB.add(1, 2)).rejects.toThrowError(/not permitted/);
208
+ });
209
+ it("rejects a call with invalid Data arguments (never invokes the member)", async () => {
210
+ const { aToB, demoB } = setup();
211
+ const invoke = vi.spyOn(demoB.service, "add");
212
+ // Untyped path: send a string where the schema requires a number.
213
+ const untyped = aToB;
214
+ await expect(untyped.add("x", "y")).rejects.toThrowError(/invalid arguments/);
215
+ expect(invoke).not.toHaveBeenCalled();
216
+ });
217
+ });
218
+ describe("teardown", () => {
219
+ it("rejects a pending call when the endpoint closes mid-flight", async () => {
220
+ const { ea, aToB } = setup();
221
+ const pending = aToB.add(1, 2); // registered synchronously
222
+ ea.close(); // before any reply can arrive
223
+ await expect(pending).rejects.toThrowError(/closed/);
224
+ });
225
+ it("releases host subscriptions when the channel closes", async () => {
226
+ const { ea, aToB, demoB } = setup();
227
+ aToB.tracked(() => undefined);
228
+ await flush();
229
+ expect(demoB.stats.activeObservers).toBe(1);
230
+ ea.close();
231
+ await flush();
232
+ expect(demoB.stats.activeObservers).toBe(0);
233
+ });
234
+ it("runs host generator finally when the channel closes mid-stream", async () => {
235
+ const { ea, aToB, demoB } = setup();
236
+ const gen = aToB.countUp(100);
237
+ expect((await gen.next()).value).toBe(1);
238
+ ea.close();
239
+ await flush();
240
+ expect(demoB.stats.countUpFinally).toBe(1);
241
+ });
242
+ it("ends a consumed generator gracefully after close", async () => {
243
+ const { ea, aToB } = setup();
244
+ const gen = aToB.countUp(100);
245
+ expect((await gen.next()).value).toBe(1);
246
+ ea.close();
247
+ expect((await gen.next()).done).toBe(true);
248
+ });
249
+ });
250
+ //# sourceMappingURL=rpc.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.test.js","sourceRoot":"","sources":["../src/rpc.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { RpcMessage } from "./protocol.js";
2
+ /**
3
+ * Runtime-agnostic, bidirectional message channel carrying {@link RpcMessage}s.
4
+ *
5
+ * Mirrors the `@adobe/data-sync` `SyncTransport` shape (send / onMessage /
6
+ * onClose / close). RPC is symmetric, so `Send` and `Receive` default to the
7
+ * same `RpcMessage` union. Implementations are provided for a `MessagePort`
8
+ * (the primary iframe/worker transport), a `Window` (the initial port handoff),
9
+ * and an in-process loopback pair (tests / demos).
10
+ *
11
+ * The transport does not own serialization — callers pass structured objects and
12
+ * the underlying channel structured-clones them. Ordering of `send` calls is
13
+ * preserved and delivery is assumed reliable.
14
+ */
15
+ export interface RpcTransport<Send = RpcMessage, Receive = RpcMessage> {
16
+ /**
17
+ * Send a message to the remote end. `transfer` optionally lists
18
+ * `Transferable`s handed off zero-copy (e.g. an `ArrayBuffer`); transports
19
+ * over channels without transfer semantics ignore it.
20
+ */
21
+ readonly send: (msg: Send, transfer?: readonly Transferable[]) => void;
22
+ /** Register a listener for messages from the remote end. Returns an unsubscribe. */
23
+ readonly onMessage: (listener: (msg: Receive) => void) => () => void;
24
+ /**
25
+ * Register a listener that fires once when the channel closes — local
26
+ * `close()`, remote close, or drop. Returns an unsubscribe. Firing is
27
+ * idempotent (at most once).
28
+ */
29
+ readonly onClose: (listener: () => void) => () => void;
30
+ /** Tear down the channel. */
31
+ readonly close: () => void;
32
+ }
@@ -0,0 +1,3 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ export {};
3
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,uDAAuD"}
@@ -0,0 +1,13 @@
1
+ import type { RpcTransport } from "../transport.js";
2
+ /**
3
+ * A paired in-process loopback transport for tests and single-process demos.
4
+ * Messages sent on `a` are delivered asynchronously to `b`'s listeners and
5
+ * vice-versa. Each message is `structuredClone`d on `send`, exactly as a
6
+ * `MessagePort` would — so a non-cloneable payload throws here too, and no
7
+ * live references leak across the (simulated) boundary. Closing either side
8
+ * tears down the whole channel and fires every `onClose` listener once.
9
+ */
10
+ export declare function createRpcLoopbackTransport(): {
11
+ a: RpcTransport;
12
+ b: RpcTransport;
13
+ };
@@ -0,0 +1,102 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ /**
3
+ * One directed, buffered, asynchronous pipe. Delivery is scheduled on a
4
+ * microtask (never synchronous with `send`) to model a real `MessagePort`,
5
+ * where the first value of a subscription necessarily arrives after the
6
+ * subscribe call returns. Messages sent before a listener registers are
7
+ * buffered and flushed once one does. FIFO order is preserved.
8
+ */
9
+ function createDirectedPipe() {
10
+ const listeners = new Set();
11
+ const pending = [];
12
+ let flushScheduled = false;
13
+ let closed = false;
14
+ const drain = () => {
15
+ flushScheduled = false;
16
+ if (closed)
17
+ return;
18
+ while (pending.length > 0 && listeners.size > 0) {
19
+ const msg = pending.shift();
20
+ for (const l of listeners)
21
+ l(msg);
22
+ }
23
+ };
24
+ const schedule = () => {
25
+ if (flushScheduled || closed)
26
+ return;
27
+ flushScheduled = true;
28
+ queueMicrotask(drain);
29
+ };
30
+ return {
31
+ push(msg) {
32
+ if (closed)
33
+ return;
34
+ pending.push(msg);
35
+ schedule();
36
+ },
37
+ onMessage(listener) {
38
+ listeners.add(listener);
39
+ if (pending.length > 0)
40
+ schedule();
41
+ return () => listeners.delete(listener);
42
+ },
43
+ close() {
44
+ closed = true;
45
+ pending.length = 0;
46
+ listeners.clear();
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * A paired in-process loopback transport for tests and single-process demos.
52
+ * Messages sent on `a` are delivered asynchronously to `b`'s listeners and
53
+ * vice-versa. Each message is `structuredClone`d on `send`, exactly as a
54
+ * `MessagePort` would — so a non-cloneable payload throws here too, and no
55
+ * live references leak across the (simulated) boundary. Closing either side
56
+ * tears down the whole channel and fires every `onClose` listener once.
57
+ */
58
+ export function createRpcLoopbackTransport() {
59
+ const aToB = createDirectedPipe(); // a.send → b.onMessage
60
+ const bToA = createDirectedPipe(); // b.send → a.onMessage
61
+ let closed = false;
62
+ const closeA = new Set();
63
+ const closeB = new Set();
64
+ const doClose = () => {
65
+ if (closed)
66
+ return;
67
+ closed = true;
68
+ aToB.close();
69
+ bToA.close();
70
+ for (const l of closeA)
71
+ l();
72
+ for (const l of closeB)
73
+ l();
74
+ closeA.clear();
75
+ closeB.clear();
76
+ };
77
+ const makeSide = (out, inbound, closeListeners) => ({
78
+ send(msg) {
79
+ if (closed)
80
+ return;
81
+ // Clone on send to model the structured-clone boundary of a real port.
82
+ out.push(structuredClone(msg));
83
+ },
84
+ onMessage(listener) {
85
+ return inbound.onMessage(listener);
86
+ },
87
+ onClose(listener) {
88
+ if (closed) {
89
+ listener();
90
+ return () => undefined;
91
+ }
92
+ closeListeners.add(listener);
93
+ return () => closeListeners.delete(listener);
94
+ },
95
+ close: doClose,
96
+ });
97
+ return {
98
+ a: makeSide(aToB, bToA, closeA),
99
+ b: makeSide(bToA, aToB, closeB),
100
+ };
101
+ }
102
+ //# sourceMappingURL=loopback-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback-transport.js","sourceRoot":"","sources":["../../src/transports/loopback-transport.ts"],"names":[],"mappings":"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"}