vue-app-sdk
Version:
332 lines (331 loc) • 9.45 kB
JavaScript
import { toValue, pausableWatch as watchPausable, tryOnMounted, watchWithFilter, isClient, noop, isObject, tryOnScopeDispose } from "../shared/index.js";
import { bypassFilter, createFilterWrapper, getLifeCycleTarget, pausableFilter } from "../shared/index.js";
import { shallowRef, ref, watch, nextTick } from "vue";
const defaultWindow = isClient ? window : void 0;
function unrefElement(elRef) {
var _a;
const plain = toValue(elRef);
return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
}
function useEventListener(...args) {
let target;
let events;
let listeners;
let options;
if (typeof args[0] === "string" || Array.isArray(args[0])) {
[events, listeners, options] = args;
target = defaultWindow;
} else {
[target, events, listeners, options] = args;
}
if (!target)
return noop;
if (!Array.isArray(events))
events = [events];
if (!Array.isArray(listeners))
listeners = [listeners];
const cleanups = [];
const cleanup = () => {
cleanups.forEach((fn) => fn());
cleanups.length = 0;
};
const register = (el, event, listener, options2) => {
el.addEventListener(event, listener, options2);
return () => el.removeEventListener(event, listener, options2);
};
const stopWatch = watch(
() => [unrefElement(target), toValue(options)],
([el, options2]) => {
cleanup();
if (!el)
return;
const optionsClone = isObject(options2) ? { ...options2 } : options2;
cleanups.push(
...events.flatMap((event) => {
return listeners.map((listener) => register(el, event, listener, optionsClone));
})
);
},
{ immediate: true, flush: "post" }
);
const stop = () => {
stopWatch();
cleanup();
};
tryOnScopeDispose(stop);
return stop;
}
const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
const globalKey = "__vueuse_ssr_handlers__";
const handlers = /* @__PURE__ */ getHandlers();
function getHandlers() {
if (!(globalKey in _global))
_global[globalKey] = _global[globalKey] || {};
return _global[globalKey];
}
function getSSRHandler(key, fallback) {
return handlers[key] || fallback;
}
function guessSerializerType(rawInit) {
return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any";
}
const StorageSerializers = {
boolean: {
read: (v) => v === "true",
write: (v) => String(v)
},
object: {
read: (v) => JSON.parse(v),
write: (v) => JSON.stringify(v)
},
number: {
read: (v) => Number.parseFloat(v),
write: (v) => String(v)
},
any: {
read: (v) => v,
write: (v) => String(v)
},
string: {
read: (v) => v,
write: (v) => String(v)
},
map: {
read: (v) => new Map(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v.entries()))
},
set: {
read: (v) => new Set(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v))
},
date: {
read: (v) => new Date(v),
write: (v) => v.toISOString()
}
};
const customStorageEventName = "vueuse-storage";
function useStorage(key, defaults, storage, options = {}) {
var _a;
const {
flush = "pre",
deep = true,
listenToStorageChanges = true,
writeDefaults = true,
mergeDefaults = false,
shallow,
window: window2 = defaultWindow,
eventFilter,
onError = (e) => {
console.error(e);
},
initOnMounted
} = options;
const data = (shallow ? shallowRef : ref)(typeof defaults === "function" ? defaults() : defaults);
if (!storage) {
try {
storage = getSSRHandler("getDefaultStorage", () => {
var _a2;
return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
})();
} catch (e) {
onError(e);
}
}
if (!storage)
return data;
const rawInit = toValue(defaults);
const type = guessSerializerType(rawInit);
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
const { pause: pauseWatch, resume: resumeWatch } = watchPausable(
data,
() => write(data.value),
{ flush, deep, eventFilter }
);
if (window2 && listenToStorageChanges) {
tryOnMounted(() => {
if (storage instanceof Storage)
useEventListener(window2, "storage", update);
else
useEventListener(window2, customStorageEventName, updateFromCustomEvent);
if (initOnMounted)
update();
});
}
if (!initOnMounted)
update();
function dispatchWriteEvent(oldValue, newValue) {
if (window2) {
const payload = {
key,
oldValue,
newValue,
storageArea: storage
};
window2.dispatchEvent(storage instanceof Storage ? new StorageEvent("storage", payload) : new CustomEvent(customStorageEventName, {
detail: payload
}));
}
}
function write(v) {
try {
const oldValue = storage.getItem(key);
if (v == null) {
dispatchWriteEvent(oldValue, null);
storage.removeItem(key);
} else {
const serialized = serializer.write(v);
if (oldValue !== serialized) {
storage.setItem(key, serialized);
dispatchWriteEvent(oldValue, serialized);
}
}
} catch (e) {
onError(e);
}
}
function read(event) {
const rawValue = event ? event.newValue : storage.getItem(key);
if (rawValue == null) {
if (writeDefaults && rawInit != null)
storage.setItem(key, serializer.write(rawInit));
return rawInit;
} else if (!event && mergeDefaults) {
const value = serializer.read(rawValue);
if (typeof mergeDefaults === "function")
return mergeDefaults(value, rawInit);
else if (type === "object" && !Array.isArray(value))
return { ...rawInit, ...value };
return value;
} else if (typeof rawValue !== "string") {
return rawValue;
} else {
return serializer.read(rawValue);
}
}
function update(event) {
if (event && event.storageArea !== storage)
return;
if (event && event.key == null) {
data.value = rawInit;
return;
}
if (event && event.key !== key)
return;
pauseWatch();
try {
if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))
data.value = read(event);
} catch (e) {
onError(e);
} finally {
if (event)
nextTick(resumeWatch);
else
resumeWatch();
}
}
function updateFromCustomEvent(event) {
update(event.detail);
}
return data;
}
function useStorageAsync(key, initialValue, storage, options = {}) {
var _a;
const {
flush = "pre",
deep = true,
listenToStorageChanges = true,
writeDefaults = true,
mergeDefaults = false,
shallow,
window: window2 = defaultWindow,
eventFilter,
onError = (e) => {
console.error(e);
}
} = options;
const rawInit = toValue(initialValue);
const type = guessSerializerType(rawInit);
const data = (shallow ? shallowRef : ref)(initialValue);
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
if (!storage) {
try {
storage = getSSRHandler("getDefaultStorageAsync", () => {
var _a2;
return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
})();
} catch (e) {
onError(e);
}
}
async function read(event) {
if (!storage || event && event.key !== key)
return;
try {
const rawValue = event ? event.newValue : await storage.getItem(key);
if (rawValue == null) {
data.value = rawInit;
if (writeDefaults && rawInit !== null)
await storage.setItem(key, await serializer.write(rawInit));
} else if (mergeDefaults) {
const value = await serializer.read(rawValue);
if (typeof mergeDefaults === "function")
data.value = mergeDefaults(value, rawInit);
else if (type === "object" && !Array.isArray(value))
data.value = { ...rawInit, ...value };
else data.value = value;
} else {
data.value = await serializer.read(rawValue);
}
} catch (e) {
onError(e);
}
}
read();
if (window2 && listenToStorageChanges)
useEventListener(window2, "storage", (e) => Promise.resolve().then(() => read(e)));
if (storage) {
watchWithFilter(
data,
async () => {
try {
if (data.value == null)
await storage.removeItem(key);
else
await storage.setItem(key, await serializer.write(data.value));
} catch (e) {
onError(e);
}
},
{
flush,
deep,
eventFilter
}
);
}
return data;
}
export {
StorageSerializers,
bypassFilter,
createFilterWrapper,
customStorageEventName,
defaultWindow,
getLifeCycleTarget,
getSSRHandler,
isClient,
isObject,
noop,
pausableFilter,
watchPausable as pausableWatch,
toValue,
tryOnMounted,
tryOnScopeDispose,
unrefElement,
useEventListener,
useStorage,
useStorageAsync,
watchPausable,
watchWithFilter
};