@nominalso/vibe-host 0.4.0 → 0.5.1
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 +17 -33
- package/dist/index.cjs +147 -56
- package/dist/index.d.cts +152 -70
- package/dist/index.d.ts +152 -70
- package/dist/index.js +147 -56
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1390,6 +1390,7 @@ type ActivityProviderOperationErrorType = 'Connection Error' | 'Authentication E
|
|
|
1390
1390
|
type ActivityReconciliationDefinitionData = {
|
|
1391
1391
|
type: ActivityReconciliationType;
|
|
1392
1392
|
task_definition_id: string;
|
|
1393
|
+
currency?: ActivityCurrency | null;
|
|
1393
1394
|
side_a_entity_type: ActivityReconciliationEntityType;
|
|
1394
1395
|
side_a_entity_id: string;
|
|
1395
1396
|
side_b_entity_type: ActivityReconciliationEntityType;
|
|
@@ -1403,7 +1404,6 @@ type ActivityReconciliationInstanceDataInput = {
|
|
|
1403
1404
|
task_instance_id: string;
|
|
1404
1405
|
start_date: string;
|
|
1405
1406
|
end_date: string;
|
|
1406
|
-
currency?: ActivityCurrency | null;
|
|
1407
1407
|
side_a_value?: number | string | null;
|
|
1408
1408
|
side_b_value?: number | string | null;
|
|
1409
1409
|
reconciling_items_balance?: number | string | null;
|
|
@@ -1417,7 +1417,6 @@ type ActivityReconciliationInstanceDataOutput = {
|
|
|
1417
1417
|
task_instance_id: string;
|
|
1418
1418
|
start_date: string;
|
|
1419
1419
|
end_date: string;
|
|
1420
|
-
currency?: ActivityCurrency | null;
|
|
1421
1420
|
side_a_value?: string | null;
|
|
1422
1421
|
side_b_value?: string | null;
|
|
1423
1422
|
reconciling_items_balance?: string | null;
|
|
@@ -3188,9 +3187,10 @@ interface BridgeSubsidiary {
|
|
|
3188
3187
|
*
|
|
3189
3188
|
* The host (nom-ui) is the single source of truth for these values — it knows
|
|
3190
3189
|
* the project key, the env-aware ingestion host, and the resolved person — and
|
|
3191
|
-
* delivers
|
|
3192
|
-
*
|
|
3193
|
-
*
|
|
3190
|
+
* delivers it over the bridge (as a one-time `POSTHOG_PUSH`, separate from
|
|
3191
|
+
* {@link ContextPayload}) so the iframe never hardcodes any of it. When the host
|
|
3192
|
+
* has no PostHog config (recording disabled for this env/app), it sends no
|
|
3193
|
+
* `POSTHOG_PUSH` and the bridge initializes nothing.
|
|
3194
3194
|
*/
|
|
3195
3195
|
interface PostHogContext {
|
|
3196
3196
|
/** Project API key — the same PostHog project the host (nom-ui) uses. */
|
|
@@ -3228,6 +3228,27 @@ interface PostHogContext {
|
|
|
3228
3228
|
*/
|
|
3229
3229
|
enabled: boolean;
|
|
3230
3230
|
}
|
|
3231
|
+
/**
|
|
3232
|
+
* Authentication-state change the host pushes to the iframe via `AUTH_CHANGED`.
|
|
3233
|
+
* It carries the security principal the embedded app authenticates and scopes
|
|
3234
|
+
* its own data by. Sent when the Nominal session changes: a logout
|
|
3235
|
+
* (`authenticated: false`) or an identity/tenant switch (`authenticated: true`
|
|
3236
|
+
* with a new `userId`/`tenant`). The initial state is implicit at connect — the
|
|
3237
|
+
* iframe only loads when authenticated, and the current identity/tenant are
|
|
3238
|
+
* {@link ContextPayload.user} / {@link ContextPayload.tenant}, so apps baseline
|
|
3239
|
+
* off those and react to this push.
|
|
3240
|
+
*
|
|
3241
|
+
* Subsidiary/period and other view-level state are NOT here — they ride the
|
|
3242
|
+
* follow-up `CONTEXT_PUSH` (`onContextChange`), per "auth change, then context".
|
|
3243
|
+
*/
|
|
3244
|
+
interface AuthPayload {
|
|
3245
|
+
/** Whether the Nominal user is still authenticated. */
|
|
3246
|
+
authenticated: boolean;
|
|
3247
|
+
/** The effective Nominal user id when authenticated; omitted on logout. */
|
|
3248
|
+
userId?: string;
|
|
3249
|
+
/** The tenant the user is acting in — the app's data-scoping key (RLS). */
|
|
3250
|
+
tenant?: string;
|
|
3251
|
+
}
|
|
3231
3252
|
interface ContextPayload {
|
|
3232
3253
|
tenant: string;
|
|
3233
3254
|
subsidiaryId: number;
|
|
@@ -3240,22 +3261,32 @@ interface ContextPayload {
|
|
|
3240
3261
|
subroute?: string;
|
|
3241
3262
|
/** Slug of the last closed accounting period, e.g. "mar-2026". */
|
|
3242
3263
|
lastClosedPeriodSlug?: string;
|
|
3243
|
-
/**
|
|
3244
|
-
* PostHog config for in-iframe session recording + custom events. **Absent
|
|
3245
|
-
* when recording is off** (older host, or disabled for this env/app), in which
|
|
3246
|
-
* case the bridge initializes no analytics. Optional so old hosts/bridges stay
|
|
3247
|
-
* compatible.
|
|
3248
|
-
*/
|
|
3249
|
-
posthog?: PostHogContext;
|
|
3250
3264
|
/** Version of the host SDK (@nominalso/vibe-host) running in nom-ui. */
|
|
3251
3265
|
hostVersion: string;
|
|
3252
3266
|
}
|
|
3253
|
-
/** Payload sent by the bridge when requesting context from the host. */
|
|
3254
|
-
interface GetContextPayload {
|
|
3255
|
-
/** Version of the bridge SDK (@nominalso/vibe-bridge) running in the iframe. */
|
|
3256
|
-
bridgeVersion: string;
|
|
3257
|
-
}
|
|
3258
3267
|
|
|
3268
|
+
/**
|
|
3269
|
+
* Response type for operations whose Nominal OpenAPI `200` response declares
|
|
3270
|
+
* **no content schema**. hey-api generates `200: unknown` for these, so there is
|
|
3271
|
+
* genuinely no concrete type to narrow to at codegen time — the shape is
|
|
3272
|
+
* undocumented upstream, not merely unmapped by this SDK.
|
|
3273
|
+
*
|
|
3274
|
+
* We surface this named alias instead of a bare `unknown` so the gap is
|
|
3275
|
+
* self-documenting: editors show `UntypedApiResponse` (with this doc) rather than
|
|
3276
|
+
* an anonymous `unknown`, signalling that the value must be explicitly asserted
|
|
3277
|
+
* to a known shape (`const p = res as MyPeriod`) rather than trusted. It stays
|
|
3278
|
+
* assignment-compatible with `unknown`, so no runtime or narrowing behaviour
|
|
3279
|
+
* changes.
|
|
3280
|
+
*
|
|
3281
|
+
* The fix is upstream: document these endpoints' response bodies in the owning
|
|
3282
|
+
* Nominal service's OpenAPI (then the registry entry can reference the generated
|
|
3283
|
+
* `*Response` type). Affected ops today: `GET_PERIODS`, `GET_PERIOD_INSTANCE`,
|
|
3284
|
+
* `GET_PERIOD_INSTANCE_BY_SLUG`, `POST_TASK_OUTPUT`, `GET_TASK_INSTANCE`,
|
|
3285
|
+
* `GET_TASK_INSTANCES`, `GET_TASK_DEFINITION`, `GET_ACTIVITY_DEFINITION(S)`,
|
|
3286
|
+
* `GET_ACTIVITY_INSTANCE`, `GET_ACTIVITY_INSTANCE_TASKS`,
|
|
3287
|
+
* `GET_ACTIVITY_PERIOD_TASKS`.
|
|
3288
|
+
*/
|
|
3289
|
+
type UntypedApiResponse = unknown;
|
|
3259
3290
|
interface UploadPayload {
|
|
3260
3291
|
buffer: ArrayBuffer;
|
|
3261
3292
|
fileName: string;
|
|
@@ -3328,11 +3359,11 @@ interface RequestRegistry {
|
|
|
3328
3359
|
};
|
|
3329
3360
|
GET_PERIODS: {
|
|
3330
3361
|
payload: Omit<GetPeriodInstancesApiActivityPeriodInstanceGetData, 'url'>;
|
|
3331
|
-
data:
|
|
3362
|
+
data: UntypedApiResponse;
|
|
3332
3363
|
};
|
|
3333
3364
|
POST_TASK_OUTPUT: {
|
|
3334
3365
|
payload: Omit<UpdateTaskInstanceApiActivityTaskInstanceTaskInstanceIdPutData, 'url'>;
|
|
3335
|
-
data:
|
|
3366
|
+
data: UntypedApiResponse;
|
|
3336
3367
|
};
|
|
3337
3368
|
GET_DIMENSIONS: {
|
|
3338
3369
|
payload: Omit<GetDimensionsApiAccountingDimensionGetData, 'url'>;
|
|
@@ -3348,7 +3379,7 @@ interface RequestRegistry {
|
|
|
3348
3379
|
};
|
|
3349
3380
|
GET_ACTIVITY_DEFINITIONS: {
|
|
3350
3381
|
payload: Omit<GetActivityDefinitionsApiActivityActivityDefinitionGetData, 'url'>;
|
|
3351
|
-
data:
|
|
3382
|
+
data: UntypedApiResponse;
|
|
3352
3383
|
};
|
|
3353
3384
|
GET_TASK_DEFINITIONS: {
|
|
3354
3385
|
payload: Omit<GetAllTasksDefinitionsApiActivityTaskDefinitionGetData, 'url'>;
|
|
@@ -3356,7 +3387,7 @@ interface RequestRegistry {
|
|
|
3356
3387
|
};
|
|
3357
3388
|
GET_TASK_INSTANCES: {
|
|
3358
3389
|
payload: Omit<GetAllTaskInstancesApiActivityTaskInstanceGetData, 'url'>;
|
|
3359
|
-
data:
|
|
3390
|
+
data: UntypedApiResponse;
|
|
3360
3391
|
};
|
|
3361
3392
|
GET_FISCAL_CALENDARS: {
|
|
3362
3393
|
payload: Omit<GetFiscalCalendarsBySubsidiaryApiPeriodManagerFiscalCalendarBySubsidiarySubsidiaryIdGetData, 'url'>;
|
|
@@ -3424,11 +3455,11 @@ interface RequestRegistry {
|
|
|
3424
3455
|
};
|
|
3425
3456
|
GET_PERIOD_INSTANCE: {
|
|
3426
3457
|
payload: Omit<GetPeriodInstanceApiActivityPeriodInstancePeriodInstanceIdGetData, 'url'>;
|
|
3427
|
-
data:
|
|
3458
|
+
data: UntypedApiResponse;
|
|
3428
3459
|
};
|
|
3429
3460
|
GET_PERIOD_INSTANCE_BY_SLUG: {
|
|
3430
3461
|
payload: Omit<GetPeriodInstanceBySlugApiActivityPeriodInstanceBySlugPeriodDisplayIdGetData, 'url'>;
|
|
3431
|
-
data:
|
|
3462
|
+
data: UntypedApiResponse;
|
|
3432
3463
|
};
|
|
3433
3464
|
GET_PERIOD_PROGRESS_BREAKDOWN: {
|
|
3434
3465
|
payload: Omit<GetPeriodInstanceProgressBreakdownBySlugApiActivityPeriodInstanceBySlugPeriodDisplayIdProgressBreakdownGetData, 'url'>;
|
|
@@ -3436,7 +3467,7 @@ interface RequestRegistry {
|
|
|
3436
3467
|
};
|
|
3437
3468
|
GET_ACTIVITY_DEFINITION: {
|
|
3438
3469
|
payload: Omit<GetActivityDefinitionByIdApiActivityActivityDefinitionActivityDefinitionIdGetData, 'url'>;
|
|
3439
|
-
data:
|
|
3470
|
+
data: UntypedApiResponse;
|
|
3440
3471
|
};
|
|
3441
3472
|
GET_ACTIVITY_INSTANCES: {
|
|
3442
3473
|
payload: Omit<GetActivityInstancesApiActivityActivityInstanceGetData, 'url'>;
|
|
@@ -3444,7 +3475,7 @@ interface RequestRegistry {
|
|
|
3444
3475
|
};
|
|
3445
3476
|
GET_ACTIVITY_INSTANCE: {
|
|
3446
3477
|
payload: Omit<GetActivityInstanceApiActivityActivityInstanceActivityInstanceIdGetData, 'url'>;
|
|
3447
|
-
data:
|
|
3478
|
+
data: UntypedApiResponse;
|
|
3448
3479
|
};
|
|
3449
3480
|
GET_ACTIVITY_INSTANCE_BY_PERIOD: {
|
|
3450
3481
|
payload: Omit<GetActivityInstanceByPeriodApiActivityActivityInstanceByPeriodPeriodDisplayIdActivityDefinitionIdGetData, 'url'>;
|
|
@@ -3452,15 +3483,15 @@ interface RequestRegistry {
|
|
|
3452
3483
|
};
|
|
3453
3484
|
GET_ACTIVITY_INSTANCE_TASKS: {
|
|
3454
3485
|
payload: Omit<GetTaskInstancesByActivityApiActivityActivityInstanceActivityInstanceIdTaskGetData, 'url'>;
|
|
3455
|
-
data:
|
|
3486
|
+
data: UntypedApiResponse;
|
|
3456
3487
|
};
|
|
3457
3488
|
GET_ACTIVITY_PERIOD_TASKS: {
|
|
3458
3489
|
payload: Omit<GetTaskInstancesByActivityPeriodApiActivityActivityInstanceByPeriodPeriodDisplayIdActivityDefinitionIdTaskGetData, 'url'>;
|
|
3459
|
-
data:
|
|
3490
|
+
data: UntypedApiResponse;
|
|
3460
3491
|
};
|
|
3461
3492
|
GET_TASK_DEFINITION: {
|
|
3462
3493
|
payload: Omit<GetTaskDefinitionByIdApiActivityTaskDefinitionTaskDefinitionIdGetData, 'url'>;
|
|
3463
|
-
data:
|
|
3494
|
+
data: UntypedApiResponse;
|
|
3464
3495
|
};
|
|
3465
3496
|
CREATE_TASK_DEFINITION: {
|
|
3466
3497
|
payload: Omit<CreateTaskDefinitionApiActivityTaskDefinitionPostData, 'url'>;
|
|
@@ -3476,7 +3507,7 @@ interface RequestRegistry {
|
|
|
3476
3507
|
};
|
|
3477
3508
|
GET_TASK_INSTANCE: {
|
|
3478
3509
|
payload: Omit<GetTaskInstanceByIdApiActivityTaskInstanceTaskInstanceIdGetData, 'url'>;
|
|
3479
|
-
data:
|
|
3510
|
+
data: UntypedApiResponse;
|
|
3480
3511
|
};
|
|
3481
3512
|
GET_TASK_INSTANCES_BY_FILTER: {
|
|
3482
3513
|
payload: Omit<GetAllTaskInstancesByFilterApiActivityTaskInstanceQueryPostData, 'url'>;
|
|
@@ -3506,10 +3537,6 @@ interface RequestRegistry {
|
|
|
3506
3537
|
payload: InvalidateCachePayload;
|
|
3507
3538
|
data: InvalidateResult;
|
|
3508
3539
|
};
|
|
3509
|
-
GET_CONTEXT: {
|
|
3510
|
-
payload: GetContextPayload;
|
|
3511
|
-
data: ContextPayload;
|
|
3512
|
-
};
|
|
3513
3540
|
UPLOAD_FILE: {
|
|
3514
3541
|
payload: UploadPayload;
|
|
3515
3542
|
data: UploadResponse;
|
|
@@ -3540,12 +3567,24 @@ type RequestHandlers = {
|
|
|
3540
3567
|
* string-matching `error.message`. A failed Nominal API call rehydrates as the
|
|
3541
3568
|
* {@link HttpBridgeError} subtype, which adds the HTTP `status`.
|
|
3542
3569
|
*
|
|
3570
|
+
* SDK-originated codes you may also see: `'TIMEOUT'` (a request or the connect
|
|
3571
|
+
* handshake timed out), `'DESTROYED'` (the bridge was torn down mid-flight),
|
|
3572
|
+
* `'PARENT_ORIGIN_UNRESOLVED'` (no embedding origin could be resolved) and
|
|
3573
|
+
* `'SERVER_ENVIRONMENT'` (a browser-only method was called where there is no
|
|
3574
|
+
* `window` — e.g. during SSR / in a React Server Component / in a Worker).
|
|
3575
|
+
*
|
|
3576
|
+
* This class is safe to import from any environment (see the module header).
|
|
3577
|
+
*
|
|
3543
3578
|
* @example
|
|
3544
3579
|
* ```ts
|
|
3580
|
+
* import { BridgeError } from '@nominalso/vibe-bridge'
|
|
3581
|
+
*
|
|
3545
3582
|
* try {
|
|
3546
3583
|
* await bridge.getAccounts({})
|
|
3547
3584
|
* } catch (err) {
|
|
3548
|
-
*
|
|
3585
|
+
* // `instanceof` works within a single bundle; `isBridgeError` also works
|
|
3586
|
+
* // across independently-built server/client bundles.
|
|
3587
|
+
* if (BridgeError.isBridgeError(err) && err.code === 'RATE_LIMITED') {
|
|
3549
3588
|
* // back off and retry
|
|
3550
3589
|
* }
|
|
3551
3590
|
* }
|
|
@@ -3554,6 +3593,13 @@ type RequestHandlers = {
|
|
|
3554
3593
|
declare class BridgeError extends Error {
|
|
3555
3594
|
readonly code: string;
|
|
3556
3595
|
constructor(code: string, message: string);
|
|
3596
|
+
/**
|
|
3597
|
+
* Cross-realm-safe type guard. Prefer this over `instanceof BridgeError` when
|
|
3598
|
+
* an error may have been thrown by a differently-built copy of the SDK (e.g.
|
|
3599
|
+
* server bundle vs client bundle) — it matches on a process-global brand
|
|
3600
|
+
* rather than class identity.
|
|
3601
|
+
*/
|
|
3602
|
+
static isBridgeError(err: unknown): err is BridgeError;
|
|
3557
3603
|
}
|
|
3558
3604
|
/**
|
|
3559
3605
|
* A {@link BridgeError} for a failed Nominal API call. Its `code` is always
|
|
@@ -3563,10 +3609,12 @@ declare class BridgeError extends Error {
|
|
|
3563
3609
|
*
|
|
3564
3610
|
* @example
|
|
3565
3611
|
* ```ts
|
|
3612
|
+
* import { HttpBridgeError } from '@nominalso/vibe-bridge'
|
|
3613
|
+
*
|
|
3566
3614
|
* try {
|
|
3567
3615
|
* await bridge.getAccount({ path: { account_id: 'missing' } })
|
|
3568
3616
|
* } catch (err) {
|
|
3569
|
-
* if (err
|
|
3617
|
+
* if (HttpBridgeError.isHttpBridgeError(err) && err.status === 404) {
|
|
3570
3618
|
* // handle not-found
|
|
3571
3619
|
* }
|
|
3572
3620
|
* }
|
|
@@ -3575,6 +3623,11 @@ declare class BridgeError extends Error {
|
|
|
3575
3623
|
declare class HttpBridgeError extends BridgeError {
|
|
3576
3624
|
readonly status: number;
|
|
3577
3625
|
constructor(status: number, message: string);
|
|
3626
|
+
/**
|
|
3627
|
+
* Cross-realm-safe type guard (see {@link BridgeError.isBridgeError}). Returns
|
|
3628
|
+
* `true` only for `HttpBridgeError` instances, not plain `BridgeError`s.
|
|
3629
|
+
*/
|
|
3630
|
+
static isHttpBridgeError(err: unknown): err is HttpBridgeError;
|
|
3578
3631
|
}
|
|
3579
3632
|
|
|
3580
3633
|
interface VibeApiClientOptions {
|
|
@@ -3623,6 +3676,13 @@ interface VibeAppHostOptions {
|
|
|
3623
3676
|
trustedOrigins: string[];
|
|
3624
3677
|
/** Returns the current context to send to the iframe on connect. */
|
|
3625
3678
|
getContext: () => HostContext;
|
|
3679
|
+
/**
|
|
3680
|
+
* Optional PostHog config source. Read **once per iframe** at connect and
|
|
3681
|
+
* delivered via a one-time `POSTHOG_PUSH`, kept separate from `getContext` so
|
|
3682
|
+
* it never re-sends when context or auth later change. Return `undefined` (or
|
|
3683
|
+
* a config with `enabled: false`) to disable in-iframe recording.
|
|
3684
|
+
*/
|
|
3685
|
+
getPostHog?: () => PostHogContext | undefined;
|
|
3626
3686
|
/**
|
|
3627
3687
|
* The base URL path of this Vibe App in nom-ui, e.g. `/acme/1/apps/fixed-assets`.
|
|
3628
3688
|
* Used to sync the browser URL with the iframe's internal subroute.
|
|
@@ -3675,18 +3735,11 @@ interface VibeAppHostOptions {
|
|
|
3675
3735
|
* onUpload: (p, sendProgress) => uploadToS3(p, sendProgress),
|
|
3676
3736
|
* })
|
|
3677
3737
|
*
|
|
3678
|
-
* useEffect(() =>
|
|
3679
|
-
* const iframe = iframeRef.current
|
|
3680
|
-
* if (!iframe) return
|
|
3681
|
-
* const unmount = host.mount() // listen before the iframe loads
|
|
3682
|
-
* const onLoad = () => iframe.contentWindow && host.pushContextTo(iframe.contentWindow)
|
|
3683
|
-
* iframe.addEventListener('load', onLoad)
|
|
3684
|
-
* return () => {
|
|
3685
|
-
* iframe.removeEventListener('load', onLoad)
|
|
3686
|
-
* unmount()
|
|
3687
|
-
* }
|
|
3688
|
-
* }, [host])
|
|
3738
|
+
* useEffect(() => host.mount(), [host]) // returns the unmount cleanup
|
|
3689
3739
|
* ```
|
|
3740
|
+
*
|
|
3741
|
+
* `mount()` just starts listening; the iframe identifies itself via its
|
|
3742
|
+
* `CONNECT` handshake, so the host never needs the iframe's `Window` up front.
|
|
3690
3743
|
*/
|
|
3691
3744
|
declare class VibeAppHost {
|
|
3692
3745
|
/**
|
|
@@ -3699,26 +3752,29 @@ declare class VibeAppHost {
|
|
|
3699
3752
|
/** The exact (non-pattern) subset of {@link trustedOrigins} — see {@link concreteTargets}. */
|
|
3700
3753
|
private readonly exactOrigins;
|
|
3701
3754
|
/**
|
|
3702
|
-
*
|
|
3703
|
-
*
|
|
3704
|
-
*
|
|
3755
|
+
* The connected iframe, as two facets of one thing: `connectedWindow` is its
|
|
3756
|
+
* `Window` (identity + the single push target) and `connectedOrigin` is its
|
|
3757
|
+
* origin (what you `postMessage` to — you cannot post to a `Window` ref, nor to
|
|
3758
|
+
* a glob). Both are written together by {@link handleConnect} (the sole writer)
|
|
3759
|
+
* and cleared together on unmount, so they can never diverge.
|
|
3760
|
+
*
|
|
3761
|
+
* There is deliberately no other window reference. The connected window can
|
|
3762
|
+
* only be learned from each `CONNECT` handshake's `event.source`, never at
|
|
3763
|
+
* mount: a reloaded/remounted iframe is a *new* `Window` with the same origin,
|
|
3764
|
+
* so a mount-time window would be stale. The gate blocks every non-`CONNECT`
|
|
3765
|
+
* message whose source isn't `connectedWindow`; every proactive push targets it.
|
|
3705
3766
|
*/
|
|
3706
|
-
private
|
|
3767
|
+
private connectedWindow;
|
|
3768
|
+
private connectedOrigin;
|
|
3707
3769
|
private readonly handlers;
|
|
3708
3770
|
private readonly commandHandlers;
|
|
3709
3771
|
private readonly getContext;
|
|
3772
|
+
private readonly getPostHog?;
|
|
3710
3773
|
private readonly appBasePath;
|
|
3711
3774
|
private readonly onRequestComplete?;
|
|
3712
3775
|
private readonly rateLimiter;
|
|
3713
3776
|
private readonly boundHandleMessage;
|
|
3714
3777
|
private readonly boundHandlePopState;
|
|
3715
|
-
private iframeWindow;
|
|
3716
|
-
/**
|
|
3717
|
-
* Source windows we've already logged a successful handshake for. The bridge
|
|
3718
|
-
* polls `GET_CONTEXT` on an interval until it connects, so without this the
|
|
3719
|
-
* "Vibe App connected" line repeats on every poll (SSOT §13 F3).
|
|
3720
|
-
*/
|
|
3721
|
-
private readonly handshakeLoggedWindows;
|
|
3722
3778
|
private readonly kindHandlers;
|
|
3723
3779
|
private dispatchCommand;
|
|
3724
3780
|
/**
|
|
@@ -3738,31 +3794,57 @@ declare class VibeAppHost {
|
|
|
3738
3794
|
* Starts listening for bridge messages and sets up browser back/forward sync.
|
|
3739
3795
|
* Returns a cleanup function to call on unmount.
|
|
3740
3796
|
*
|
|
3741
|
-
*
|
|
3742
|
-
*
|
|
3743
|
-
*
|
|
3744
|
-
|
|
3797
|
+
* Takes no iframe window: the host learns the iframe from its `CONNECT`
|
|
3798
|
+
* handshake (and re-learns it on every reload), then delivers context as the
|
|
3799
|
+
* reply to that handshake. Just call `mount()` once the host exists.
|
|
3800
|
+
*/
|
|
3801
|
+
mount(): () => void;
|
|
3802
|
+
/**
|
|
3803
|
+
* Re-reads `getContext()` and re-pushes it to the connected iframe, so an open
|
|
3804
|
+
* app reacts to a tenant/subsidiary switch or period close without reloading.
|
|
3805
|
+
* PostHog is not re-sent (it rides only the connect handshake). No-op until an
|
|
3806
|
+
* iframe is mounted.
|
|
3745
3807
|
*/
|
|
3746
|
-
|
|
3808
|
+
refreshContext(): void;
|
|
3747
3809
|
/**
|
|
3748
|
-
*
|
|
3749
|
-
*
|
|
3750
|
-
*
|
|
3810
|
+
* Notifies the connected iframe of a Nominal auth change — a logout
|
|
3811
|
+
* (`authenticated: false`) or an identity/tenant switch (`authenticated: true`
|
|
3812
|
+
* with a new `userId`/`tenant`) — via `AUTH_CHANGED`, so the app re-authenticates
|
|
3813
|
+
* or signs its own backend out. No-op until the iframe has connected. When auth
|
|
3814
|
+
* and context change together, call this *before* {@link refreshContext} ("auth
|
|
3815
|
+
* change, then context").
|
|
3751
3816
|
*/
|
|
3752
|
-
|
|
3817
|
+
notifyAuthChange(auth: AuthPayload): void;
|
|
3753
3818
|
private pushContext;
|
|
3754
3819
|
private handlePopState;
|
|
3755
3820
|
private pushToIframe;
|
|
3821
|
+
/**
|
|
3822
|
+
* Sends the host's PostHog config to a freshly connected iframe as a one-time
|
|
3823
|
+
* POSTHOG_PUSH. No-op when no `getPostHog` source is configured or it returns
|
|
3824
|
+
* nothing (recording disabled). Targets the exact handshaking window/origin
|
|
3825
|
+
* (no `concreteTargets` fan-out) since it fires from a validated inbound poll.
|
|
3826
|
+
*/
|
|
3827
|
+
private pushPostHog;
|
|
3756
3828
|
private handleMessage;
|
|
3829
|
+
/**
|
|
3830
|
+
* Handles the CONNECT handshake: records the connecting window/origin (which
|
|
3831
|
+
* opens the connection gate for it) and pushes the initial context + one-time
|
|
3832
|
+
* PostHog config. Only the first CONNECT per origin pushes — later retries are
|
|
3833
|
+
* ignored, so the bridge receives exactly one initial CONTEXT_PUSH (no
|
|
3834
|
+
* spurious onContextChange). A reloaded iframe is a new window and re-connects
|
|
3835
|
+
* normally. If `getContext()` throws, the window is left unconnected so the
|
|
3836
|
+
* bridge's retry can recover.
|
|
3837
|
+
*/
|
|
3838
|
+
private handleConnect;
|
|
3757
3839
|
/**
|
|
3758
3840
|
* Concrete origins a proactive push may target: the exact allowlist entries
|
|
3759
|
-
* plus
|
|
3760
|
-
*
|
|
3761
|
-
*
|
|
3841
|
+
* plus the connected iframe's learned origin. Never includes glob patterns
|
|
3842
|
+
* (you cannot `postMessage` to one). When only exact origins are configured
|
|
3843
|
+
* this equals the configured set, so behaviour is unchanged.
|
|
3762
3844
|
*/
|
|
3763
3845
|
private concreteTargets;
|
|
3764
3846
|
private handleRequest;
|
|
3765
3847
|
private respond;
|
|
3766
3848
|
}
|
|
3767
3849
|
|
|
3768
|
-
export { BridgeError, type ContextPayload, type HostContext, type HostHandlers, HttpBridgeError, type InvalidateCachePayload, type InvalidateResult, type NavigateAction, type NavigatePayload, type PostHogContext, type RequestCompleteInfo, type RequestHandlers, type SetSideNavPayload, type SwitchSubsidiaryPayload, type UploadPayload, type UploadProgress, type UploadResponse, type VibeApiClientOptions, VibeAppHost, type VibeAppHostOptions };
|
|
3850
|
+
export { type AuthPayload, BridgeError, type ContextPayload, type HostContext, type HostHandlers, HttpBridgeError, type InvalidateCachePayload, type InvalidateResult, type NavigateAction, type NavigatePayload, type PostHogContext, type RequestCompleteInfo, type RequestHandlers, type SetSideNavPayload, type SwitchSubsidiaryPayload, type UploadPayload, type UploadProgress, type UploadResponse, type VibeApiClientOptions, VibeAppHost, type VibeAppHostOptions };
|