@onboardjs/supabase-plugin
Version:
Official Supabase persistence plugin for OnboardJS.
92 lines (91 loc) • 3.45 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 = "0.1.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) {
super.install(t);
const r = () => {
const s = t.getState().context, e = this.config.useSupabaseAuth ? "currentUser.id" : this.config.contextKeyForId;
if (!e) return;
const a = e.split(".").reduce((n, i) => n ? n[i] : void 0, s);
if (typeof a == "string")
return a;
a !== void 0 && console.warn(
`[Supabase Plugin] Expected a string at context key '${e}', but found type '${typeof a}'.`
);
};
return t.setDataLoadHandler(
async () => {
let s, e = null;
if (this.config.useSupabaseAuth) {
const { data: u } = await this.config.client.auth.getUser();
e = u.user, s = e == null ? void 0 : e.id;
} else
s = r();
if (!s) return null;
const { data: a, error: n } = await this.config.client.from(this.tableName).select(this.stateDataColumn).eq(this.userIdColumn, s).maybeSingle();
if (n)
return this._handleError(n, "load"), null;
const i = (a && typeof a == "object" ? a[this.stateDataColumn] : {}) || {};
return this.config.useSupabaseAuth && e && (i.currentUser = e), i;
}
), t.setDataPersistHandler(async (s, e) => {
const a = r();
if (!a) return;
const n = {
...s,
currentStepId: e
// Include the current step ID in the persisted state
}, { error: i } = await this.config.client.from(this.tableName).upsert(
{
[this.userIdColumn]: a,
[this.stateDataColumn]: n
},
{ onConflict: this.userIdColumn }
);
i && this._handleError(i, "persist");
}), t.setClearPersistedDataHandler(async () => {
const s = r();
if (!s) return;
const { error: e } = await this.config.client.from(this.tableName).update({
[this.stateDataColumn]: null
}).eq(this.userIdColumn, s);
e && this._handleError(e, "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 s = new Error(
`[Supabase Plugin] Operation '${r}' failed: ${t.message}`
);
s.cause = t, this.engine.reportError(s, `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
};