@unhingged/vizu-core 0.1.0 → 0.1.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/dist/auto.cjs +62 -4
- package/dist/auto.cjs.map +1 -1
- package/dist/auto.js +62 -4
- package/dist/auto.js.map +1 -1
- package/dist/index.cjs +62 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +62 -4
- package/dist/index.js.map +1 -1
- package/dist/vizu.min.js +11 -11
- package/dist/vizu.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1724,10 +1724,28 @@ var CloudStorageAdapter = class {
|
|
|
1724
1724
|
this.cachedToken = null;
|
|
1725
1725
|
/** Single-flight: at most one popup at a time. Subsequent requests await this. */
|
|
1726
1726
|
this.pendingAuth = null;
|
|
1727
|
+
/** Whether we've already fired onAuthChanged for the current token. */
|
|
1728
|
+
this.lastNotifiedTokenId = null;
|
|
1727
1729
|
this.workspace = opts.workspace;
|
|
1728
1730
|
this.apiUrl = (opts.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
1729
1731
|
this.autoSignIn = opts.autoSignIn !== false;
|
|
1732
|
+
this.onAuthChanged = opts.onAuthChanged;
|
|
1730
1733
|
this.cachedToken = this.readStoredToken();
|
|
1734
|
+
if (this.cachedToken && !this.isExpired(this.cachedToken)) {
|
|
1735
|
+
this.fireAuthChanged(this.cachedToken);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Open the sign-in popup right now (or no-op if a valid token is
|
|
1740
|
+
* cached). Vizu calls this on enable() so the user signs in BEFORE
|
|
1741
|
+
* trying to leave a comment — no surprise modal mid-comment.
|
|
1742
|
+
*
|
|
1743
|
+
* Throws auth_canceled if the user closes the popup. Caller can
|
|
1744
|
+
* decide whether to disable the surface or leave it in a read-only
|
|
1745
|
+
* state.
|
|
1746
|
+
*/
|
|
1747
|
+
async preflightAuth() {
|
|
1748
|
+
await this.resolveToken();
|
|
1731
1749
|
}
|
|
1732
1750
|
/* ─── StorageAdapter v2 ───────────────────────────────────────────── */
|
|
1733
1751
|
async load(_namespace) {
|
|
@@ -1916,6 +1934,7 @@ var CloudStorageAdapter = class {
|
|
|
1916
1934
|
const fresh = this.readStoredToken();
|
|
1917
1935
|
if (fresh) {
|
|
1918
1936
|
this.cachedToken = fresh;
|
|
1937
|
+
this.fireAuthChanged(fresh);
|
|
1919
1938
|
return fresh;
|
|
1920
1939
|
}
|
|
1921
1940
|
if (!this.autoSignIn) {
|
|
@@ -1924,6 +1943,7 @@ var CloudStorageAdapter = class {
|
|
|
1924
1943
|
if (!this.pendingAuth) {
|
|
1925
1944
|
this.pendingAuth = this.openSignInPopup().then((t) => {
|
|
1926
1945
|
this.writeStoredToken(t);
|
|
1946
|
+
this.fireAuthChanged(t);
|
|
1927
1947
|
return t;
|
|
1928
1948
|
}).finally(() => {
|
|
1929
1949
|
this.pendingAuth = null;
|
|
@@ -1931,6 +1951,22 @@ var CloudStorageAdapter = class {
|
|
|
1931
1951
|
}
|
|
1932
1952
|
return this.pendingAuth;
|
|
1933
1953
|
}
|
|
1954
|
+
/**
|
|
1955
|
+
* Notify the host that the authenticated identity changed. De-duped
|
|
1956
|
+
* via the token string so multiple resolveToken() hits with the same
|
|
1957
|
+
* cached token don't re-call setUser on every fetch.
|
|
1958
|
+
*/
|
|
1959
|
+
fireAuthChanged(token) {
|
|
1960
|
+
if (this.lastNotifiedTokenId === token.token) return;
|
|
1961
|
+
this.lastNotifiedTokenId = token.token;
|
|
1962
|
+
try {
|
|
1963
|
+
this.onAuthChanged?.({ userId: token.userId, user: token.user });
|
|
1964
|
+
} catch (err) {
|
|
1965
|
+
if (typeof console !== "undefined") {
|
|
1966
|
+
console.warn("[vizu/cloud] onAuthChanged callback threw", err);
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1934
1970
|
openSignInPopup() {
|
|
1935
1971
|
return new Promise((resolve, reject) => {
|
|
1936
1972
|
if (typeof window === "undefined") {
|
|
@@ -1963,7 +1999,13 @@ var CloudStorageAdapter = class {
|
|
|
1963
1999
|
if (typeof data.token !== "string" || typeof data.expiresAt !== "string" || typeof data.userId !== "string") return;
|
|
1964
2000
|
resolved = true;
|
|
1965
2001
|
cleanup();
|
|
1966
|
-
|
|
2002
|
+
const userPayload = data.user;
|
|
2003
|
+
const user = userPayload && typeof userPayload.name === "string" ? {
|
|
2004
|
+
id: typeof userPayload.id === "string" ? userPayload.id : data.userId,
|
|
2005
|
+
name: userPayload.name,
|
|
2006
|
+
avatarUrl: typeof userPayload.avatarUrl === "string" ? userPayload.avatarUrl : void 0
|
|
2007
|
+
} : null;
|
|
2008
|
+
resolve({ token: data.token, expiresAt: data.expiresAt, userId: data.userId, user });
|
|
1967
2009
|
};
|
|
1968
2010
|
const onPoll = window.setInterval(() => {
|
|
1969
2011
|
if (popup.closed) {
|
|
@@ -4064,7 +4106,7 @@ var DEFAULTS = {
|
|
|
4064
4106
|
namespace: "default",
|
|
4065
4107
|
accent: "#FF6647"
|
|
4066
4108
|
};
|
|
4067
|
-
function resolveStorage(storage, cloud, defaultMode) {
|
|
4109
|
+
function resolveStorage(storage, cloud, defaultMode, onAuthChanged) {
|
|
4068
4110
|
if (cloud) {
|
|
4069
4111
|
if (storage && typeof console !== "undefined") {
|
|
4070
4112
|
console.warn("[vizu] Both `cloud` and `storage` set; `cloud` wins. Drop `storage` to silence this.");
|
|
@@ -4072,7 +4114,8 @@ function resolveStorage(storage, cloud, defaultMode) {
|
|
|
4072
4114
|
return new CloudStorageAdapter({
|
|
4073
4115
|
workspace: cloud.workspace,
|
|
4074
4116
|
apiUrl: cloud.apiUrl,
|
|
4075
|
-
autoSignIn: cloud.autoSignIn
|
|
4117
|
+
autoSignIn: cloud.autoSignIn,
|
|
4118
|
+
onAuthChanged
|
|
4076
4119
|
});
|
|
4077
4120
|
}
|
|
4078
4121
|
if (!storage) return defaultMode === "local" ? new LocalStorageAdapter() : new InMemoryStorageAdapter();
|
|
@@ -4178,7 +4221,14 @@ var Vizu = class {
|
|
|
4178
4221
|
this.opts.namespace = options.namespace ?? DEFAULTS.namespace;
|
|
4179
4222
|
this.opts.accent = options.accent ?? DEFAULTS.accent;
|
|
4180
4223
|
this.parsedShortcut = parseShortcut(this.opts.shortcut);
|
|
4181
|
-
this.storage = resolveStorage(
|
|
4224
|
+
this.storage = resolveStorage(
|
|
4225
|
+
options.storage,
|
|
4226
|
+
options.cloud,
|
|
4227
|
+
_defaultStorage,
|
|
4228
|
+
(info) => {
|
|
4229
|
+
if (info.user) this.setUser(info.user);
|
|
4230
|
+
}
|
|
4231
|
+
);
|
|
4182
4232
|
this.user = options.user ?? null;
|
|
4183
4233
|
if (options.actions) this.actions = [...options.actions];
|
|
4184
4234
|
if (options.onCommentAdded) this.bus.on("comment:added", (p) => options.onCommentAdded(p.comment));
|
|
@@ -4224,6 +4274,14 @@ var Vizu = class {
|
|
|
4224
4274
|
this.enabled = true;
|
|
4225
4275
|
this.bus.emit("enabled", {});
|
|
4226
4276
|
this.deferred(() => this.mount());
|
|
4277
|
+
if (this.storage instanceof CloudStorageAdapter) {
|
|
4278
|
+
void this.storage.preflightAuth().catch((err) => {
|
|
4279
|
+
if (err?.code === "auth_canceled" || err?.code === "popup_blocked") return;
|
|
4280
|
+
if (typeof console !== "undefined") {
|
|
4281
|
+
console.warn("[vizu] preflight auth failed:", err);
|
|
4282
|
+
}
|
|
4283
|
+
});
|
|
4284
|
+
}
|
|
4227
4285
|
}
|
|
4228
4286
|
disable() {
|
|
4229
4287
|
if (!this.enabled) return;
|