@nominalso/vibe-host 0.0.1 → 0.2.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/README.md +75 -11
- package/dist/index.cjs +213 -52
- package/dist/index.d.cts +194 -12
- package/dist/index.d.ts +194 -12
- package/dist/index.js +211 -52
- package/package.json +1 -11
package/dist/index.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.0
|
|
2
|
+
var version = "0.2.0";
|
|
3
3
|
|
|
4
4
|
// ../protocol-types/dist/index.js
|
|
5
|
+
function normalizeSubroute(subroute) {
|
|
6
|
+
const normalized = subroute.startsWith("/") ? subroute : `/${subroute}`;
|
|
7
|
+
const path = normalized.split(/[?#]/)[0];
|
|
8
|
+
let decoded = path;
|
|
9
|
+
let prev;
|
|
10
|
+
do {
|
|
11
|
+
prev = decoded;
|
|
12
|
+
decoded = decoded.replace(/%25/gi, "%").replace(/%2e/gi, ".").replace(/%2f/gi, "/");
|
|
13
|
+
} while (decoded !== prev);
|
|
14
|
+
if (decoded.split("/").some((segment) => segment === "..")) return null;
|
|
15
|
+
return normalized;
|
|
16
|
+
}
|
|
5
17
|
var PROTOCOL_ID = "nominal-vibe-bridge";
|
|
6
18
|
var PROTOCOL_VERSION = 1;
|
|
7
19
|
var BRIDGE_KINDS = ["request", "response", "push", "command", "progress"];
|
|
@@ -18,6 +30,20 @@ function isBridgeMessage(data) {
|
|
|
18
30
|
if (CORRELATED_KINDS_SET.has(d.kind) && typeof d.requestId !== "string") return false;
|
|
19
31
|
return true;
|
|
20
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
|
+
};
|
|
21
47
|
|
|
22
48
|
// ../api-client/dist/index.js
|
|
23
49
|
import {
|
|
@@ -352,10 +378,6 @@ var getSubsidiaryParentCurrenciesApiTenancySubsidiarySubsidiaryIdParentCurrencie
|
|
|
352
378
|
};
|
|
353
379
|
function createVibeApiClient({ baseUrl, stripApiPrefix }) {
|
|
354
380
|
const client2 = createClient2(createConfig2({ baseUrl }));
|
|
355
|
-
client2.interceptors.request.use((request) => {
|
|
356
|
-
console.log("[vibe-api-client] request url:", request.url);
|
|
357
|
-
return request;
|
|
358
|
-
});
|
|
359
381
|
if (stripApiPrefix) {
|
|
360
382
|
client2.interceptors.request.use(
|
|
361
383
|
(request) => new Request(request.url.replace(`${baseUrl}/api/`, `${baseUrl}/`), request)
|
|
@@ -364,16 +386,28 @@ function createVibeApiClient({ baseUrl, stripApiPrefix }) {
|
|
|
364
386
|
return client2;
|
|
365
387
|
}
|
|
366
388
|
|
|
367
|
-
// src/
|
|
389
|
+
// src/handlers/call.ts
|
|
368
390
|
async function call(fn, payload, client2) {
|
|
369
|
-
const { data } = await fn({ ...payload, client: client2 });
|
|
370
|
-
if (data == null)
|
|
391
|
+
const { data, response } = await fn({ ...payload, client: client2 });
|
|
392
|
+
if (data == null) {
|
|
393
|
+
if (response && !response.ok) {
|
|
394
|
+
throw new HttpBridgeError(
|
|
395
|
+
response.status,
|
|
396
|
+
`API request failed with status ${response.status}`
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
if (!response) {
|
|
400
|
+
throw new Error("API request produced no response");
|
|
401
|
+
}
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
371
404
|
return data;
|
|
372
405
|
}
|
|
373
|
-
|
|
374
|
-
|
|
406
|
+
|
|
407
|
+
// src/handlers/accounting.ts
|
|
408
|
+
function accountingHandlers(client2) {
|
|
375
409
|
return {
|
|
376
|
-
//
|
|
410
|
+
// Chart of accounts
|
|
377
411
|
GET_CHART_OF_ACCOUNTS: (p) => call(getCoaFlatApiAccountingSubsidiarySubsidiaryIdCoaAccountGet, p, client2),
|
|
378
412
|
GET_COA_TREE: (p) => call(getCoaTreeApiAccountingSubsidiarySubsidiaryIdCoaGet, p, client2),
|
|
379
413
|
GET_COA_FLAT_SIMPLE: (p) => call(
|
|
@@ -398,7 +432,7 @@ function createHandlerMap(options) {
|
|
|
398
432
|
),
|
|
399
433
|
GET_ACCOUNTS: (p) => call(getAccountsApiAccountingAccountGet, p, client2),
|
|
400
434
|
GET_ACCOUNT: (p) => call(getAccountApiAccountingAccountAccountIdGet, p, client2),
|
|
401
|
-
//
|
|
435
|
+
// Exchange rates
|
|
402
436
|
GET_CONVERSION_RATES: (p) => call(getConversionRateApiAccountingCurrencyCurrencyConversionRatesGet, p, client2),
|
|
403
437
|
GET_EFFECTIVE_EXCHANGE_RATE: (p) => call(getEffectiveExchangeRateApiAccountingConsolidationExchangeRateGet, p, client2),
|
|
404
438
|
GET_EXCHANGE_RATE_BY_DATE: (p) => call(
|
|
@@ -406,7 +440,7 @@ function createHandlerMap(options) {
|
|
|
406
440
|
p,
|
|
407
441
|
client2
|
|
408
442
|
),
|
|
409
|
-
//
|
|
443
|
+
// Dimensions
|
|
410
444
|
GET_DIMENSIONS: (p) => call(getDimensionsApiAccountingDimensionGet, p, client2),
|
|
411
445
|
GET_DIMENSION_VALUES: (p) => call(getDimensionValuesApiAccountingDimensionValueGet, p, client2),
|
|
412
446
|
GET_DIMENSION_VALUES_HIERARCHICAL: (p) => call(
|
|
@@ -419,7 +453,7 @@ function createHandlerMap(options) {
|
|
|
419
453
|
p,
|
|
420
454
|
client2
|
|
421
455
|
),
|
|
422
|
-
//
|
|
456
|
+
// Journal entries
|
|
423
457
|
GET_JOURNAL_ENTRIES: (p) => call(
|
|
424
458
|
getSubsidiaryJournalApiAccountingSubsidiarySubsidiaryIdJournalEntryGet,
|
|
425
459
|
p,
|
|
@@ -434,8 +468,14 @@ function createHandlerMap(options) {
|
|
|
434
468
|
getJournalEntryApiAccountingSubsidiarySubsidiaryIdJournalEntryJournalEntryIdGet,
|
|
435
469
|
p,
|
|
436
470
|
client2
|
|
437
|
-
)
|
|
438
|
-
|
|
471
|
+
)
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/handlers/activity.ts
|
|
476
|
+
function activityHandlers(client2) {
|
|
477
|
+
return {
|
|
478
|
+
// Period instances
|
|
439
479
|
GET_PERIODS: (p) => call(getPeriodInstancesApiActivityPeriodInstanceGet, p, client2),
|
|
440
480
|
GET_PERIOD_INSTANCE: (p) => call(getPeriodInstanceApiActivityPeriodInstancePeriodInstanceIdGet, p, client2),
|
|
441
481
|
GET_PERIOD_INSTANCE_BY_SLUG: (p) => call(
|
|
@@ -448,14 +488,14 @@ function createHandlerMap(options) {
|
|
|
448
488
|
p,
|
|
449
489
|
client2
|
|
450
490
|
),
|
|
451
|
-
// Activity
|
|
491
|
+
// Activity definitions
|
|
452
492
|
GET_ACTIVITY_DEFINITIONS: (p) => call(getActivityDefinitionsApiActivityActivityDefinitionGet, p, client2),
|
|
453
493
|
GET_ACTIVITY_DEFINITION: (p) => call(
|
|
454
494
|
getActivityDefinitionByIdApiActivityActivityDefinitionActivityDefinitionIdGet,
|
|
455
495
|
p,
|
|
456
496
|
client2
|
|
457
497
|
),
|
|
458
|
-
// Activity
|
|
498
|
+
// Activity instances
|
|
459
499
|
GET_ACTIVITY_INSTANCES: (p) => call(getActivityInstancesApiActivityActivityInstanceGet, p, client2),
|
|
460
500
|
GET_ACTIVITY_INSTANCE: (p) => call(getActivityInstanceApiActivityActivityInstanceActivityInstanceIdGet, p, client2),
|
|
461
501
|
GET_ACTIVITY_INSTANCE_BY_PERIOD: (p) => call(
|
|
@@ -473,28 +513,43 @@ function createHandlerMap(options) {
|
|
|
473
513
|
p,
|
|
474
514
|
client2
|
|
475
515
|
),
|
|
476
|
-
//
|
|
516
|
+
// Task definitions
|
|
477
517
|
GET_TASK_DEFINITIONS: (p) => call(getAllTasksDefinitionsApiActivityTaskDefinitionGet, p, client2),
|
|
478
518
|
GET_TASK_DEFINITION: (p) => call(getTaskDefinitionByIdApiActivityTaskDefinitionTaskDefinitionIdGet, p, client2),
|
|
479
519
|
CREATE_TASK_DEFINITION: (p) => call(createTaskDefinitionApiActivityTaskDefinitionPost, p, client2),
|
|
480
520
|
UPDATE_TASK_DEFINITION: (p) => call(updateTaskDefinitionApiActivityTaskDefinitionTaskDefinitionIdPut, p, client2),
|
|
481
521
|
GET_TASK_DEFINITIONS_BY_FILTER: (p) => call(getAllTasksDefinitionsByFilterApiActivityTaskDefinitionQueryPost, p, client2),
|
|
482
|
-
//
|
|
522
|
+
// Task instances
|
|
483
523
|
GET_TASK_INSTANCES: (p) => call(getAllTaskInstancesApiActivityTaskInstanceGet, p, client2),
|
|
484
524
|
GET_TASK_INSTANCE: (p) => call(getTaskInstanceByIdApiActivityTaskInstanceTaskInstanceIdGet, p, client2),
|
|
485
525
|
POST_TASK_OUTPUT: (p) => call(updateTaskInstanceApiActivityTaskInstanceTaskInstanceIdPut, p, client2),
|
|
486
|
-
GET_TASK_INSTANCES_BY_FILTER: (p) => call(getAllTaskInstancesByFilterApiActivityTaskInstanceQueryPost, p, client2)
|
|
487
|
-
|
|
526
|
+
GET_TASK_INSTANCES_BY_FILTER: (p) => call(getAllTaskInstancesByFilterApiActivityTaskInstanceQueryPost, p, client2)
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/handlers/audit-trail.ts
|
|
531
|
+
function auditTrailHandlers(client2) {
|
|
532
|
+
return {
|
|
488
533
|
GET_AUDIT_EVENTS: (p) => call(getEventsApiAuditTrailEventGet, p, client2),
|
|
489
|
-
GET_ENTITY_AUDIT_EVENTS: (p) => call(getEntityEventsApiAuditTrailEventEntityTargetTypeTargetIdPost, p, client2)
|
|
490
|
-
|
|
534
|
+
GET_ENTITY_AUDIT_EVENTS: (p) => call(getEntityEventsApiAuditTrailEventEntityTargetTypeTargetIdPost, p, client2)
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// src/handlers/period-manager.ts
|
|
539
|
+
function periodManagerHandlers(client2) {
|
|
540
|
+
return {
|
|
491
541
|
GET_FISCAL_CALENDARS: (p) => call(
|
|
492
542
|
getFiscalCalendarsBySubsidiaryApiPeriodManagerFiscalCalendarBySubsidiarySubsidiaryIdGet,
|
|
493
543
|
p,
|
|
494
544
|
client2
|
|
495
545
|
),
|
|
496
|
-
GET_FISCAL_CALENDAR: (p) => call(getFiscalCalendarByIdApiPeriodManagerFiscalCalendarCalendarIdGet, p, client2)
|
|
497
|
-
|
|
546
|
+
GET_FISCAL_CALENDAR: (p) => call(getFiscalCalendarByIdApiPeriodManagerFiscalCalendarCalendarIdGet, p, client2)
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/handlers/tenancy.ts
|
|
551
|
+
function tenancyHandlers(client2) {
|
|
552
|
+
return {
|
|
498
553
|
GET_SUBSIDIARIES: (p) => call(getAllSubsidiariesApiTenancySubsidiaryGet, p, client2),
|
|
499
554
|
GET_SUBSIDIARY: (p) => call(getSubsidiaryApiTenancySubsidiarySubsidiaryIdGet, p, client2),
|
|
500
555
|
GET_SUBSIDIARY_PARENT_CURRENCIES: (p) => call(
|
|
@@ -506,46 +561,115 @@ function createHandlerMap(options) {
|
|
|
506
561
|
};
|
|
507
562
|
}
|
|
508
563
|
|
|
509
|
-
// src/
|
|
510
|
-
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
564
|
+
// src/handlerMap.ts
|
|
565
|
+
function createHandlerMap(options) {
|
|
566
|
+
const client2 = createVibeApiClient(options);
|
|
567
|
+
return {
|
|
568
|
+
...accountingHandlers(client2),
|
|
569
|
+
...activityHandlers(client2),
|
|
570
|
+
...auditTrailHandlers(client2),
|
|
571
|
+
...periodManagerHandlers(client2),
|
|
572
|
+
...tenancyHandlers(client2)
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// src/rateLimiter.ts
|
|
577
|
+
var DEFAULT_RATE_LIMIT = 60;
|
|
578
|
+
function createRateLimiter(limit = DEFAULT_RATE_LIMIT, windowMs = 6e4) {
|
|
579
|
+
return { timestamps: [], limit, windowMs };
|
|
580
|
+
}
|
|
581
|
+
function checkRateLimit(state) {
|
|
582
|
+
const now = Date.now();
|
|
583
|
+
const cutoff = now - state.windowMs;
|
|
584
|
+
state.timestamps = state.timestamps.filter((t) => t > cutoff);
|
|
585
|
+
if (state.timestamps.length >= state.limit) {
|
|
586
|
+
return false;
|
|
515
587
|
}
|
|
516
|
-
|
|
588
|
+
state.timestamps.push(now);
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/unwired.ts
|
|
593
|
+
function warnUnwired(command) {
|
|
594
|
+
return () => {
|
|
595
|
+
console.warn(`[vibe-host] Received "${command}" command but no handler is wired \u2014 ignoring.`);
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function rejectUnwired(op) {
|
|
599
|
+
return () => Promise.reject(
|
|
600
|
+
new BridgeError("NOT_WIRED", `[vibe-host] Received "${op}" request but no handler is wired.`)
|
|
601
|
+
);
|
|
517
602
|
}
|
|
518
603
|
|
|
519
604
|
// src/VibeAppHost.ts
|
|
520
605
|
var VibeAppHost = class {
|
|
521
|
-
constructor(
|
|
606
|
+
constructor(opts) {
|
|
522
607
|
this.iframeWindow = null;
|
|
608
|
+
/**
|
|
609
|
+
* Source windows we've already logged a successful handshake for. The bridge
|
|
610
|
+
* polls `GET_CONTEXT` on an interval until it connects, so without this the
|
|
611
|
+
* "Vibe App connected" line repeats on every poll (SSOT §13 F3).
|
|
612
|
+
*/
|
|
613
|
+
this.handshakeLoggedWindows = /* @__PURE__ */ new WeakSet();
|
|
523
614
|
this.kindHandlers = {
|
|
524
615
|
request: (msg, source, origin) => this.handleRequest(msg, source, origin),
|
|
525
616
|
command: (msg) => this.dispatchCommand(msg)
|
|
526
617
|
};
|
|
527
|
-
|
|
528
|
-
REPORT_SUBROUTE: (payload) => {
|
|
529
|
-
const newPath = payload.subroute === "/" ? this.appBasePath : `${this.appBasePath}${payload.subroute}`;
|
|
530
|
-
const method = payload.replace ? "replaceState" : "pushState";
|
|
531
|
-
window.history[method](null, "", newPath);
|
|
532
|
-
}
|
|
533
|
-
};
|
|
618
|
+
const { trustedOrigins, getContext, appBasePath, clientConfig } = opts;
|
|
534
619
|
this.trustedOrigins = new Set(trustedOrigins);
|
|
535
620
|
this.getContext = getContext;
|
|
536
621
|
this.appBasePath = appBasePath;
|
|
622
|
+
this.onRequestComplete = opts.onRequestComplete;
|
|
623
|
+
this.rateLimiter = createRateLimiter(opts.rateLimit ?? DEFAULT_RATE_LIMIT);
|
|
537
624
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
538
625
|
this.boundHandlePopState = this.handlePopState.bind(this);
|
|
539
|
-
this.handlers = this.initializeHandlers(
|
|
626
|
+
this.handlers = this.initializeHandlers(
|
|
627
|
+
clientConfig || { baseUrl: "", stripApiPrefix: false },
|
|
628
|
+
opts
|
|
629
|
+
);
|
|
630
|
+
this.commandHandlers = this.buildCommandHandlers(opts);
|
|
540
631
|
}
|
|
541
632
|
dispatchCommand(msg) {
|
|
542
633
|
const handler = this.commandHandlers[msg.type];
|
|
543
|
-
handler
|
|
634
|
+
if (!handler) {
|
|
635
|
+
console.warn(`[vibe-host] Received unknown command "${msg.type}" \u2014 ignoring.`);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
try {
|
|
639
|
+
handler(msg.payload);
|
|
640
|
+
} catch (err) {
|
|
641
|
+
console.warn(`[vibe-host] Command "${msg.type}" handler threw \u2014 ignoring.`, err);
|
|
642
|
+
}
|
|
544
643
|
}
|
|
545
|
-
|
|
644
|
+
/**
|
|
645
|
+
* Commands: `REPORT_SUBROUTE` is handled internally (transport + traversal
|
|
646
|
+
* guard, item `l`); navigation/UI side effects are injected by the consumer,
|
|
647
|
+
* falling back to warn-and-ignore (DP4).
|
|
648
|
+
*/
|
|
649
|
+
buildCommandHandlers(opts) {
|
|
650
|
+
return {
|
|
651
|
+
REPORT_SUBROUTE: (payload) => {
|
|
652
|
+
const safe = normalizeSubroute(payload.subroute);
|
|
653
|
+
if (safe === null) return;
|
|
654
|
+
const newPath = safe === "/" ? this.appBasePath : `${this.appBasePath}${safe}`;
|
|
655
|
+
const method = payload.replace ? "replaceState" : "pushState";
|
|
656
|
+
window.history[method](null, "", newPath);
|
|
657
|
+
},
|
|
658
|
+
NAVIGATE: opts.onNavigate ?? warnUnwired("NAVIGATE"),
|
|
659
|
+
SET_SIDE_NAV: opts.onSetSideNav ?? warnUnwired("SET_SIDE_NAV"),
|
|
660
|
+
SWITCH_SUBSIDIARY: opts.onSwitchSubsidiary ?? warnUnwired("SWITCH_SUBSIDIARY")
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Requests: the built-in API map (hey-api), plus the injected/awaited side
|
|
665
|
+
* effects with safe defaults — unwired `UPLOAD_FILE` rejects with a coded
|
|
666
|
+
* error; unwired `INVALIDATE_CACHE` resolves to a no-op (DP4).
|
|
667
|
+
*/
|
|
668
|
+
initializeHandlers(clientConfig, opts) {
|
|
546
669
|
return {
|
|
547
670
|
...createHandlerMap(clientConfig),
|
|
548
|
-
UPLOAD_FILE:
|
|
671
|
+
UPLOAD_FILE: opts.onUpload ?? rejectUnwired("UPLOAD_FILE"),
|
|
672
|
+
INVALIDATE_CACHE: opts.onInvalidateCache ?? (async () => ({ invalidated: false }))
|
|
549
673
|
};
|
|
550
674
|
}
|
|
551
675
|
/**
|
|
@@ -617,12 +741,33 @@ var VibeAppHost = class {
|
|
|
617
741
|
async handleRequest(msg, source, origin) {
|
|
618
742
|
const { requestId, type } = msg;
|
|
619
743
|
if (type === "GET_CONTEXT") {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
744
|
+
try {
|
|
745
|
+
const ctx = { ...this.getContext(), hostVersion: version };
|
|
746
|
+
if (!this.handshakeLoggedWindows.has(source)) {
|
|
747
|
+
this.handshakeLoggedWindows.add(source);
|
|
748
|
+
const bridgeVersion = msg.payload?.bridgeVersion ?? "unknown";
|
|
749
|
+
console.log(
|
|
750
|
+
`[vibe-host] Vibe App connected \u2014 bridge: ${bridgeVersion}, host: ${version}, tenant: ${ctx.tenant}, user: ${ctx.user.displayName}`
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
this.respond(source, origin, { kind: "response", type, requestId, ok: true, data: ctx });
|
|
754
|
+
} catch (err) {
|
|
755
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
756
|
+
const code = err instanceof BridgeError ? err.code : "CONTEXT_ERROR";
|
|
757
|
+
this.respond(source, origin, { kind: "response", type, requestId, ok: false, error, code });
|
|
758
|
+
}
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (!checkRateLimit(this.rateLimiter)) {
|
|
762
|
+
this.respond(source, origin, {
|
|
763
|
+
kind: "response",
|
|
764
|
+
type,
|
|
765
|
+
requestId,
|
|
766
|
+
ok: false,
|
|
767
|
+
error: `Too many requests. Limit is ${this.rateLimiter.limit} per minute.`,
|
|
768
|
+
code: "RATE_LIMITED"
|
|
769
|
+
});
|
|
770
|
+
this.onRequestComplete?.({ type, ok: false, payload: msg.payload });
|
|
626
771
|
return;
|
|
627
772
|
}
|
|
628
773
|
const sendProgress = (payload) => {
|
|
@@ -640,9 +785,21 @@ var VibeAppHost = class {
|
|
|
640
785
|
const handler = this.handlers[type];
|
|
641
786
|
const data = await handler(msg.payload, sendProgress);
|
|
642
787
|
this.respond(source, origin, { kind: "response", type, requestId, ok: true, data });
|
|
788
|
+
this.onRequestComplete?.({ type, ok: true, payload: msg.payload });
|
|
643
789
|
} catch (err) {
|
|
644
790
|
const error = err instanceof Error ? err.message : String(err);
|
|
645
|
-
|
|
791
|
+
const code = err instanceof BridgeError ? err.code : void 0;
|
|
792
|
+
const status = err instanceof HttpBridgeError ? err.status : void 0;
|
|
793
|
+
this.respond(source, origin, {
|
|
794
|
+
kind: "response",
|
|
795
|
+
type,
|
|
796
|
+
requestId,
|
|
797
|
+
ok: false,
|
|
798
|
+
error,
|
|
799
|
+
code,
|
|
800
|
+
status
|
|
801
|
+
});
|
|
802
|
+
this.onRequestComplete?.({ type, ok: false, payload: msg.payload });
|
|
646
803
|
}
|
|
647
804
|
}
|
|
648
805
|
respond(target, origin, response) {
|
|
@@ -653,5 +810,7 @@ var VibeAppHost = class {
|
|
|
653
810
|
}
|
|
654
811
|
};
|
|
655
812
|
export {
|
|
813
|
+
BridgeError,
|
|
814
|
+
HttpBridgeError,
|
|
656
815
|
VibeAppHost
|
|
657
816
|
};
|
package/package.json
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nominalso/vibe-host",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Host-side SDK for embedding Nominal Vibe Apps — receives bridge requests over a typed postMessage protocol and dispatches them to Nominal APIs (used by nom-ui).",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"nominal",
|
|
8
|
-
"vibe-apps",
|
|
9
|
-
"vibe-app",
|
|
10
|
-
"sdk",
|
|
11
|
-
"iframe",
|
|
12
|
-
"postmessage",
|
|
13
|
-
"host",
|
|
14
|
-
"embed"
|
|
15
|
-
],
|
|
16
6
|
"homepage": "https://github.com/nominalso/vibe-apps-sdk#readme",
|
|
17
7
|
"bugs": {
|
|
18
8
|
"url": "https://github.com/nominalso/vibe-apps-sdk/issues"
|