@shadowob/sdk 1.1.7 → 1.1.9

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,192 @@
1
+ import {
2
+ getShadowServerAppChannelMessageDeliveries,
3
+ getShadowServerAppChannelMessageErrors,
4
+ getShadowServerAppInboxDeliveries,
5
+ getShadowServerAppInboxErrors,
6
+ unwrapShadowServerAppCommandPayload
7
+ } from "./chunk-OMTGSMTQ.js";
8
+
9
+ // src/bridge.ts
10
+ var ShadowBridge = class _ShadowBridge {
11
+ static commandRequestType = "shadow.app.command.request";
12
+ static commandResponseType = "shadow.app.command.response";
13
+ static inboxesRequestType = "shadow.app.inboxes.request";
14
+ static inboxesResponseType = "shadow.app.inboxes.response";
15
+ static enqueueInboxTaskRequestType = "shadow.app.inbox.enqueue.request";
16
+ static enqueueInboxTaskResponseType = "shadow.app.inbox.enqueue.response";
17
+ static openBuddyCreatorRequestType = "shadow.app.buddy.create.request";
18
+ static openBuddyCreatorResponseType = "shadow.app.buddy.create.response";
19
+ static inboxDeliveries(payload) {
20
+ return getShadowServerAppInboxDeliveries(payload);
21
+ }
22
+ static inboxErrors(payload) {
23
+ return getShadowServerAppInboxErrors(payload);
24
+ }
25
+ static channelMessageDeliveries(payload) {
26
+ return getShadowServerAppChannelMessageDeliveries(payload);
27
+ }
28
+ static channelMessageErrors(payload) {
29
+ return getShadowServerAppChannelMessageErrors(payload);
30
+ }
31
+ static unwrapCommandPayload(payload) {
32
+ return unwrapShadowServerAppCommandPayload(payload);
33
+ }
34
+ appKey;
35
+ targetOrigin;
36
+ timeoutMs;
37
+ win;
38
+ hasLaunchContext;
39
+ pending = /* @__PURE__ */ new Map();
40
+ onMessage = (event) => {
41
+ let data = event.data;
42
+ if (typeof data === "string") {
43
+ try {
44
+ data = JSON.parse(data || "{}");
45
+ } catch {
46
+ return;
47
+ }
48
+ }
49
+ if (!data || typeof data !== "object") return;
50
+ const record = data;
51
+ if (typeof record.requestId !== "string" || typeof record.type !== "string") return;
52
+ const entry = this.pending.get(record.requestId);
53
+ if (!entry || record.type !== entry.responseType) return;
54
+ this.pending.delete(record.requestId);
55
+ if (record.ok) entry.resolve(record.result);
56
+ else
57
+ entry.reject(
58
+ new Error(typeof record.error === "string" ? record.error : "Bridge request failed")
59
+ );
60
+ };
61
+ constructor(options) {
62
+ this.appKey = options.appKey;
63
+ this.targetOrigin = options.targetOrigin ?? "*";
64
+ this.timeoutMs = options.timeoutMs ?? 6e4;
65
+ this.win = options.windowRef ?? (typeof window === "undefined" ? null : window);
66
+ this.hasLaunchContext = this.resolveLaunchContext();
67
+ this.win?.addEventListener("message", this.onMessage);
68
+ }
69
+ dispose() {
70
+ this.win?.removeEventListener("message", this.onMessage);
71
+ for (const entry of this.pending.values()) {
72
+ entry.reject(new Error("ShadowBridge disposed"));
73
+ }
74
+ this.pending.clear();
75
+ }
76
+ isAvailable() {
77
+ if (!this.win) return false;
78
+ return this.hasLaunchContext && (this.win.parent !== this.win || !!this.win.ReactNativeWebView);
79
+ }
80
+ command(commandName, input, options = {}) {
81
+ return this.request(
82
+ _ShadowBridge.commandRequestType,
83
+ _ShadowBridge.commandResponseType,
84
+ {
85
+ commandName,
86
+ input,
87
+ ...options.channelId ? { channelId: options.channelId } : {},
88
+ ...options.task ? { task: options.task } : {}
89
+ },
90
+ options.timeoutMs
91
+ ).then(
92
+ (payload) => unwrapShadowServerAppCommandPayload(payload)
93
+ );
94
+ }
95
+ inboxes(options = {}) {
96
+ return this.request(
97
+ _ShadowBridge.inboxesRequestType,
98
+ _ShadowBridge.inboxesResponseType,
99
+ {},
100
+ options.timeoutMs ?? 15e3
101
+ );
102
+ }
103
+ enqueueInboxTask(input, options = {}) {
104
+ return this.request(
105
+ _ShadowBridge.enqueueInboxTaskRequestType,
106
+ _ShadowBridge.enqueueInboxTaskResponseType,
107
+ input,
108
+ options.timeoutMs
109
+ );
110
+ }
111
+ openBuddyCreator(input = {}, options = {}) {
112
+ return this.request(
113
+ _ShadowBridge.openBuddyCreatorRequestType,
114
+ _ShadowBridge.openBuddyCreatorResponseType,
115
+ input,
116
+ options.timeoutMs ?? 10 * 60 * 1e3
117
+ );
118
+ }
119
+ unwrapCommandPayload(payload) {
120
+ return unwrapShadowServerAppCommandPayload(payload);
121
+ }
122
+ inboxDeliveries(payload) {
123
+ return getShadowServerAppInboxDeliveries(payload);
124
+ }
125
+ inboxErrors(payload) {
126
+ return getShadowServerAppInboxErrors(payload);
127
+ }
128
+ channelMessageDeliveries(payload) {
129
+ return getShadowServerAppChannelMessageDeliveries(payload);
130
+ }
131
+ channelMessageErrors(payload) {
132
+ return getShadowServerAppChannelMessageErrors(payload);
133
+ }
134
+ request(requestType, responseType, payload, timeoutMs = this.timeoutMs) {
135
+ if (!this.isAvailable()) {
136
+ return Promise.reject(
137
+ new Error("ShadowBridge is not available outside a Shadow launch frame")
138
+ );
139
+ }
140
+ const requestId = `req_${Math.random().toString(36).slice(2)}`;
141
+ this.postMessage({
142
+ type: requestType,
143
+ requestId,
144
+ appKey: this.appKey,
145
+ ...payload
146
+ });
147
+ return new Promise((resolve, reject) => {
148
+ this.pending.set(requestId, {
149
+ responseType,
150
+ resolve,
151
+ reject
152
+ });
153
+ this.win?.setTimeout(() => {
154
+ if (!this.pending.has(requestId)) return;
155
+ this.pending.delete(requestId);
156
+ reject(new Error("Bridge request timed out"));
157
+ }, timeoutMs);
158
+ });
159
+ }
160
+ postMessage(message) {
161
+ if (!this.win) return;
162
+ if (this.win.ReactNativeWebView) {
163
+ this.win.ReactNativeWebView.postMessage(JSON.stringify(message));
164
+ return;
165
+ }
166
+ this.win.parent.postMessage(message, this.targetOrigin);
167
+ }
168
+ resolveLaunchContext() {
169
+ if (!this.win) return false;
170
+ const storageKey = `shadow.bridge.launch:${this.appKey}`;
171
+ const memoryContexts = this.win.__shadowBridgeLaunchContexts ??= {};
172
+ const hasLaunchToken = new URLSearchParams(this.win.location.search).has("shadow_launch");
173
+ if (hasLaunchToken) {
174
+ memoryContexts[this.appKey] = true;
175
+ try {
176
+ this.win.sessionStorage?.setItem(storageKey, "1");
177
+ } catch {
178
+ }
179
+ return true;
180
+ }
181
+ if (memoryContexts[this.appKey]) return true;
182
+ try {
183
+ return this.win.sessionStorage?.getItem(storageKey) === "1";
184
+ } catch {
185
+ return false;
186
+ }
187
+ }
188
+ };
189
+
190
+ export {
191
+ ShadowBridge
192
+ };