@nominalso/vibe-bridge 0.5.0 → 0.7.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/AGENTS.md +13 -4
- package/README.md +45 -7
- package/dist/chunk-QAMP6I2C.js +405 -0
- package/dist/chunk-QAMP6I2C.js.map +1 -0
- package/dist/index.browser.cjs +1211 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.js +1172 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.cjs +198 -46
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +94 -3782
- package/dist/index.d.ts +94 -3782
- package/dist/index.js +176 -403
- package/dist/index.js.map +1 -0
- package/dist/index.server.cjs +448 -0
- package/dist/index.server.cjs.map +1 -0
- package/dist/index.server.d.cts +51 -0
- package/dist/index.server.d.ts +51 -0
- package/dist/index.server.js +84 -0
- package/dist/index.server.js.map +1 -0
- package/dist/version-Cufn3-b0.d.cts +3990 -0
- package/dist/version-Cufn3-b0.d.ts +3990 -0
- package/docs/getting-started.md +3 -1
- package/llms.txt +3 -1
- package/package.json +27 -30
package/dist/index.js
CHANGED
|
@@ -1,368 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} while (decoded !== prev);
|
|
14
|
-
if (decoded.split("/").some((segment) => segment === "..")) return null;
|
|
15
|
-
return normalized;
|
|
16
|
-
}
|
|
17
|
-
var PROTOCOL_ID = "nominal-vibe-bridge";
|
|
18
|
-
var PROTOCOL_VERSION = 2;
|
|
19
|
-
var BRIDGE_KINDS = ["request", "response", "push", "command", "progress"];
|
|
20
|
-
var CORRELATED_KINDS = ["request", "response", "progress"];
|
|
21
|
-
var BRIDGE_KINDS_SET = new Set(BRIDGE_KINDS);
|
|
22
|
-
var CORRELATED_KINDS_SET = new Set(CORRELATED_KINDS);
|
|
23
|
-
function isBridgeMessage(data) {
|
|
24
|
-
if (typeof data !== "object" || data === null) return false;
|
|
25
|
-
const d = data;
|
|
26
|
-
if (d.__protocol !== PROTOCOL_ID) return false;
|
|
27
|
-
if (d.__version !== PROTOCOL_VERSION) return false;
|
|
28
|
-
if (typeof d.kind !== "string" || !BRIDGE_KINDS_SET.has(d.kind)) return false;
|
|
29
|
-
if (typeof d.type !== "string") return false;
|
|
30
|
-
if (CORRELATED_KINDS_SET.has(d.kind) && typeof d.requestId !== "string") return false;
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
var BridgeError = class extends Error {
|
|
34
|
-
constructor(code, message) {
|
|
35
|
-
super(message);
|
|
36
|
-
this.code = code;
|
|
37
|
-
this.name = "BridgeError";
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
var HttpBridgeError = class extends BridgeError {
|
|
41
|
-
constructor(status, message) {
|
|
42
|
-
super("REQUEST_FAILED", message);
|
|
43
|
-
this.status = status;
|
|
44
|
-
this.name = "HttpBridgeError";
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
function isOriginPattern(entry) {
|
|
48
|
-
return entry.includes("*");
|
|
49
|
-
}
|
|
50
|
-
var patternCache = /* @__PURE__ */ new Map();
|
|
51
|
-
function patternToRegExp(pattern) {
|
|
52
|
-
const cached = patternCache.get(pattern);
|
|
53
|
-
if (cached) return cached;
|
|
54
|
-
const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
55
|
-
const body = escaped.replace(/\\\*/g, "[^./:@?#\\s]+");
|
|
56
|
-
const compiled = new RegExp(`^${body}$`);
|
|
57
|
-
patternCache.set(pattern, compiled);
|
|
58
|
-
return compiled;
|
|
59
|
-
}
|
|
60
|
-
function matchesOrigin(origin, entry) {
|
|
61
|
-
if (!isOriginPattern(entry)) return origin === entry;
|
|
62
|
-
return patternToRegExp(entry).test(origin);
|
|
63
|
-
}
|
|
64
|
-
function isOriginAllowed(origin, allowlist, { allowPatterns }) {
|
|
65
|
-
for (const entry of allowlist) {
|
|
66
|
-
if (isOriginPattern(entry)) {
|
|
67
|
-
if (allowPatterns && matchesOrigin(origin, entry)) return true;
|
|
68
|
-
} else if (origin === entry) {
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/VibeAppBridge.ts
|
|
76
|
-
import posthogDefault from "posthog-js";
|
|
77
|
-
|
|
78
|
-
// src/data-methods.ts
|
|
79
|
-
var BridgeDataMethods = class {
|
|
80
|
-
// ---------------------------------------------------------------------------
|
|
81
|
-
// Operations — Accounting: chart of accounts
|
|
82
|
-
//
|
|
83
|
-
// Each method is a typed wrapper over `request('<OP>', payload)`. The payload
|
|
84
|
-
// and return types come straight from the Nominal API (`RequestRegistry`).
|
|
85
|
-
// For any operation without a named method, call `request('<OP>', payload)`.
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
/**
|
|
88
|
-
* Fetch the flat chart of accounts for a subsidiary.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* const ctx = await bridge.connect()
|
|
93
|
-
* const accounts = await bridge.getChartOfAccounts({
|
|
94
|
-
* path: { subsidiary_id: ctx.subsidiaryId },
|
|
95
|
-
* })
|
|
96
|
-
* ```
|
|
97
|
-
*/
|
|
98
|
-
getChartOfAccounts(payload) {
|
|
99
|
-
return this.request("GET_CHART_OF_ACCOUNTS", payload);
|
|
100
|
-
}
|
|
101
|
-
/** Fetch the chart of accounts as a hierarchical tree for a subsidiary. */
|
|
102
|
-
getCoaTree(payload) {
|
|
103
|
-
return this.request("GET_COA_TREE", payload);
|
|
104
|
-
}
|
|
105
|
-
/** Fetch a simplified flat chart of accounts for a subsidiary. */
|
|
106
|
-
getCoaFlatSimple(payload) {
|
|
107
|
-
return this.request("GET_COA_FLAT_SIMPLE", payload);
|
|
108
|
-
}
|
|
109
|
-
/** Fetch the flat chart of accounts grouped by account group. */
|
|
110
|
-
getCoaGrouped(payload) {
|
|
111
|
-
return this.request("GET_COA_GROUPED", payload);
|
|
112
|
-
}
|
|
113
|
-
/** Fetch a single chart-of-accounts account by id within a subsidiary. */
|
|
114
|
-
getCoaAccount(payload) {
|
|
115
|
-
return this.request("GET_COA_ACCOUNT", payload);
|
|
116
|
-
}
|
|
117
|
-
/** List the currencies available to a subsidiary's chart of accounts. */
|
|
118
|
-
getSubsidiaryAvailableCurrencies(payload) {
|
|
119
|
-
return this.request("GET_SUBSIDIARY_AVAILABLE_CURRENCIES", payload);
|
|
120
|
-
}
|
|
121
|
-
/** Fetch accounts at the tenant level. */
|
|
122
|
-
getAccounts(payload) {
|
|
123
|
-
return this.request("GET_ACCOUNTS", payload);
|
|
124
|
-
}
|
|
125
|
-
/** Fetch a single account by id. */
|
|
126
|
-
getAccount(payload) {
|
|
127
|
-
return this.request("GET_ACCOUNT", payload);
|
|
128
|
-
}
|
|
129
|
-
// ---------------------------------------------------------------------------
|
|
130
|
-
// Operations — Accounting: exchange rates
|
|
131
|
-
// ---------------------------------------------------------------------------
|
|
132
|
-
/** Fetch currency conversion rates for a currency. */
|
|
133
|
-
getConversionRates(payload) {
|
|
134
|
-
return this.request("GET_CONVERSION_RATES", payload);
|
|
135
|
-
}
|
|
136
|
-
/** Fetch the effective consolidation exchange rate. */
|
|
137
|
-
getEffectiveExchangeRate(payload) {
|
|
138
|
-
return this.request("GET_EFFECTIVE_EXCHANGE_RATE", payload);
|
|
139
|
-
}
|
|
140
|
-
/** Fetch the exchange-rate period covering a given input date. */
|
|
141
|
-
getExchangeRateByDate(payload) {
|
|
142
|
-
return this.request("GET_EXCHANGE_RATE_BY_DATE", payload);
|
|
143
|
-
}
|
|
144
|
-
// ---------------------------------------------------------------------------
|
|
145
|
-
// Operations — Accounting: dimensions
|
|
146
|
-
// ---------------------------------------------------------------------------
|
|
147
|
-
/** List accounting dimensions. */
|
|
148
|
-
getDimensions(payload) {
|
|
149
|
-
return this.request("GET_DIMENSIONS", payload);
|
|
150
|
-
}
|
|
151
|
-
/** List values for accounting dimensions. */
|
|
152
|
-
getDimensionValues(payload) {
|
|
153
|
-
return this.request("GET_DIMENSION_VALUES", payload);
|
|
154
|
-
}
|
|
155
|
-
/** List dimension values in hierarchical form. */
|
|
156
|
-
getDimensionValuesHierarchical(payload) {
|
|
157
|
-
return this.request("GET_DIMENSION_VALUES_HIERARCHICAL", payload);
|
|
158
|
-
}
|
|
159
|
-
/** List account assignments for a dimension/account pair. */
|
|
160
|
-
getDimensionAccountAssignments(payload) {
|
|
161
|
-
return this.request("GET_DIMENSION_ACCOUNT_ASSIGNMENTS", payload);
|
|
162
|
-
}
|
|
163
|
-
// ---------------------------------------------------------------------------
|
|
164
|
-
// Operations — Accounting: journal entries
|
|
165
|
-
// ---------------------------------------------------------------------------
|
|
166
|
-
/**
|
|
167
|
-
* Fetch journal entries for a subsidiary, optionally filtered by date range.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const entries = await bridge.getJournalEntries({
|
|
172
|
-
* path: { subsidiary_id: ctx.subsidiaryId },
|
|
173
|
-
* query: { from_date: '2026-01-01', to_date: '2026-03-31' },
|
|
174
|
-
* })
|
|
175
|
-
* ```
|
|
176
|
-
*/
|
|
177
|
-
getJournalEntries(payload) {
|
|
178
|
-
return this.request("GET_JOURNAL_ENTRIES", payload);
|
|
179
|
-
}
|
|
180
|
-
/** Fetch journal entry lines for a subsidiary. */
|
|
181
|
-
getJournalLines(payload) {
|
|
182
|
-
return this.request("GET_JOURNAL_LINES", payload);
|
|
183
|
-
}
|
|
184
|
-
/** Fetch a single journal entry by id within a subsidiary. */
|
|
185
|
-
getJournalEntry(payload) {
|
|
186
|
-
return this.request("GET_JOURNAL_ENTRY", payload);
|
|
187
|
-
}
|
|
188
|
-
// ---------------------------------------------------------------------------
|
|
189
|
-
// Operations — Activity: period instances
|
|
190
|
-
// ---------------------------------------------------------------------------
|
|
191
|
-
/** List accounting period instances. */
|
|
192
|
-
getPeriods(payload) {
|
|
193
|
-
return this.request("GET_PERIODS", payload);
|
|
194
|
-
}
|
|
195
|
-
/** Fetch a single period instance by id. */
|
|
196
|
-
getPeriodInstance(payload) {
|
|
197
|
-
return this.request("GET_PERIOD_INSTANCE", payload);
|
|
198
|
-
}
|
|
199
|
-
/** Fetch a period instance by its display slug (e.g. `"mar-2026"`). */
|
|
200
|
-
getPeriodInstanceBySlug(payload) {
|
|
201
|
-
return this.request("GET_PERIOD_INSTANCE_BY_SLUG", payload);
|
|
202
|
-
}
|
|
203
|
-
/** Fetch the close-progress breakdown for a period (by slug). */
|
|
204
|
-
getPeriodProgressBreakdown(payload) {
|
|
205
|
-
return this.request("GET_PERIOD_PROGRESS_BREAKDOWN", payload);
|
|
206
|
-
}
|
|
207
|
-
// ---------------------------------------------------------------------------
|
|
208
|
-
// Operations — Activity: activity definitions
|
|
209
|
-
// ---------------------------------------------------------------------------
|
|
210
|
-
/** List activity definitions. */
|
|
211
|
-
getActivityDefinitions(payload) {
|
|
212
|
-
return this.request("GET_ACTIVITY_DEFINITIONS", payload);
|
|
213
|
-
}
|
|
214
|
-
/** Fetch a single activity definition by id. */
|
|
215
|
-
getActivityDefinition(payload) {
|
|
216
|
-
return this.request("GET_ACTIVITY_DEFINITION", payload);
|
|
217
|
-
}
|
|
218
|
-
// ---------------------------------------------------------------------------
|
|
219
|
-
// Operations — Activity: activity instances
|
|
220
|
-
// ---------------------------------------------------------------------------
|
|
221
|
-
/** List activity instances. */
|
|
222
|
-
getActivityInstances(payload) {
|
|
223
|
-
return this.request("GET_ACTIVITY_INSTANCES", payload);
|
|
224
|
-
}
|
|
225
|
-
/** Fetch a single activity instance by id. */
|
|
226
|
-
getActivityInstance(payload) {
|
|
227
|
-
return this.request("GET_ACTIVITY_INSTANCE", payload);
|
|
228
|
-
}
|
|
229
|
-
/** Fetch an activity instance for a given period + activity definition. */
|
|
230
|
-
getActivityInstanceByPeriod(payload) {
|
|
231
|
-
return this.request("GET_ACTIVITY_INSTANCE_BY_PERIOD", payload);
|
|
232
|
-
}
|
|
233
|
-
/** List task instances for an activity instance. */
|
|
234
|
-
getActivityInstanceTasks(payload) {
|
|
235
|
-
return this.request("GET_ACTIVITY_INSTANCE_TASKS", payload);
|
|
236
|
-
}
|
|
237
|
-
/** List task instances for an activity in a given period. */
|
|
238
|
-
getActivityPeriodTasks(payload) {
|
|
239
|
-
return this.request("GET_ACTIVITY_PERIOD_TASKS", payload);
|
|
240
|
-
}
|
|
241
|
-
// ---------------------------------------------------------------------------
|
|
242
|
-
// Operations — Activity: task definitions
|
|
243
|
-
// ---------------------------------------------------------------------------
|
|
244
|
-
/** List task definitions. */
|
|
245
|
-
getTaskDefinitions(payload) {
|
|
246
|
-
return this.request("GET_TASK_DEFINITIONS", payload);
|
|
247
|
-
}
|
|
248
|
-
/** Fetch a single task definition by id. */
|
|
249
|
-
getTaskDefinition(payload) {
|
|
250
|
-
return this.request("GET_TASK_DEFINITION", payload);
|
|
251
|
-
}
|
|
252
|
-
/** Create a task definition. */
|
|
253
|
-
createTaskDefinition(payload) {
|
|
254
|
-
return this.request("CREATE_TASK_DEFINITION", payload);
|
|
255
|
-
}
|
|
256
|
-
/** Update a task definition by id. */
|
|
257
|
-
updateTaskDefinition(payload) {
|
|
258
|
-
return this.request("UPDATE_TASK_DEFINITION", payload);
|
|
259
|
-
}
|
|
260
|
-
/** Query task definitions by filter. */
|
|
261
|
-
getTaskDefinitionsByFilter(payload) {
|
|
262
|
-
return this.request("GET_TASK_DEFINITIONS_BY_FILTER", payload);
|
|
263
|
-
}
|
|
264
|
-
// ---------------------------------------------------------------------------
|
|
265
|
-
// Operations — Activity: task instances
|
|
266
|
-
// ---------------------------------------------------------------------------
|
|
267
|
-
/** List task instances. */
|
|
268
|
-
getTaskInstances(payload) {
|
|
269
|
-
return this.request("GET_TASK_INSTANCES", payload);
|
|
270
|
-
}
|
|
271
|
-
/** Fetch a single task instance by id. */
|
|
272
|
-
getTaskInstance(payload) {
|
|
273
|
-
return this.request("GET_TASK_INSTANCE", payload);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Submit a Close-Management task output. This is the **only write path** back
|
|
277
|
-
* into Nominal — Vibe Apps never write Nominal data directly.
|
|
278
|
-
*
|
|
279
|
-
* @example
|
|
280
|
-
* ```ts
|
|
281
|
-
* // `body` carries the task-specific output shape.
|
|
282
|
-
* await bridge.postTaskOutput({
|
|
283
|
-
* path: { task_instance_id: 'task-1' },
|
|
284
|
-
* body: {},
|
|
285
|
-
* })
|
|
286
|
-
* ```
|
|
287
|
-
*/
|
|
288
|
-
postTaskOutput(payload) {
|
|
289
|
-
return this.request("POST_TASK_OUTPUT", payload);
|
|
290
|
-
}
|
|
291
|
-
/** Query task instances by filter. */
|
|
292
|
-
getTaskInstancesByFilter(payload) {
|
|
293
|
-
return this.request("GET_TASK_INSTANCES_BY_FILTER", payload);
|
|
294
|
-
}
|
|
295
|
-
// ---------------------------------------------------------------------------
|
|
296
|
-
// Operations — Audit trail
|
|
297
|
-
// ---------------------------------------------------------------------------
|
|
298
|
-
/** List audit-trail events. */
|
|
299
|
-
getAuditEvents(payload) {
|
|
300
|
-
return this.request("GET_AUDIT_EVENTS", payload);
|
|
301
|
-
}
|
|
302
|
-
/** List audit-trail events for a specific entity. */
|
|
303
|
-
getEntityAuditEvents(payload) {
|
|
304
|
-
return this.request("GET_ENTITY_AUDIT_EVENTS", payload);
|
|
305
|
-
}
|
|
306
|
-
// ---------------------------------------------------------------------------
|
|
307
|
-
// Operations — Period manager: fiscal calendars
|
|
308
|
-
// ---------------------------------------------------------------------------
|
|
309
|
-
/** List fiscal calendars for a subsidiary. */
|
|
310
|
-
getFiscalCalendars(payload) {
|
|
311
|
-
return this.request("GET_FISCAL_CALENDARS", payload);
|
|
312
|
-
}
|
|
313
|
-
/** Fetch a single fiscal calendar by id. */
|
|
314
|
-
getFiscalCalendar(payload) {
|
|
315
|
-
return this.request("GET_FISCAL_CALENDAR", payload);
|
|
316
|
-
}
|
|
317
|
-
// ---------------------------------------------------------------------------
|
|
318
|
-
// Operations — Tenancy
|
|
319
|
-
// ---------------------------------------------------------------------------
|
|
320
|
-
/** List subsidiaries for the tenant. */
|
|
321
|
-
getSubsidiaries(payload) {
|
|
322
|
-
return this.request("GET_SUBSIDIARIES", payload);
|
|
323
|
-
}
|
|
324
|
-
/** Fetch a single subsidiary by id. */
|
|
325
|
-
getSubsidiary(payload) {
|
|
326
|
-
return this.request("GET_SUBSIDIARY", payload);
|
|
327
|
-
}
|
|
328
|
-
/** List parent currencies for a subsidiary. */
|
|
329
|
-
getSubsidiaryParentCurrencies(payload) {
|
|
330
|
-
return this.request("GET_SUBSIDIARY_PARENT_CURRENCIES", payload);
|
|
331
|
-
}
|
|
332
|
-
/** List users for the tenant. */
|
|
333
|
-
getTenantUsers(payload) {
|
|
334
|
-
return this.request("GET_TENANT_USERS", payload);
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Uploads a file through the host. Converts the `File` to an `ArrayBuffer`
|
|
338
|
-
* before sending — sandboxed iframes cannot pass `File` handles across
|
|
339
|
-
* windows. Resolves once Nominal has stored the file.
|
|
340
|
-
*
|
|
341
|
-
* @example
|
|
342
|
-
* ```ts
|
|
343
|
-
* const input = document.querySelector<HTMLInputElement>('#file')!
|
|
344
|
-
* const file = input.files![0]
|
|
345
|
-
* const result = await bridge.upload(file, {
|
|
346
|
-
* entityType: 'JOURNAL_ENTRY',
|
|
347
|
-
* entityId: '123',
|
|
348
|
-
* onProgress: (p) => console.log(`${p.progress}%`),
|
|
349
|
-
* })
|
|
350
|
-
* // result.attachmentId, result.name
|
|
351
|
-
* ```
|
|
352
|
-
*/
|
|
353
|
-
async upload(file, options) {
|
|
354
|
-
const buffer = await file.arrayBuffer();
|
|
355
|
-
const payload = {
|
|
356
|
-
buffer,
|
|
357
|
-
fileName: file.name,
|
|
358
|
-
fileType: file.type,
|
|
359
|
-
entityType: options.entityType,
|
|
360
|
-
entityId: options.entityId
|
|
361
|
-
};
|
|
362
|
-
const onProgress = options.onProgress ? (p) => options.onProgress(p) : void 0;
|
|
363
|
-
return this.request("UPLOAD_FILE", payload, onProgress);
|
|
364
|
-
}
|
|
365
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
BRIDGE_VERSION,
|
|
3
|
+
BridgeDataMethods,
|
|
4
|
+
BridgeError,
|
|
5
|
+
HttpBridgeError,
|
|
6
|
+
PROTOCOL_ID,
|
|
7
|
+
PROTOCOL_VERSION,
|
|
8
|
+
isBridgeMessage,
|
|
9
|
+
isOriginAllowed,
|
|
10
|
+
isOriginPattern,
|
|
11
|
+
normalizeSubroute
|
|
12
|
+
} from "./chunk-QAMP6I2C.js";
|
|
366
13
|
|
|
367
14
|
// src/timeouts.ts
|
|
368
15
|
var CONNECT_TIMEOUT_MS = 1e4;
|
|
@@ -389,13 +36,23 @@ function resolveRequestTimeout(type, requestTimeout) {
|
|
|
389
36
|
|
|
390
37
|
// src/VibeAppBridge.ts
|
|
391
38
|
function resolvePosthog(mod) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return
|
|
39
|
+
const hasInit = (o) => typeof o?.init === "function";
|
|
40
|
+
const d1 = mod?.default;
|
|
41
|
+
if (hasInit(d1)) return d1;
|
|
42
|
+
const d2 = d1?.default;
|
|
43
|
+
if (hasInit(d2)) return d2;
|
|
44
|
+
if (hasInit(mod)) return mod;
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function serverEnvError(method) {
|
|
48
|
+
return new BridgeError(
|
|
49
|
+
"SERVER_ENVIRONMENT",
|
|
50
|
+
`VibeAppBridge.${method} was called outside a browser (no \`window\`). The bridge only runs in the browser \u2014 call it from a client component or effect, not during SSR, in a React Server Component, or in a Worker.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
function assertBrowser(method) {
|
|
54
|
+
if (typeof window === "undefined") throw serverEnvError(method);
|
|
397
55
|
}
|
|
398
|
-
var posthog = resolvePosthog(posthogDefault);
|
|
399
56
|
var PARENT_ORIGIN_OVERRIDE_KEY = "__NOM_VIBE_PARENT_ORIGIN__";
|
|
400
57
|
var PREVIEW_HOST_RE = /(?:^|\.)(?:vercel\.app|lovable\.app|lovable\.dev|lovableproject\.com)$|^(?:localhost|127\.0\.0\.1)$/;
|
|
401
58
|
function isPreviewSelfHost(hostname) {
|
|
@@ -455,9 +112,22 @@ function resolveOriginPolicy(configured) {
|
|
|
455
112
|
return { targetOrigin, isTrusted };
|
|
456
113
|
}
|
|
457
114
|
var VibeAppBridge = class extends BridgeDataMethods {
|
|
458
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Stores options only — **pure and side-effect-free**. No `window`,
|
|
117
|
+
* `document`, `history`, `postMessage`, `crypto`, or `posthog-js` access
|
|
118
|
+
* happens here, so constructing a bridge is safe during SSR / in a Server
|
|
119
|
+
* Component / in a Worker. Browser wiring is deferred to {@link connect} /
|
|
120
|
+
* {@link attach}.
|
|
121
|
+
*/
|
|
122
|
+
constructor(options = {}) {
|
|
459
123
|
super();
|
|
124
|
+
/** Concrete origin to `postMessage` to, or `null` until resolved at {@link attach}. */
|
|
125
|
+
this.targetOrigin = null;
|
|
126
|
+
/** Validates an inbound `event.origin`; rejects everything until {@link attach}. */
|
|
127
|
+
this.isTrustedOrigin = () => false;
|
|
460
128
|
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
129
|
+
/** Whether {@link attach} has installed the message listener + resolved origin. */
|
|
130
|
+
this.attached = false;
|
|
461
131
|
this.context = null;
|
|
462
132
|
/**
|
|
463
133
|
* Set once {@link initPostHog} has successfully called `posthog.init()`.
|
|
@@ -465,6 +135,16 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
465
135
|
* recording is actually live.
|
|
466
136
|
*/
|
|
467
137
|
this.posthogInitialized = false;
|
|
138
|
+
/** The lazily-imported `posthog-js` singleton, once recording is initialized. */
|
|
139
|
+
this.posthogInstance = null;
|
|
140
|
+
/**
|
|
141
|
+
* Set for the duration of an in-flight {@link initPostHog} (which is async — it
|
|
142
|
+
* awaits `import('posthog-js')`). Serializes initialization so two overlapping
|
|
143
|
+
* `POSTHOG_PUSH`es can't both call `posthog.init()`.
|
|
144
|
+
*/
|
|
145
|
+
this.posthogIniting = false;
|
|
146
|
+
/** So the "posthog-js not installed" warning is logged at most once. */
|
|
147
|
+
this.posthogUnavailableWarned = false;
|
|
468
148
|
this.connectPromise = null;
|
|
469
149
|
this.connectPollInterval = null;
|
|
470
150
|
this.connectTimeout = null;
|
|
@@ -505,8 +185,12 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
505
185
|
},
|
|
506
186
|
// Persistent (not nulled after connect): the host delivers PostHog once at
|
|
507
187
|
// connect via its own push, and initPostHog is idempotent, so this can run
|
|
508
|
-
// whenever the message arrives, independent of how connect() resolved.
|
|
509
|
-
|
|
188
|
+
// whenever the message arrives, independent of how connect() resolved. Fire
|
|
189
|
+
// and forget — initPostHog is async (lazy-imports posthog-js) and swallows
|
|
190
|
+
// its own errors.
|
|
191
|
+
POSTHOG_PUSH: (payload) => {
|
|
192
|
+
void this.initPostHog(payload);
|
|
193
|
+
},
|
|
510
194
|
// Persistent: the host pushes auth changes (logout, identity/tenant
|
|
511
195
|
// switch) at any time after connect.
|
|
512
196
|
AUTH_CHANGED: (payload) => this.authChangeCallback?.(payload),
|
|
@@ -536,42 +220,72 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
536
220
|
this.ui = {
|
|
537
221
|
/** Collapse or expand the host's side navigation. */
|
|
538
222
|
setSideNav: (payload) => {
|
|
223
|
+
assertBrowser("ui.setSideNav()");
|
|
539
224
|
this.sendCommand("SET_SIDE_NAV", payload);
|
|
540
225
|
},
|
|
541
226
|
/** Switch the host to a different subsidiary. */
|
|
542
227
|
switchSubsidiary: (subsidiaryId) => {
|
|
228
|
+
assertBrowser("ui.switchSubsidiary()");
|
|
543
229
|
this.sendCommand("SWITCH_SUBSIDIARY", { subsidiaryId });
|
|
544
230
|
}
|
|
545
231
|
};
|
|
546
|
-
|
|
547
|
-
this.
|
|
548
|
-
this.isTrustedOrigin = policy.isTrusted;
|
|
549
|
-
this.requestTimeout = requestTimeout;
|
|
232
|
+
this.parentOriginOption = options.parentOrigin;
|
|
233
|
+
this.requestTimeout = options.requestTimeout;
|
|
550
234
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
551
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
552
235
|
}
|
|
553
236
|
dispatchPush(msg) {
|
|
554
237
|
const handler = this.pushHandlers[msg.type];
|
|
555
238
|
handler(msg.payload);
|
|
556
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Installs the browser wiring: resolves the parent-origin policy and starts
|
|
242
|
+
* listening for host `postMessage`s. **Idempotent** and safe to call before
|
|
243
|
+
* {@link connect} if you want the bridge receiving pushes early; {@link
|
|
244
|
+
* connect} calls it for you, so most apps never call this directly.
|
|
245
|
+
*
|
|
246
|
+
* @throws `BridgeError` code `'SERVER_ENVIRONMENT'` if called where there is no
|
|
247
|
+
* `window`.
|
|
248
|
+
*/
|
|
249
|
+
attach() {
|
|
250
|
+
assertBrowser("attach()");
|
|
251
|
+
if (this.attached) return;
|
|
252
|
+
const policy = resolveOriginPolicy(this.parentOriginOption);
|
|
253
|
+
this.targetOrigin = policy.targetOrigin;
|
|
254
|
+
this.isTrustedOrigin = policy.isTrusted;
|
|
255
|
+
window.addEventListener("message", this.boundHandleMessage);
|
|
256
|
+
this.attached = true;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Lazily installs the browser wiring on first transport use. Keeps the
|
|
260
|
+
* constructor pure while ensuring that any method reaching the wire (a data
|
|
261
|
+
* `request`, a fire-and-forget command) works without an explicit prior
|
|
262
|
+
* `attach()`/`connect()` — attach stays idempotent, so `connect()` is
|
|
263
|
+
* unaffected.
|
|
264
|
+
*/
|
|
265
|
+
ensureAttached() {
|
|
266
|
+
if (!this.attached) this.attach();
|
|
267
|
+
}
|
|
557
268
|
/**
|
|
558
269
|
* Connects to the host and returns the tenant/user {@link ContextPayload}.
|
|
559
270
|
* **Call this once on app init and await it before any other method** — data
|
|
560
271
|
* methods, `upload()`, and subroute reporting all require an established
|
|
561
272
|
* connection. Concurrent calls return the same promise.
|
|
562
273
|
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
* `
|
|
274
|
+
* First {@link attach | attaches} the browser wiring (message listener +
|
|
275
|
+
* origin resolution), then sends a `CONNECT` handshake, re-sending every 500ms
|
|
276
|
+
* until the host replies by pushing the context (so it works even if the host
|
|
277
|
+
* mounts after the iframe loads). Context is only ever delivered by push.
|
|
278
|
+
* Rejects with `Bridge connect timed out` after 10 seconds if no context
|
|
279
|
+
* arrives (usually a `parentOrigin` mismatch or the host hasn't mounted).
|
|
568
280
|
*
|
|
569
281
|
* After connecting, if the context includes an initial subroute (e.g. from
|
|
570
282
|
* a deep link), the bridge navigates to it and starts auto-tracking
|
|
571
283
|
* internal navigation via the history API.
|
|
572
284
|
*
|
|
573
285
|
* @returns The tenant/user/subsidiary context for this app session.
|
|
574
|
-
* @throws
|
|
286
|
+
* @throws Rejects with `BridgeError` code `'SERVER_ENVIRONMENT'` if called
|
|
287
|
+
* where there is no `window`, `'PARENT_ORIGIN_UNRESOLVED'` if no embedding
|
|
288
|
+
* origin could be resolved, or `'TIMEOUT'` if no context arrives in 10s.
|
|
575
289
|
* @example
|
|
576
290
|
* ```ts
|
|
577
291
|
* const ctx = await bridge.connect()
|
|
@@ -579,8 +293,10 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
579
293
|
* ```
|
|
580
294
|
*/
|
|
581
295
|
connect() {
|
|
296
|
+
if (typeof window === "undefined") return Promise.reject(serverEnvError("connect()"));
|
|
582
297
|
if (this.context) return Promise.resolve(this.context);
|
|
583
298
|
if (this.connectPromise) return this.connectPromise;
|
|
299
|
+
this.attach();
|
|
584
300
|
if (this.targetOrigin === null) {
|
|
585
301
|
return Promise.reject(
|
|
586
302
|
new BridgeError(
|
|
@@ -614,7 +330,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
614
330
|
this.onContextReceived = null;
|
|
615
331
|
this.rejectConnect = null;
|
|
616
332
|
console.log(
|
|
617
|
-
`[vibe-bridge] Connected \u2014 bridge: ${
|
|
333
|
+
`[vibe-bridge] Connected \u2014 bridge: ${BRIDGE_VERSION}, host: ${ctx.hostVersion}, tenant: ${ctx.tenant}, user: ${ctx.user.displayName}`
|
|
618
334
|
);
|
|
619
335
|
const initialSubroute = ctx.subroute ? normalizeSubroute(ctx.subroute) : null;
|
|
620
336
|
if (initialSubroute && initialSubroute !== "/") {
|
|
@@ -631,7 +347,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
631
347
|
resolve(ctx);
|
|
632
348
|
};
|
|
633
349
|
const sendConnect = () => {
|
|
634
|
-
this.sendCommand("CONNECT", { bridgeVersion:
|
|
350
|
+
this.sendCommand("CONNECT", { bridgeVersion: BRIDGE_VERSION });
|
|
635
351
|
};
|
|
636
352
|
sendConnect();
|
|
637
353
|
this.connectPollInterval = setInterval(sendConnect, CONNECT_POLL_MS);
|
|
@@ -644,6 +360,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
644
360
|
* Use this for hash-based routers or non-standard navigation patterns.
|
|
645
361
|
*/
|
|
646
362
|
reportSubroute(subroute, options) {
|
|
363
|
+
assertBrowser("reportSubroute()");
|
|
647
364
|
const normalized = normalizeSubroute(subroute);
|
|
648
365
|
if (normalized === null) return;
|
|
649
366
|
this.lastReportedSubroute = normalized;
|
|
@@ -654,6 +371,8 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
654
371
|
* If no callback is registered, the SDK uses `history.pushState` + a
|
|
655
372
|
* `popstate` event, which works for most SPA routers automatically.
|
|
656
373
|
* Returns an unsubscribe function.
|
|
374
|
+
*
|
|
375
|
+
* Pure — only stores the callback, so it is safe to call before {@link connect}.
|
|
657
376
|
*/
|
|
658
377
|
onSubrouteRequest(callback) {
|
|
659
378
|
this.subrouteCallback = callback;
|
|
@@ -668,6 +387,8 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
668
387
|
* returns. Returns an unsubscribe function. Single subscriber: a second call
|
|
669
388
|
* replaces the first. Wire it **before {@link connect}** (the bridge warns at
|
|
670
389
|
* connect if it isn't).
|
|
390
|
+
*
|
|
391
|
+
* Pure — only stores the callback, so it is safe to call before {@link connect}.
|
|
671
392
|
*/
|
|
672
393
|
onContextChange(callback) {
|
|
673
394
|
this.contextChangeCallback = callback;
|
|
@@ -684,7 +405,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
684
405
|
*
|
|
685
406
|
* **Wire this before {@link connect}** — without it the embedded app won't
|
|
686
407
|
* sign out when the user logs out of Nominal (the bridge warns at connect if
|
|
687
|
-
* it isn't wired).
|
|
408
|
+
* it isn't wired). Pure — only stores the callback.
|
|
688
409
|
*/
|
|
689
410
|
onAuthChange(callback) {
|
|
690
411
|
this.authChangeCallback = callback;
|
|
@@ -730,6 +451,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
730
451
|
* ```
|
|
731
452
|
*/
|
|
732
453
|
navigate(path, action = "push") {
|
|
454
|
+
assertBrowser("navigate()");
|
|
733
455
|
this.sendCommand("NAVIGATE", { path, action });
|
|
734
456
|
}
|
|
735
457
|
/**
|
|
@@ -743,10 +465,12 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
743
465
|
* ```
|
|
744
466
|
*/
|
|
745
467
|
navigateTo(route, routeParams, action = "push") {
|
|
468
|
+
assertBrowser("navigateTo()");
|
|
746
469
|
this.sendCommand("NAVIGATE", { route, routeParams, action });
|
|
747
470
|
}
|
|
748
471
|
/** Refreshes the host's current route (re-fetches its server data). Fire-and-forget. */
|
|
749
472
|
refresh() {
|
|
473
|
+
assertBrowser("refresh()");
|
|
750
474
|
this.sendCommand("NAVIGATE", { action: "refresh" });
|
|
751
475
|
}
|
|
752
476
|
/**
|
|
@@ -768,8 +492,9 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
768
492
|
*
|
|
769
493
|
* **No-op until {@link connect} has resolved with PostHog enabled by the
|
|
770
494
|
* host** — if the host didn't send a `posthog` block (older host, or recording
|
|
771
|
-
* disabled for this env/app),
|
|
772
|
-
*
|
|
495
|
+
* disabled for this env/app), or `posthog-js` isn't installed (it is an
|
|
496
|
+
* optional dependency), nothing is sent. App authors don't import `posthog-js`
|
|
497
|
+
* themselves; this is the supported event surface.
|
|
773
498
|
*
|
|
774
499
|
* The event is sent **directly** from the iframe's own PostHog instance (only
|
|
775
500
|
* the session *recording* is forwarded to the parent), so it carries the
|
|
@@ -786,20 +511,33 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
786
511
|
* ```
|
|
787
512
|
*/
|
|
788
513
|
track(event, properties) {
|
|
789
|
-
|
|
790
|
-
|
|
514
|
+
assertBrowser("track()");
|
|
515
|
+
if (!this.posthogInitialized || !this.posthogInstance) return;
|
|
516
|
+
this.posthogInstance.capture(event, properties);
|
|
791
517
|
}
|
|
518
|
+
/**
|
|
519
|
+
* Tears down the bridge: stops the connect handshake, removes the message
|
|
520
|
+
* listener, restores patched history methods, and rejects any in-flight calls
|
|
521
|
+
* with a `'DESTROYED'` error. **Idempotent and safe on the server** — calling
|
|
522
|
+
* it when {@link connect}/{@link attach} never ran (or where there is no
|
|
523
|
+
* `window`) is a no-op, so it is safe as a React effect cleanup.
|
|
524
|
+
*/
|
|
792
525
|
destroy() {
|
|
793
526
|
this.teardownNavigationTracking();
|
|
794
527
|
this.rejectConnect?.(new BridgeError("DESTROYED", "Bridge destroyed"));
|
|
795
528
|
this.stopConnectPolling();
|
|
796
|
-
window
|
|
529
|
+
if (this.attached && typeof window !== "undefined") {
|
|
530
|
+
window.removeEventListener("message", this.boundHandleMessage);
|
|
531
|
+
}
|
|
532
|
+
this.attached = false;
|
|
797
533
|
for (const pending of this.pendingRequests.values()) {
|
|
798
534
|
pending.reject(new BridgeError("DESTROYED", "Bridge destroyed"));
|
|
799
535
|
}
|
|
800
536
|
this.pendingRequests.clear();
|
|
801
537
|
this.context = null;
|
|
802
538
|
this.posthogInitialized = false;
|
|
539
|
+
this.posthogInstance = null;
|
|
540
|
+
this.posthogIniting = false;
|
|
803
541
|
this.connectPromise = null;
|
|
804
542
|
this.onContextReceived = null;
|
|
805
543
|
this.rejectConnect = null;
|
|
@@ -818,23 +556,34 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
818
556
|
this.connectTimeout = null;
|
|
819
557
|
}
|
|
820
558
|
}
|
|
559
|
+
warnPosthogUnavailable() {
|
|
560
|
+
if (this.posthogUnavailableWarned) return;
|
|
561
|
+
this.posthogUnavailableWarned = true;
|
|
562
|
+
console.warn(
|
|
563
|
+
"[vibe-bridge] The host enabled session recording but `posthog-js` is not installed (it is an optional dependency). Recording and track() are disabled. Run `npm i posthog-js` to enable them."
|
|
564
|
+
);
|
|
565
|
+
}
|
|
821
566
|
/**
|
|
822
567
|
* Initializes PostHog session recording + analytics from the host-supplied
|
|
823
568
|
* config carried by a one-time `POSTHOG_PUSH`, **only when the host opted in**
|
|
824
569
|
* (`config.enabled`).
|
|
825
570
|
*
|
|
571
|
+
* `posthog-js` is an **optional dependency**, loaded lazily via `await
|
|
572
|
+
* import('posthog-js')` the first time recording is enabled — so it stays out
|
|
573
|
+
* of the import graph (and out of any server bundle) for apps that never
|
|
574
|
+
* record. If it isn't installed, this warns once and no-ops (never throws).
|
|
575
|
+
*
|
|
826
576
|
* The host is the single source of truth: when it sends no `POSTHOG_PUSH`
|
|
827
577
|
* (recording disabled for this env/app) or `enabled: false`, this does
|
|
828
|
-
* nothing
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
* in try/catch so a duplicate push or a PostHog failure is harmless.
|
|
578
|
+
* nothing. Cross-origin replay needs `recordCrossOriginIframes` on both sides
|
|
579
|
+
* so the parent receives the iframe's rrweb frames into one stitched recording,
|
|
580
|
+
* and `identify()` ties the iframe's recording + events to the same person as
|
|
581
|
+
* the host. Idempotent (the `posthogInitialized` guard) and wrapped in
|
|
582
|
+
* try/catch so a duplicate push or a PostHog failure is harmless.
|
|
834
583
|
*/
|
|
835
|
-
initPostHog(config) {
|
|
584
|
+
async initPostHog(config) {
|
|
836
585
|
if (!config.enabled) return;
|
|
837
|
-
if (this.posthogInitialized) return;
|
|
586
|
+
if (this.posthogInitialized || this.posthogIniting) return;
|
|
838
587
|
if (typeof window === "undefined") return;
|
|
839
588
|
if (!config.token || !config.apiHost || !config.distinctId) {
|
|
840
589
|
console.warn(
|
|
@@ -842,7 +591,20 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
842
591
|
);
|
|
843
592
|
return;
|
|
844
593
|
}
|
|
594
|
+
this.posthogIniting = true;
|
|
845
595
|
try {
|
|
596
|
+
let posthog;
|
|
597
|
+
try {
|
|
598
|
+
posthog = resolvePosthog(await import("posthog-js"));
|
|
599
|
+
} catch {
|
|
600
|
+
this.warnPosthogUnavailable();
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
if (!posthog) {
|
|
604
|
+
this.warnPosthogUnavailable();
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (!this.attached) return;
|
|
846
608
|
posthog.init(config.token, {
|
|
847
609
|
api_host: config.apiHost,
|
|
848
610
|
// absolute ingestion host, NOT a relative /ingest proxy
|
|
@@ -865,16 +627,19 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
865
627
|
}
|
|
866
628
|
});
|
|
867
629
|
posthog.identify(config.distinctId);
|
|
630
|
+
this.posthogInstance = posthog;
|
|
868
631
|
this.posthogInitialized = true;
|
|
869
632
|
console.log("[vibe-bridge] PostHog session recording initialized");
|
|
870
633
|
} catch (err) {
|
|
871
634
|
console.warn("[vibe-bridge] PostHog init failed \u2014 continuing without recording.", err);
|
|
635
|
+
} finally {
|
|
636
|
+
this.posthogIniting = false;
|
|
872
637
|
}
|
|
873
638
|
}
|
|
874
639
|
/**
|
|
875
640
|
* Monkey-patches `history.pushState` and `history.replaceState` to
|
|
876
641
|
* auto-detect SPA navigation and report it to the host. Called after
|
|
877
|
-
* connect() resolves.
|
|
642
|
+
* connect() resolves (so `window`/`history` are guaranteed present).
|
|
878
643
|
*/
|
|
879
644
|
setupNavigationTracking() {
|
|
880
645
|
if (this.origPushState) return;
|
|
@@ -925,6 +690,7 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
925
690
|
this.sendCommand("REPORT_SUBROUTE", { subroute, replace });
|
|
926
691
|
}
|
|
927
692
|
sendCommand(type, payload) {
|
|
693
|
+
this.ensureAttached();
|
|
928
694
|
this.postToParent({
|
|
929
695
|
__protocol: PROTOCOL_ID,
|
|
930
696
|
__version: PROTOCOL_VERSION,
|
|
@@ -940,12 +706,18 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
940
706
|
* `onProgress` callback. `type` autocompletes to every operation name and
|
|
941
707
|
* narrows `payload`/return to that operation's types.
|
|
942
708
|
*
|
|
709
|
+
* @throws Rejects with `BridgeError` code `'SERVER_ENVIRONMENT'` if called
|
|
710
|
+
* where there is no `window`.
|
|
943
711
|
* @example
|
|
944
712
|
* ```ts
|
|
945
713
|
* const accounts = await bridge.request('GET_ACCOUNTS', { query: { account_ids: ['acc-1'] } })
|
|
946
714
|
* ```
|
|
947
715
|
*/
|
|
948
716
|
request(type, payload, onProgress) {
|
|
717
|
+
if (typeof window === "undefined") {
|
|
718
|
+
return Promise.reject(serverEnvError(`request(${String(type)})`));
|
|
719
|
+
}
|
|
720
|
+
this.ensureAttached();
|
|
949
721
|
return new Promise((resolve, reject) => {
|
|
950
722
|
const requestId = crypto.randomUUID();
|
|
951
723
|
const timer = setTimeout(
|
|
@@ -1011,8 +783,9 @@ var VibeAppBridge = class extends BridgeDataMethods {
|
|
|
1011
783
|
}
|
|
1012
784
|
};
|
|
1013
785
|
export {
|
|
1014
|
-
|
|
786
|
+
BRIDGE_VERSION,
|
|
1015
787
|
BridgeError,
|
|
1016
788
|
HttpBridgeError,
|
|
1017
789
|
VibeAppBridge
|
|
1018
790
|
};
|
|
791
|
+
//# sourceMappingURL=index.js.map
|