@provydon/vue-auto-save
Version:
A Vue 3 composable that autosaves forms with debounce, optional field skipping, and blockable watchers.
116 lines (115 loc) • 2.44 kB
JavaScript
import { ref as F, watch as x, onScopeDispose as J, isRef as N, unref as P } from "vue";
const R = [
"save",
"applicationId",
"isDirty",
"processing",
"errors",
"hasErrors",
"recentlySuccessful",
"wasSuccessful",
"data",
"transform",
"get",
"post",
"put",
"patch",
"delete",
"cancel",
"reset",
"clearErrors",
"setError",
"setData"
];
function C(c, h) {
const {
debounce: s = 3e3,
skipFields: I = [],
skipInertiaFields: T = !0,
deep: O = !0,
debug: n = !1,
serialize: y = JSON.stringify,
compare: o,
saveOnInit: b = !1,
onSave: W,
onBeforeSave: m,
onAfterSave: g,
onError: l
} = h, u = F(!1), a = F(!0);
let r = () => {
}, i = () => {
};
const z = (t = 1e3) => {
a.value = !1, r(), i(), setTimeout(() => {
a.value = !0;
}, t);
}, j = (t = null) => {
if (a.value = !0, r(), i(), t === null)
f(), o ? v = null : d = null, p();
else {
const e = A(p, t);
i = e.cancel, e.call();
}
}, f = () => {
const t = N(c) ? P(c) : c, e = {};
for (const S of Object.keys(t))
T && R.includes(S) || I.includes(S) || (e[S] = t[S]);
return e;
};
let d = b ? null : y(f()), v = o ? b ? null : f() : null;
const p = () => {
if (!a.value) return;
const t = f();
if (o) {
if (v && o(v, t)) return;
v = t;
} else {
const e = y(t);
if (d !== null && e === d) return;
d = e;
}
n && console.log("[AutoSave] Detected changes. Saving..."), u.value = !0;
try {
m == null || m(), Promise.resolve(W()).then(() => {
g == null || g(), n && console.log("[AutoSave] Save successful.");
}).catch((e) => {
l == null || l(e), n && console.error("[AutoSave] Save failed:", e);
}).finally(() => {
u.value = !1;
});
} catch (e) {
l == null || l(e), n && console.error("[AutoSave] Immediate error:", e), u.value = !1;
}
}, D = A(p, s), w = D.call;
r = D.cancel;
const k = x(
c,
w,
{
deep: O,
flush: "post"
}
);
return J(() => {
k(), r(), i();
}), b && p(), {
isAutoSaving: u,
blockWatcher: z,
unblockWatcher: j,
stop: k
};
}
function A(c, h) {
let s;
return {
call: () => {
clearTimeout(s), s = setTimeout(() => c(), h);
},
cancel: () => {
clearTimeout(s);
}
};
}
export {
C as useAutoSaveForm
};