@nebulr-group/bridge-svelte 0.9.1-beta.0 → 0.9.1-beta.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.
|
@@ -199,6 +199,39 @@ async function waitForConfigured() {
|
|
|
199
199
|
clearTimeout(timer);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
/** Longest the first render waits for the plan's features before showing anyway. */
|
|
203
|
+
const ENTITLEMENTS_FIRST_RENDER_WAIT_MS = 1500;
|
|
204
|
+
// TBP-810 — flag rules on `bridge:billing.entitlement.*` read auth-core's
|
|
205
|
+
// entitlements store. Nothing ever configured it, so it could not load itself
|
|
206
|
+
// and only filled from `/session/init` on the first realtime connect, about a
|
|
207
|
+
// second after the page rendered. Until then an entitled user saw every
|
|
208
|
+
// plan-gated feature locked (and a click offered an upgrade). Configure it,
|
|
209
|
+
// then load it before the first render — bounded, so a slow or failing read
|
|
210
|
+
// shows the page anyway and the store fills in when it can, as before.
|
|
211
|
+
async function loadEntitlementsBeforeFirstRender(bridge) {
|
|
212
|
+
try {
|
|
213
|
+
const store = useBridge().entitlementsStore;
|
|
214
|
+
store.configure({
|
|
215
|
+
apiBaseUrl: bridge.getApiContext().apiBaseUrl,
|
|
216
|
+
getAccessToken: () => bridge.getApiContext().accessToken ?? null,
|
|
217
|
+
}, logger);
|
|
218
|
+
if (store.isHydrated())
|
|
219
|
+
return;
|
|
220
|
+
let timer;
|
|
221
|
+
const timeout = new Promise((resolve) => {
|
|
222
|
+
timer = setTimeout(resolve, ENTITLEMENTS_FIRST_RENDER_WAIT_MS);
|
|
223
|
+
});
|
|
224
|
+
try {
|
|
225
|
+
await Promise.race([store.hydrate(), timeout]);
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
logger.debug('[bridgeBootstrap] entitlements not loaded before first render:', err);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
202
235
|
// Once per page load. Concurrent callers share the same promise, so a first
|
|
203
236
|
// navigation that redirects mid-bootstrap does not start a second refresh or
|
|
204
237
|
// flag load. Never rejects: every step is best-effort by design — none of them
|
|
@@ -219,17 +252,22 @@ function ensureInitialised() {
|
|
|
219
252
|
}
|
|
220
253
|
// Auto-manage billing state so the notice/gate render without the
|
|
221
254
|
// integrator wiring a mount, and `hard` billing route rules can decide.
|
|
255
|
+
// The plan's features load alongside it (same round-trip time, so the
|
|
256
|
+
// page waits no longer).
|
|
222
257
|
try {
|
|
223
258
|
const bridge = getBridgeAuth();
|
|
224
259
|
const ctx = bridge.getApiContext();
|
|
225
260
|
if (ctx.accessToken) {
|
|
226
|
-
await
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
261
|
+
await Promise.all([
|
|
262
|
+
useBridge().subscription.mount({
|
|
263
|
+
apiBaseUrl: ctx.apiBaseUrl,
|
|
264
|
+
accessToken: ctx.accessToken,
|
|
265
|
+
appId: ctx.appId,
|
|
266
|
+
// TBP-762 — renew an out-of-date sign-in and retry instead of failing.
|
|
267
|
+
onTokenStale: tokenStaleHandlerOf(bridge),
|
|
268
|
+
}),
|
|
269
|
+
loadEntitlementsBeforeFirstRender(bridge),
|
|
270
|
+
]);
|
|
233
271
|
}
|
|
234
272
|
}
|
|
235
273
|
catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebulr-group/bridge-svelte",
|
|
3
|
-
"version": "0.9.1-beta.
|
|
3
|
+
"version": "0.9.1-beta.1",
|
|
4
4
|
"description": "The Bridge for SvelteKit: sign-in, workspaces and roles, feature flags, Stripe subscriptions and plan limits in one .env line and three files.",
|
|
5
5
|
"author": "Iman Pouya",
|
|
6
6
|
"license": "MIT",
|