@nebulr-group/bridge-auth-core 0.7.1 → 0.7.2
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.
|
@@ -14,13 +14,22 @@ interface ConfigureOptions {
|
|
|
14
14
|
export declare class EntitlementsStore {
|
|
15
15
|
private _cache;
|
|
16
16
|
private _hydrated;
|
|
17
|
+
private _lastAttemptAt;
|
|
17
18
|
private _hydrating;
|
|
18
19
|
private _subscribers;
|
|
19
20
|
private _opts;
|
|
20
21
|
private _logger;
|
|
21
22
|
/** Wire HTTP options + optional logger. Framework wrappers call this once. */
|
|
22
23
|
configure(opts: ConfigureOptions, logger?: Logger): void;
|
|
23
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Has a real answer arrived yet? Drives fail-closed reads.
|
|
26
|
+
*
|
|
27
|
+
* `can()` cannot distinguish "not loaded" from "explicitly denied" — both
|
|
28
|
+
* read as `false`. That is correct for gating UX, but it is also why a store
|
|
29
|
+
* that never hydrated looked exactly like a workspace entitled to nothing,
|
|
30
|
+
* instead of a bug (TBP-686). Check this before treating a `false` as a
|
|
31
|
+
* denial, and when showing a paywall rather than a spinner.
|
|
32
|
+
*/
|
|
24
33
|
isHydrated(): boolean;
|
|
25
34
|
/**
|
|
26
35
|
* Initial-hydration fetch. Idempotent — concurrent callers share one
|
|
@@ -47,6 +56,20 @@ export declare class EntitlementsStore {
|
|
|
47
56
|
can(name: string): boolean;
|
|
48
57
|
/** All cached entitlements (shallow copy). */
|
|
49
58
|
all(): EntitlementSnapshot;
|
|
59
|
+
/**
|
|
60
|
+
* Force a re-fetch, ignoring the retry interval and the hydrated flag.
|
|
61
|
+
* For a consumer that knows something changed out of band.
|
|
62
|
+
*/
|
|
63
|
+
refresh(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Kick a hydration attempt from a read, so the store recovers on its own
|
|
66
|
+
* once a token exists.
|
|
67
|
+
*
|
|
68
|
+
* Deliberately throttled: a failing endpoint would otherwise be retried on
|
|
69
|
+
* every `can()` call, and `can()` runs inside render. The in-flight guard in
|
|
70
|
+
* `hydrate()` handles concurrency; this handles repetition.
|
|
71
|
+
*/
|
|
72
|
+
private _ensureHydrating;
|
|
50
73
|
/**
|
|
51
74
|
* Subscribe to snapshot changes. Returns an unsubscribe fn.
|
|
52
75
|
* Does NOT invoke immediately with the current snapshot — the consumer can
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlements-store.d.ts","sourceRoot":"","sources":["../../src/billing/entitlements-store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAExD,UAAU,gBAAgB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACrC;
|
|
1
|
+
{"version":3,"file":"entitlements-store.d.ts","sourceRoot":"","sources":["../../src/billing/entitlements-store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAExD,UAAU,gBAAgB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACrC;AAWD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAAsB;IAErC,8EAA8E;IAC9E,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,GAAE,MAAmB,GAAG,IAAI;IAKpE;;;;;;;;OAQG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC9B;;;;OAIG;IACH,wBAAwB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAM7D;;;;;;;;OAQG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQ1B,8CAA8C;IAC9C,GAAG,IAAI,mBAAmB;IAK1B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,IAAI;IAOnC,0CAA0C;IAC1C,eAAe,IAAI,IAAI;IASvB,OAAO,CAAC,OAAO;CAUhB"}
|
|
@@ -17,9 +17,12 @@ const noopLogger = {
|
|
|
17
17
|
warn: () => { },
|
|
18
18
|
error: () => { },
|
|
19
19
|
};
|
|
20
|
+
/** Minimum gap between read-triggered hydration attempts. */
|
|
21
|
+
const RETRY_INTERVAL_MS = 2000;
|
|
20
22
|
export class EntitlementsStore {
|
|
21
23
|
_cache = {};
|
|
22
24
|
_hydrated = false;
|
|
25
|
+
_lastAttemptAt = 0;
|
|
23
26
|
_hydrating = false;
|
|
24
27
|
_subscribers = new Set();
|
|
25
28
|
_opts = null;
|
|
@@ -29,7 +32,15 @@ export class EntitlementsStore {
|
|
|
29
32
|
this._opts = opts;
|
|
30
33
|
this._logger = logger;
|
|
31
34
|
}
|
|
32
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Has a real answer arrived yet? Drives fail-closed reads.
|
|
37
|
+
*
|
|
38
|
+
* `can()` cannot distinguish "not loaded" from "explicitly denied" — both
|
|
39
|
+
* read as `false`. That is correct for gating UX, but it is also why a store
|
|
40
|
+
* that never hydrated looked exactly like a workspace entitled to nothing,
|
|
41
|
+
* instead of a bug (TBP-686). Check this before treating a `false` as a
|
|
42
|
+
* denial, and when showing a paywall rather than a spinner.
|
|
43
|
+
*/
|
|
33
44
|
isHydrated() {
|
|
34
45
|
return this._hydrated;
|
|
35
46
|
}
|
|
@@ -45,8 +56,14 @@ export class EntitlementsStore {
|
|
|
45
56
|
if (!this._opts)
|
|
46
57
|
return;
|
|
47
58
|
const token = this._opts.getAccessToken();
|
|
59
|
+
// No token yet. Attach fires before sign-in has produced one, so this is
|
|
60
|
+
// the normal first-load case, not an error — leave the store unhydrated so
|
|
61
|
+
// `_ensureHydrating()` can pick it up on the next read once a token exists.
|
|
62
|
+
// Returning here used to be terminal: nothing ever called hydrate again, so
|
|
63
|
+
// `can()` answered false for every key for the whole session (TBP-686).
|
|
48
64
|
if (!token)
|
|
49
65
|
return;
|
|
66
|
+
this._lastAttemptAt = Date.now();
|
|
50
67
|
this._hydrating = true;
|
|
51
68
|
try {
|
|
52
69
|
const url = `${this._opts.apiBaseUrl.replace(/\/+$/, '')}/entitlements`;
|
|
@@ -85,14 +102,44 @@ export class EntitlementsStore {
|
|
|
85
102
|
* — fail-closed protects against showing privileged UX on a cold start.
|
|
86
103
|
*/
|
|
87
104
|
can(name) {
|
|
88
|
-
if (!this._hydrated)
|
|
105
|
+
if (!this._hydrated) {
|
|
106
|
+
this._ensureHydrating();
|
|
89
107
|
return false;
|
|
108
|
+
}
|
|
90
109
|
return this._cache[name] === true;
|
|
91
110
|
}
|
|
92
111
|
/** All cached entitlements (shallow copy). */
|
|
93
112
|
all() {
|
|
113
|
+
if (!this._hydrated)
|
|
114
|
+
this._ensureHydrating();
|
|
94
115
|
return { ...this._cache };
|
|
95
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Force a re-fetch, ignoring the retry interval and the hydrated flag.
|
|
119
|
+
* For a consumer that knows something changed out of band.
|
|
120
|
+
*/
|
|
121
|
+
async refresh() {
|
|
122
|
+
this._hydrated = false;
|
|
123
|
+
this._lastAttemptAt = 0;
|
|
124
|
+
await this.hydrate();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Kick a hydration attempt from a read, so the store recovers on its own
|
|
128
|
+
* once a token exists.
|
|
129
|
+
*
|
|
130
|
+
* Deliberately throttled: a failing endpoint would otherwise be retried on
|
|
131
|
+
* every `can()` call, and `can()` runs inside render. The in-flight guard in
|
|
132
|
+
* `hydrate()` handles concurrency; this handles repetition.
|
|
133
|
+
*/
|
|
134
|
+
_ensureHydrating() {
|
|
135
|
+
if (this._hydrating || !this._opts)
|
|
136
|
+
return;
|
|
137
|
+
if (Date.now() - this._lastAttemptAt < RETRY_INTERVAL_MS)
|
|
138
|
+
return;
|
|
139
|
+
if (!this._opts.getAccessToken())
|
|
140
|
+
return;
|
|
141
|
+
void this.hydrate();
|
|
142
|
+
}
|
|
96
143
|
/**
|
|
97
144
|
* Subscribe to snapshot changes. Returns an unsubscribe fn.
|
|
98
145
|
* Does NOT invoke immediately with the current snapshot — the consumer can
|
|
@@ -109,6 +156,7 @@ export class EntitlementsStore {
|
|
|
109
156
|
this._cache = {};
|
|
110
157
|
this._hydrated = false;
|
|
111
158
|
this._hydrating = false;
|
|
159
|
+
this._lastAttemptAt = 0;
|
|
112
160
|
this._subscribers.clear();
|
|
113
161
|
this._opts = null;
|
|
114
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlements-store.js","sourceRoot":"","sources":["../../src/billing/entitlements-store.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,8EAA8E;AAC9E,wCAAwC;AACxC,wDAAwD;AACxD,+EAA+E;AAC/E,+EAA+E;AAC/E,gFAAgF;AAChF,qDAAqD;AACrD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,cAAc;AAEd,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAkBvC,MAAM,UAAU,GAAW;IACzB,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF,MAAM,OAAO,iBAAiB;IACpB,MAAM,GAAwB,EAAE,CAAC;IACjC,SAAS,GAAG,KAAK,CAAC;IAClB,UAAU,GAAG,KAAK,CAAC;IACnB,YAAY,GAAG,IAAI,GAAG,EAAY,CAAC;IACnC,KAAK,GAA4B,IAAI,CAAC;IACtC,OAAO,GAAW,UAAU,CAAC;IAErC,8EAA8E;IAC9E,SAAS,CAAC,IAAsB,EAAE,SAAiB,UAAU;QAC3D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"entitlements-store.js","sourceRoot":"","sources":["../../src/billing/entitlements-store.ts"],"names":[],"mappings":"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"}
|