@aurobore/bridge-js 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aurobore contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,36 @@
1
+ import { type BridgeError } from "@aurobore/core";
2
+ import type { BridgeTransport } from "./transport/types.js";
3
+ export interface InvokeOptions {
4
+ stream?: boolean;
5
+ timeoutMs?: number;
6
+ signal?: AbortSignal;
7
+ }
8
+ export interface StreamSubscription {
9
+ subscriptionId: string;
10
+ onData: (payload: unknown) => void;
11
+ onError: (error: BridgeError) => void;
12
+ onComplete: () => void;
13
+ stop: () => void;
14
+ }
15
+ export declare class Bridge {
16
+ private readonly transport;
17
+ private readonly pending;
18
+ private readonly streams;
19
+ private readonly eventHandlers;
20
+ private readonly transportUnsub;
21
+ constructor(transport: BridgeTransport);
22
+ /** Вызов нативного метода плагина → Promise. */
23
+ invoke(plugin: string, method: string, args?: unknown, options?: InvokeOptions): Promise<unknown>;
24
+ /** Подписка на событие (native→JS или JS→native echo). */
25
+ on(name: string, handler: (data: unknown) => void): () => void;
26
+ off(name: string, handler: (data: unknown) => void): void;
27
+ /** Одноразовая подписка на событие. */
28
+ once(name: string, handler: (data: unknown) => void): () => void;
29
+ /** Эмит события JS→native. */
30
+ emit(name: string, data?: unknown): void;
31
+ destroy(): void;
32
+ private invokeStream;
33
+ private handleInbound;
34
+ private dispatchEvent;
35
+ }
36
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAwBD,qBAAa,MAAM;IAML,OAAO,CAAC,QAAQ,CAAC,SAAS;IALtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmD;IACjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAa;gBAEf,SAAS,EAAE,eAAe;IAIvD,gDAAgD;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IA0CjG,0DAA0D;IAC1D,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI;IAU9D,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIzD,uCAAuC;IACvC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI;IAQhE,8BAA8B;IAC9B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAUxC,OAAO,IAAI,IAAI;IAUf,OAAO,CAAC,YAAY;IAoEpB,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,aAAa;CAStB"}
package/dist/bridge.js ADDED
@@ -0,0 +1,201 @@
1
+ import { BRIDGE_ERROR_CODES, createBridgeError, createCancel, isEventMessage, isResponseMessage, isStreamMessage, } from "@aurobore/core";
2
+ import { createInvoke } from "./messages.js";
3
+ const DEFAULT_TIMEOUT_MS = 30_000;
4
+ function assertJsonSerializable(value) {
5
+ try {
6
+ JSON.stringify(value);
7
+ }
8
+ catch {
9
+ throw createBridgeError(BRIDGE_ERROR_CODES.INVALID_ARGS, "Arguments are not JSON-serializable");
10
+ }
11
+ }
12
+ export class Bridge {
13
+ transport;
14
+ pending = new Map();
15
+ streams = new Map();
16
+ eventHandlers = new Map();
17
+ transportUnsub;
18
+ constructor(transport) {
19
+ this.transport = transport;
20
+ this.transportUnsub = transport.onReceive((msg) => this.handleInbound(msg));
21
+ }
22
+ /** Вызов нативного метода плагина → Promise. */
23
+ invoke(plugin, method, args, options) {
24
+ try {
25
+ assertJsonSerializable(args ?? null);
26
+ }
27
+ catch (error) {
28
+ return Promise.reject(error);
29
+ }
30
+ if (options?.stream) {
31
+ return this.invokeStream(plugin, method, args, options);
32
+ }
33
+ const msg = createInvoke(plugin, method, args, { stream: false });
34
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
35
+ return new Promise((resolve, reject) => {
36
+ const entry = { resolve, reject };
37
+ if (options?.signal) {
38
+ if (options.signal.aborted) {
39
+ reject(createBridgeError(BRIDGE_ERROR_CODES.CANCELLED, "Invoke cancelled"));
40
+ return;
41
+ }
42
+ const onAbort = () => {
43
+ this.pending.delete(msg.id);
44
+ if (entry.timeoutId)
45
+ clearTimeout(entry.timeoutId);
46
+ this.transport.send(createCancel(msg.id));
47
+ reject(createBridgeError(BRIDGE_ERROR_CODES.CANCELLED, "Invoke cancelled"));
48
+ };
49
+ entry.abortHandler = onAbort;
50
+ options.signal.addEventListener("abort", onAbort, { once: true });
51
+ }
52
+ entry.timeoutId = setTimeout(() => {
53
+ this.pending.delete(msg.id);
54
+ reject(createBridgeError(BRIDGE_ERROR_CODES.TIMEOUT, `Invoke timed out after ${timeoutMs}ms`));
55
+ }, timeoutMs);
56
+ this.pending.set(msg.id, entry);
57
+ this.transport.send(msg);
58
+ });
59
+ }
60
+ /** Подписка на событие (native→JS или JS→native echo). */
61
+ on(name, handler) {
62
+ if (!this.eventHandlers.has(name)) {
63
+ this.eventHandlers.set(name, new Set());
64
+ }
65
+ this.eventHandlers.get(name).add(handler);
66
+ return () => {
67
+ this.off(name, handler);
68
+ };
69
+ }
70
+ off(name, handler) {
71
+ this.eventHandlers.get(name)?.delete(handler);
72
+ }
73
+ /** Одноразовая подписка на событие. */
74
+ once(name, handler) {
75
+ const wrapped = (data) => {
76
+ this.off(name, wrapped);
77
+ handler(data);
78
+ };
79
+ return this.on(name, wrapped);
80
+ }
81
+ /** Эмит события JS→native. */
82
+ emit(name, data) {
83
+ try {
84
+ assertJsonSerializable(data ?? null);
85
+ }
86
+ catch (error) {
87
+ console.error("[aurobore-bridge] emit failed:", error);
88
+ return;
89
+ }
90
+ this.transport.send({ type: "event", name, ...(data === undefined ? {} : { data }) });
91
+ }
92
+ destroy() {
93
+ this.transportUnsub();
94
+ for (const [, entry] of this.pending) {
95
+ if (entry.timeoutId)
96
+ clearTimeout(entry.timeoutId);
97
+ }
98
+ this.pending.clear();
99
+ this.streams.clear();
100
+ this.eventHandlers.clear();
101
+ }
102
+ invokeStream(plugin, method, args, options) {
103
+ const msg = createInvoke(plugin, method, args, { stream: true });
104
+ const subscriptionId = msg.id;
105
+ const sub = {
106
+ subscriptionId,
107
+ onData: () => { },
108
+ onError: () => { },
109
+ onComplete: () => { },
110
+ stop: () => { },
111
+ };
112
+ this.streams.set(subscriptionId, {
113
+ onData: (payload) => sub.onData(payload),
114
+ onError: (error) => sub.onError(error),
115
+ onComplete: () => sub.onComplete(),
116
+ });
117
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
118
+ const timeoutId = setTimeout(() => {
119
+ if (this.streams.has(subscriptionId)) {
120
+ this.streams.delete(subscriptionId);
121
+ sub.onError(createBridgeError(BRIDGE_ERROR_CODES.TIMEOUT, `Stream timed out after ${timeoutMs}ms`));
122
+ }
123
+ }, timeoutMs);
124
+ const originalOnComplete = sub.onComplete;
125
+ sub.onComplete = () => {
126
+ clearTimeout(timeoutId);
127
+ originalOnComplete();
128
+ };
129
+ const cleanupStream = () => {
130
+ this.streams.delete(subscriptionId);
131
+ clearTimeout(timeoutId);
132
+ this.transport.send(createCancel(subscriptionId));
133
+ };
134
+ sub.stop = () => {
135
+ cleanupStream();
136
+ };
137
+ if (options?.signal) {
138
+ if (options.signal.aborted) {
139
+ cleanupStream();
140
+ return Promise.reject(createBridgeError(BRIDGE_ERROR_CODES.CANCELLED, "Invoke cancelled"));
141
+ }
142
+ options.signal.addEventListener("abort", () => {
143
+ cleanupStream();
144
+ sub.onError(createBridgeError(BRIDGE_ERROR_CODES.CANCELLED, "Invoke cancelled"));
145
+ }, { once: true });
146
+ }
147
+ this.transport.send(msg);
148
+ return Promise.resolve(sub);
149
+ }
150
+ handleInbound(msg) {
151
+ if (isResponseMessage(msg)) {
152
+ const entry = this.pending.get(msg.id);
153
+ if (!entry)
154
+ return;
155
+ this.pending.delete(msg.id);
156
+ if (entry.timeoutId)
157
+ clearTimeout(entry.timeoutId);
158
+ if (entry.abortHandler && msg.ok) {
159
+ // abort handler cleanup handled on abort
160
+ }
161
+ if (msg.ok) {
162
+ entry.resolve(msg.result);
163
+ }
164
+ else {
165
+ entry.reject(msg.error ?? createBridgeError("BRIDGE_UNKNOWN", "Unknown bridge error"));
166
+ }
167
+ return;
168
+ }
169
+ if (isEventMessage(msg)) {
170
+ this.dispatchEvent(msg.name, msg.data);
171
+ return;
172
+ }
173
+ if (isStreamMessage(msg)) {
174
+ const stream = this.streams.get(msg.subscriptionId);
175
+ if (!stream)
176
+ return;
177
+ if (msg.phase === "data") {
178
+ stream.onData(msg.payload);
179
+ }
180
+ else if (msg.phase === "error") {
181
+ stream.onError(msg.error ?? createBridgeError("BRIDGE_STREAM_ERROR", "Stream error"));
182
+ this.streams.delete(msg.subscriptionId);
183
+ }
184
+ else if (msg.phase === "complete") {
185
+ stream.onComplete();
186
+ this.streams.delete(msg.subscriptionId);
187
+ }
188
+ }
189
+ }
190
+ dispatchEvent(name, data) {
191
+ for (const handler of this.eventHandlers.get(name) ?? []) {
192
+ try {
193
+ handler(data);
194
+ }
195
+ catch (e) {
196
+ console.error("[aurobore-bridge] event handler error:", e);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.d.ts","sourceRoot":"","sources":["../src/bridge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { BRIDGE_ERROR_CODES } from "@aurobore/core";
3
+ import { Bridge } from "./bridge.js";
4
+ import { LoopbackNativeStub, LoopbackTransport } from "./transport/loopback.js";
5
+ import { resetCallIdCounter } from "./messages.js";
6
+ describe("Bridge (loopback)", () => {
7
+ function setup() {
8
+ resetCallIdCounter();
9
+ const [jsSide, nativeSide] = LoopbackTransport.pair();
10
+ const bridge = new Bridge(jsSide);
11
+ const native = new LoopbackNativeStub(nativeSide);
12
+ return { bridge, native };
13
+ }
14
+ it("invoke ping → Promise resolve", async () => {
15
+ const { bridge } = setup();
16
+ const result = await bridge.invoke("Echo", "ping");
17
+ expect(result).toEqual({ pong: true });
18
+ });
19
+ it("invoke echo возвращает args", async () => {
20
+ const { bridge } = setup();
21
+ const result = await bridge.invoke("Echo", "echo", { hello: "world" });
22
+ expect(result).toEqual({ hello: "world" });
23
+ });
24
+ it("invoke fail → reject со structured error", async () => {
25
+ const { bridge } = setup();
26
+ await expect(bridge.invoke("Echo", "fail")).rejects.toEqual({
27
+ code: "ECHO_TEST_ERROR",
28
+ message: "demo error",
29
+ data: { code: 42 },
30
+ });
31
+ });
32
+ it("корреляция: два параллельных invoke не перепутываются", async () => {
33
+ const { bridge } = setup();
34
+ const [a, b] = await Promise.all([
35
+ bridge.invoke("Echo", "echo", { id: "a" }),
36
+ bridge.invoke("Echo", "echo", { id: "b" }),
37
+ ]);
38
+ expect(a).toEqual({ id: "a" });
39
+ expect(b).toEqual({ id: "b" });
40
+ });
41
+ it("bidirectional events: emit app:demo → on app:echo", async () => {
42
+ const { bridge } = setup();
43
+ const received = vi.fn();
44
+ bridge.on("app:echo", received);
45
+ bridge.emit("app:demo", { hello: "native" });
46
+ await new Promise((r) => setTimeout(r, 0));
47
+ expect(received).toHaveBeenCalledWith({ hello: "native" });
48
+ });
49
+ it("stream watchTicks: data → complete", async () => {
50
+ const { bridge } = setup();
51
+ const ticks = [];
52
+ const sub = (await bridge.invoke("Echo", "watchTicks", {}, { stream: true }));
53
+ sub.onData = (payload) => {
54
+ ticks.push(payload.tick);
55
+ };
56
+ await new Promise((resolve) => {
57
+ sub.onComplete = resolve;
58
+ });
59
+ expect(ticks).toEqual([1, 2, 3, 4, 5]);
60
+ });
61
+ it("timeout reject", async () => {
62
+ resetCallIdCounter();
63
+ const [jsSide] = LoopbackTransport.pair();
64
+ const bridge = new Bridge(jsSide);
65
+ await expect(bridge.invoke("Echo", "ping", undefined, { timeoutMs: 50 })).rejects.toMatchObject({
66
+ code: BRIDGE_ERROR_CODES.TIMEOUT,
67
+ });
68
+ });
69
+ it("once вызывает handler один раз", async () => {
70
+ const { bridge } = setup();
71
+ const received = vi.fn();
72
+ bridge.once("app:echo", received);
73
+ bridge.emit("app:demo", { n: 1 });
74
+ bridge.emit("app:demo", { n: 2 });
75
+ await new Promise((r) => setTimeout(r, 0));
76
+ expect(received).toHaveBeenCalledTimes(1);
77
+ expect(received).toHaveBeenCalledWith({ n: 1 });
78
+ });
79
+ it("invalid JSON args reject до отправки", async () => {
80
+ const { bridge } = setup();
81
+ const circular = {};
82
+ circular.self = circular;
83
+ await expect(bridge.invoke("Echo", "echo", circular)).rejects.toMatchObject({
84
+ code: BRIDGE_ERROR_CODES.INVALID_ARGS,
85
+ });
86
+ });
87
+ it("AbortSignal отменяет stream на native", async () => {
88
+ const { bridge } = setup();
89
+ const controller = new AbortController();
90
+ const ticks = [];
91
+ const sub = (await bridge.invoke("Echo", "watchTicks", {}, {
92
+ stream: true,
93
+ signal: controller.signal,
94
+ }));
95
+ await new Promise((resolve) => {
96
+ sub.onData = (payload) => {
97
+ ticks.push(payload.tick);
98
+ if (ticks.length === 2)
99
+ controller.abort();
100
+ };
101
+ sub.onError = () => resolve();
102
+ });
103
+ expect(ticks.length).toBeLessThan(5);
104
+ });
105
+ });
106
+ //# sourceMappingURL=bridge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.js","sourceRoot":"","sources":["../src/bridge.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * IIFE-бандл для runtime/container: window.Aurobore = { invoke, on, emit, off }.
3
+ */
4
+ import { Bridge } from "./bridge.js";
5
+ declare global {
6
+ interface Window {
7
+ Aurobore: {
8
+ invoke: Bridge["invoke"];
9
+ on: Bridge["on"];
10
+ off: Bridge["off"];
11
+ emit: Bridge["emit"];
12
+ };
13
+ }
14
+ }
15
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAKrC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,QAAQ,EAAE;YACR,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YACzB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACjB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;SACtB,CAAC;KACH;CACF"}
package/dist/bundle.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * IIFE-бандл для runtime/container: window.Aurobore = { invoke, on, emit, off }.
3
+ */
4
+ import { Bridge } from "./bridge.js";
5
+ import { WebViewTransport } from "./transport/webview.js";
6
+ const bridge = new Bridge(new WebViewTransport());
7
+ window.Aurobore = {
8
+ invoke: (plugin, method, args, options) => bridge.invoke(plugin, method, args, options),
9
+ on: (name, handler) => bridge.on(name, handler),
10
+ off: (name, handler) => bridge.off(name, handler),
11
+ emit: (name, data) => bridge.emit(name, data),
12
+ };
13
+ console.log("[aurobore-bridge] M2 bridge initialized");
14
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;AAalD,MAAM,CAAC,QAAQ,GAAG;IAChB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IACvF,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;IAC/C,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;IACjD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;CAC9C,CAAC;AAEF,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @aurobore/bridge-js — низкоуровневая JS-сторона моста (M2).
3
+ */
4
+ export { BRIDGE_PROTOCOL_VERSION, createInvoke, nextCallId, resetCallIdCounter } from "./messages.js";
5
+ export { Bridge, type InvokeOptions, type StreamSubscription } from "./bridge.js";
6
+ export type { BridgeTransport } from "./transport/types.js";
7
+ export { LoopbackNativeStub, LoopbackTransport } from "./transport/loopback.js";
8
+ export { WebViewTransport } from "./transport/webview.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAClF,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @aurobore/bridge-js — низкоуровневая JS-сторона моста (M2).
3
+ */
4
+ export { BRIDGE_PROTOCOL_VERSION, createInvoke, nextCallId, resetCallIdCounter } from "./messages.js";
5
+ export { Bridge } from "./bridge.js";
6
+ export { LoopbackNativeStub, LoopbackTransport } from "./transport/loopback.js";
7
+ export { WebViewTransport } from "./transport/webview.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,MAAM,EAA+C,MAAM,aAAa,CAAC;AAElF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createInvoke, nextCallId } from "./messages.js";
3
+ describe("@aurobore/bridge-js messages", () => {
4
+ it("nextCallId выдаёт уникальные id", () => {
5
+ expect(nextCallId()).not.toBe(nextCallId());
6
+ });
7
+ it("createInvoke формирует корректное сообщение invoke", () => {
8
+ const msg = createInvoke("Device", "getInfo", { verbose: true });
9
+ expect(msg.type).toBe("invoke");
10
+ expect(msg.protocol).toBe(1);
11
+ expect(msg.plugin).toBe("Device");
12
+ expect(msg.method).toBe("getInfo");
13
+ expect(msg.args).toEqual({ verbose: true });
14
+ expect(msg.id).toMatch(/^c-\d+$/);
15
+ });
16
+ });
17
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzD,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Форма сообщений invoke и генератор корреляционных id.
3
+ */
4
+ import { BRIDGE_PROTOCOL_VERSION, type InvokeMessage } from "@aurobore/core";
5
+ export { BRIDGE_PROTOCOL_VERSION };
6
+ export type { InvokeMessage };
7
+ /** Возвращает уникальный корреляционный id вызова (см. docs/architecture/bridge.md §3). */
8
+ export declare function nextCallId(): string;
9
+ export declare function createInvoke(plugin: string, method: string, args?: unknown, meta?: {
10
+ stream?: boolean;
11
+ }): InvokeMessage;
12
+ /** Сброс счётчика id (только для тестов). */
13
+ export declare function resetCallIdCounter(): void;
14
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE7E,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B,2FAA2F;AAC3F,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,EACd,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,aAAa,CAUf;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Форма сообщений invoke и генератор корреляционных id.
3
+ */
4
+ import { BRIDGE_PROTOCOL_VERSION } from "@aurobore/core";
5
+ export { BRIDGE_PROTOCOL_VERSION };
6
+ let counter = 0;
7
+ /** Возвращает уникальный корреляционный id вызова (см. docs/architecture/bridge.md §3). */
8
+ export function nextCallId() {
9
+ counter += 1;
10
+ return `c-${counter}`;
11
+ }
12
+ export function createInvoke(plugin, method, args, meta) {
13
+ return {
14
+ type: "invoke",
15
+ protocol: BRIDGE_PROTOCOL_VERSION,
16
+ id: nextCallId(),
17
+ plugin,
18
+ method,
19
+ ...(args === undefined ? {} : { args }),
20
+ ...(meta === undefined ? {} : { meta }),
21
+ };
22
+ }
23
+ /** Сброс счётчика id (только для тестов). */
24
+ export function resetCallIdCounter() {
25
+ counter = 0;
26
+ }
27
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,uBAAuB,EAAsB,MAAM,gBAAgB,CAAC;AAE7E,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAInC,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,2FAA2F;AAC3F,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,CAAC;IACb,OAAO,KAAK,OAAO,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,MAAc,EACd,IAAc,EACd,IAA2B;IAE3B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,uBAAuB;QACjC,EAAE,EAAE,UAAU,EAAE;QAChB,MAAM;QACN,MAAM;QACN,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,kBAAkB;IAChC,OAAO,GAAG,CAAC,CAAC;AACd,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { BridgeInbound, BridgeMessage, BridgeOutbound } from "@aurobore/core";
2
+ import type { LoopbackTransportLike } from "./types.js";
3
+ type Handler = (msg: BridgeInbound) => void;
4
+ type RawHandler = (msg: BridgeMessage) => void;
5
+ /** In-memory транспорт для unit-тестов: попарное соединение JS↔JS. */
6
+ export declare class LoopbackTransport implements LoopbackTransportLike {
7
+ private handlers;
8
+ private rawHandlers;
9
+ peer: LoopbackTransport | null;
10
+ static pair(): [LoopbackTransport, LoopbackTransport];
11
+ send(message: BridgeOutbound): void;
12
+ sendRaw(message: BridgeMessage): void;
13
+ onReceive(handler: Handler): () => void;
14
+ onReceiveRaw(handler: RawHandler): () => void;
15
+ }
16
+ /** Симуляция native-стороны в loopback-тестах. */
17
+ export declare class LoopbackNativeStub {
18
+ private readonly transport;
19
+ private activeStreamId;
20
+ private streamTimeoutId;
21
+ constructor(transport: LoopbackTransport);
22
+ private reply;
23
+ private streamTicks;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=loopback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback.d.ts","sourceRoot":"","sources":["../../src/transport/loopback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;AAC5C,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;AAE/C,sEAAsE;AACtE,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,WAAW,CAAyB;IAC5C,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAEtC,MAAM,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAQrD,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAInC,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAYrC,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI;IAOvC,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,IAAI;CAM9C;AAED,kDAAkD;AAClD,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAHtC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAA8C;gBAExC,SAAS,EAAE,iBAAiB;IAwCzD,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,WAAW;CAyBpB"}
@@ -0,0 +1,131 @@
1
+ /** In-memory транспорт для unit-тестов: попарное соединение JS↔JS. */
2
+ export class LoopbackTransport {
3
+ handlers = new Set();
4
+ rawHandlers = new Set();
5
+ peer = null;
6
+ static pair() {
7
+ const a = new LoopbackTransport();
8
+ const b = new LoopbackTransport();
9
+ a.peer = b;
10
+ b.peer = a;
11
+ return [a, b];
12
+ }
13
+ send(message) {
14
+ this.sendRaw(message);
15
+ }
16
+ sendRaw(message) {
17
+ if (!this.peer)
18
+ return;
19
+ queueMicrotask(() => {
20
+ for (const handler of this.peer.handlers) {
21
+ handler(message);
22
+ }
23
+ for (const handler of this.peer.rawHandlers) {
24
+ handler(message);
25
+ }
26
+ });
27
+ }
28
+ onReceive(handler) {
29
+ this.handlers.add(handler);
30
+ return () => {
31
+ this.handlers.delete(handler);
32
+ };
33
+ }
34
+ onReceiveRaw(handler) {
35
+ this.rawHandlers.add(handler);
36
+ return () => {
37
+ this.rawHandlers.delete(handler);
38
+ };
39
+ }
40
+ }
41
+ /** Симуляция native-стороны в loopback-тестах. */
42
+ export class LoopbackNativeStub {
43
+ transport;
44
+ activeStreamId = null;
45
+ streamTimeoutId = null;
46
+ constructor(transport) {
47
+ this.transport = transport;
48
+ transport.onReceiveRaw((msg) => {
49
+ if (msg.type === "cancel") {
50
+ if (this.activeStreamId === msg.id && this.streamTimeoutId !== null) {
51
+ clearTimeout(this.streamTimeoutId);
52
+ this.streamTimeoutId = null;
53
+ this.activeStreamId = null;
54
+ }
55
+ return;
56
+ }
57
+ if (msg.type === "invoke") {
58
+ const { id, plugin, method, args } = msg;
59
+ if (plugin === "Echo" && method === "ping") {
60
+ this.reply(id, true, { pong: true });
61
+ }
62
+ else if (plugin === "Echo" && method === "echo") {
63
+ this.reply(id, true, args);
64
+ }
65
+ else if (plugin === "Echo" && method === "fail") {
66
+ this.reply(id, false, {
67
+ code: "ECHO_TEST_ERROR",
68
+ message: "demo error",
69
+ data: { code: 42 },
70
+ });
71
+ }
72
+ else if (plugin === "Echo" && method === "watchTicks") {
73
+ this.streamTicks(id);
74
+ }
75
+ else {
76
+ this.reply(id, false, {
77
+ code: "BRIDGE_METHOD_NOT_FOUND",
78
+ message: `Unknown method ${method}`,
79
+ });
80
+ }
81
+ }
82
+ else if (msg.type === "event" && msg.name === "app:demo") {
83
+ this.transport.sendRaw({
84
+ type: "event",
85
+ name: "app:echo",
86
+ data: msg.data,
87
+ });
88
+ }
89
+ });
90
+ }
91
+ reply(id, ok, payload) {
92
+ if (ok) {
93
+ this.transport.sendRaw({ type: "response", id, ok: true, result: payload });
94
+ }
95
+ else {
96
+ this.transport.sendRaw({
97
+ type: "response",
98
+ id,
99
+ ok: false,
100
+ error: payload,
101
+ });
102
+ }
103
+ }
104
+ streamTicks(subscriptionId) {
105
+ this.activeStreamId = subscriptionId;
106
+ let tick = 0;
107
+ const send = () => {
108
+ tick += 1;
109
+ if (tick <= 5) {
110
+ this.transport.sendRaw({
111
+ type: "stream",
112
+ subscriptionId,
113
+ phase: "data",
114
+ payload: { tick },
115
+ });
116
+ this.streamTimeoutId = setTimeout(send, 10);
117
+ }
118
+ else {
119
+ this.streamTimeoutId = null;
120
+ this.activeStreamId = null;
121
+ this.transport.sendRaw({
122
+ type: "stream",
123
+ subscriptionId,
124
+ phase: "complete",
125
+ });
126
+ }
127
+ };
128
+ send();
129
+ }
130
+ }
131
+ //# sourceMappingURL=loopback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback.js","sourceRoot":"","sources":["../../src/transport/loopback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { BridgeInbound, BridgeMessage, BridgeOutbound } from "@aurobore/core";
2
+ /** Тонкий шов транспорта моста (ADR-004). */
3
+ export interface BridgeTransport {
4
+ send(message: BridgeOutbound): void;
5
+ onReceive(handler: (msg: BridgeInbound) => void): () => void;
6
+ }
7
+ /** Loopback принимает сообщения в обе стороны (для тестов). */
8
+ export interface LoopbackTransportLike extends BridgeTransport {
9
+ sendRaw(message: BridgeMessage): void;
10
+ onReceiveRaw(handler: (msg: BridgeMessage) => void): () => void;
11
+ }
12
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEnF,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC9D;AAED,+DAA+D;AAC/D,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,YAAY,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { BridgeInbound, BridgeOutbound } from "@aurobore/core";
2
+ import type { BridgeTransport } from "./types.js";
3
+ declare global {
4
+ function sendAsyncMessage(name: string, data: unknown): void;
5
+ var __auroboreBridgeReceive: ((msg: BridgeInbound) => void) | undefined;
6
+ }
7
+ /** Production-транспорт через Aurora WebView async messages. */
8
+ export declare class WebViewTransport implements BridgeTransport {
9
+ private handlers;
10
+ constructor();
11
+ send(message: BridgeOutbound): void;
12
+ onReceive(handler: (msg: BridgeInbound) => void): () => void;
13
+ }
14
+ //# sourceMappingURL=webview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webview.d.ts","sourceRoot":"","sources":["../../src/transport/webview.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,CAAC,MAAM,CAAC;IACb,SAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7D,IAAI,uBAAuB,EAAE,CAAC,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzE;AAED,gEAAgE;AAChE,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAA2C;;IAU3D,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IASnC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI;CAM7D"}
@@ -0,0 +1,27 @@
1
+ import { BRIDGE_CHANNEL } from "@aurobore/core";
2
+ /** Production-транспорт через Aurora WebView async messages. */
3
+ export class WebViewTransport {
4
+ handlers = new Set();
5
+ constructor() {
6
+ globalThis.__auroboreBridgeReceive = (msg) => {
7
+ for (const handler of this.handlers) {
8
+ handler(msg);
9
+ }
10
+ };
11
+ }
12
+ send(message) {
13
+ if (typeof globalThis.sendAsyncMessage !== "function") {
14
+ console.warn("[aurobore-bridge] sendAsyncMessage unavailable");
15
+ return;
16
+ }
17
+ // Aurora WebView: nested objects may fail CefValue conversion — send JSON string.
18
+ globalThis.sendAsyncMessage(BRIDGE_CHANNEL, JSON.stringify(message));
19
+ }
20
+ onReceive(handler) {
21
+ this.handlers.add(handler);
22
+ return () => {
23
+ this.handlers.delete(handler);
24
+ };
25
+ }
26
+ }
27
+ //# sourceMappingURL=webview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webview.js","sourceRoot":"","sources":["../../src/transport/webview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAShD,gEAAgE;AAChE,MAAM,OAAO,gBAAgB;IACnB,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IAE3D;QACE,UAAU,CAAC,uBAAuB,GAAG,CAAC,GAAkB,EAAE,EAAE;YAC1D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAuB;QAC1B,IAAI,OAAO,UAAU,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,kFAAkF;QAClF,UAAU,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,SAAS,CAAC,OAAqC;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC;IACJ,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@aurobore/bridge-js",
3
+ "version": "0.0.0",
4
+ "description": "Низкоуровневая JS-сторона моста: корреляция, Promise, события, стримы, сериализация.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "dependencies": {
22
+ "@aurobore/core": "0.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "esbuild": "^0.24.2"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc -b && node scripts/bundle.mjs",
29
+ "clean": "tsc -b --clean"
30
+ }
31
+ }