@onboardjs/supabase-plugin
Version:
Official Supabase persistence plugin for OnboardJS.
83 lines (82 loc) • 3.36 kB
JavaScript
import { BasePlugin as l } from "@onboardjs/core";
class d extends l {
constructor(t) {
if (super(t), this.name = "onboardjs-supabase-plugin", this.version = "1.0.0", !t.client)
throw new Error("[Supabase Plugin] Supabase client instance is required.");
if (!t.useSupabaseAuth && !t.contextKeyForId)
throw new Error(
"[Supabase Plugin] Either `useSupabaseAuth` must be true or `contextKeyForId` must be provided."
);
this.config = t, this._tableName = t.tableName ?? "onboarding_state", this._userIdColumn = t.userIdColumn ?? "user_id", this._stateDataColumn = t.stateDataColumn ?? "state_data";
}
/**
* Installs the Supabase persistence plugin into the OnboardingEngine.
* @param engine The OnboardingEngine instance to install the plugin into.
* @returns A cleanup function to remove the plugin's handlers.
*/
async install(t) {
await super.install(t);
const r = () => {
const e = t.getState().context, s = this.config.useSupabaseAuth ? "currentUser.id" : this.config.contextKeyForId;
if (!s) return;
const a = s.split(".").reduce((i, n) => i ? i[n] : void 0, e);
if (typeof a == "string")
return a;
a !== void 0 && console.warn(
`[Supabase Plugin] Expected a string at context key '${s}', but found type '${typeof a}'.`
);
};
return t.setDataLoadHandler(async () => {
let e, s = null;
if (this.config.useSupabaseAuth) {
const { data: u } = await this.config.client.auth.getUser();
s = u.user, e = s?.id;
} else
e = r();
if (!e) return null;
const { data: a, error: i } = await this.config.client.from(this._tableName).select(this._stateDataColumn).eq(this._userIdColumn, e).maybeSingle();
if (i)
return this._handleError(i, "load"), null;
const n = (a && typeof a == "object" ? a[this._stateDataColumn] : {}) || {};
return this.config.useSupabaseAuth && s && (n.currentUser = s), n;
}), t.setDataPersistHandler(async (e, s) => {
const a = r();
if (!a) return;
const i = {
...e,
currentStepId: s
// Include the current step ID in the persisted state
}, { error: n } = await this.config.client.from(this._tableName).upsert(
{
[this._userIdColumn]: a,
[this._stateDataColumn]: i
},
{ onConflict: this._userIdColumn }
);
n && this._handleError(n, "persist");
}), t.setClearPersistedDataHandler(async () => {
const e = r();
if (!e) return;
const { error: s } = await this.config.client.from(this._tableName).update({
[this._stateDataColumn]: null
}).eq(this._userIdColumn, e);
s && this._handleError(s, "clear");
}), async () => {
t.setDataLoadHandler(void 0), t.setDataPersistHandler(void 0), t.setClearPersistedDataHandler(void 0);
};
}
_handleError(t, r) {
if (this.config.onError && this.config.onError(t, r), this.engine) {
const e = new Error(`[Supabase Plugin] Operation '${r}' failed: ${t.message}`);
e.cause = t, this.engine.reportError(e, `SupabasePlugin.${r}`);
} else
console.error(`[Supabase Plugin] Operation '${r}' failed:`, t);
}
}
function h(o) {
return new d(o);
}
export {
d as SupabasePersistencePlugin,
h as createSupabasePlugin
};