@inzombieland/core 1.18.14 → 1.18.16

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/api-client.mjs CHANGED
@@ -109,6 +109,10 @@ const optionsHandler = (options = {}, config) => {
109
109
  };
110
110
  const fetchRequest = (url, options = {}, fetch, config) => {
111
111
  const request = async () => {
112
+ const apiActions = useApiActions();
113
+ if (typeof window !== "undefined") {
114
+ await apiActions.value?.getVisitorIdentifier?.();
115
+ }
112
116
  const opts = optionsHandler(options, config);
113
117
  try {
114
118
  const response = await fetch.raw(url, opts);
@@ -116,7 +120,6 @@ const fetchRequest = (url, options = {}, fetch, config) => {
116
120
  } catch (error) {
117
121
  const { status } = error?.response ?? { status: 500 };
118
122
  if (status === 401 && url !== "/account/1/offline") {
119
- const apiActions = useApiActions();
120
123
  await apiActions.value?.refreshToken?.();
121
124
  return request();
122
125
  }
@@ -2,6 +2,7 @@ export * from "../helpers/composables";
2
2
  export { useActiveSessions } from "./use-active-sessions";
3
3
  export { useApiActions } from "./use-api-actions";
4
4
  export { useAppLocale } from "./use-app-locale";
5
+ export { useCookies } from "./use-cookies";
5
6
  export { useSubscribe } from "./use-subscribe";
6
7
  export { useThemeMode } from "./use-theme-mode";
7
8
  export { useUser } from "./use-user";
@@ -2,6 +2,7 @@ export * from "../helpers/composables.mjs";
2
2
  export { useActiveSessions } from "./use-active-sessions.mjs";
3
3
  export { useApiActions } from "./use-api-actions.mjs";
4
4
  export { useAppLocale } from "./use-app-locale.mjs";
5
+ export { useCookies } from "./use-cookies.mjs";
5
6
  export { useSubscribe } from "./use-subscribe.mjs";
6
7
  export { useThemeMode } from "./use-theme-mode.mjs";
7
8
  export { useUser } from "./use-user.mjs";
@@ -1,13 +1,10 @@
1
1
  export declare const useApiActions: () => import("vue").Ref<{
2
- initialized: boolean;
3
2
  getVisitorIdentifier?: (() => Promise<void>) | undefined;
4
3
  refreshToken?: (() => Promise<string>) | undefined;
5
4
  }, {
6
- initialized: boolean;
7
5
  getVisitorIdentifier?: () => Promise<void>;
8
6
  refreshToken?: () => Promise<string>;
9
7
  } | {
10
- initialized: boolean;
11
8
  getVisitorIdentifier?: (() => Promise<void>) | undefined;
12
9
  refreshToken?: (() => Promise<string>) | undefined;
13
10
  }>;
@@ -1,5 +1,5 @@
1
1
  import { ref } from "vue";
2
- const apiActions = ref({ initialized: false });
2
+ const apiActions = ref({});
3
3
  export const useApiActions = () => {
4
4
  return apiActions;
5
5
  };
@@ -0,0 +1,27 @@
1
+ import { type CookieParseOptions, type CookieSerializeOptions } from "cookie-es";
2
+ import { type Ref } from "vue";
3
+ declare global {
4
+ interface Window {
5
+ cookieStore?: {
6
+ addEventListener: (type: "change", listener: (event: any) => void) => void;
7
+ removeEventListener: (type: "change", listener: (event: any) => void) => void;
8
+ };
9
+ }
10
+ }
11
+ type _CookieOptions = Omit<CookieSerializeOptions & CookieParseOptions, "decode" | "encode">;
12
+ export interface CookieOptions<T = any> extends _CookieOptions {
13
+ decode?: (value: string) => T;
14
+ encode?: (value: T) => string;
15
+ default?: () => T | Ref<T>;
16
+ watch?: boolean | "shallow";
17
+ readonly?: boolean;
18
+ }
19
+ export interface CookieRef<T> extends Ref<T> {
20
+ }
21
+ export declare function useCookies<T = string | null | undefined>(name: string, _opts?: CookieOptions<T> & {
22
+ readonly?: false;
23
+ }): CookieRef<T>;
24
+ export declare function useCookies<T = string | null | undefined>(name: string, _opts: CookieOptions<T> & {
25
+ readonly: true;
26
+ }): Readonly<CookieRef<T>>;
27
+ export {};
@@ -0,0 +1,152 @@
1
+ import { parse, serialize } from "cookie-es";
2
+ import destr from "destr";
3
+ import { klona } from "klona";
4
+ import { isEqual } from "ohash";
5
+ import { customRef, getCurrentScope, nextTick, onScopeDispose, ref, watch } from "vue";
6
+ const CookieDefaults = {
7
+ path: "/",
8
+ watch: true,
9
+ decode: (val) => destr(decodeURIComponent(val)),
10
+ encode: (val) => encodeURIComponent(typeof val === "string" ? val : JSON.stringify(val))
11
+ };
12
+ const store = typeof window !== "undefined" ? window.cookieStore : void 0;
13
+ export function useCookies(name, _opts) {
14
+ const opts = { ...CookieDefaults, ..._opts };
15
+ opts.filter ??= (key) => key === name;
16
+ const cookies = readRawCookies(opts) || {};
17
+ let delay;
18
+ if (opts.maxAge !== void 0) {
19
+ delay = opts.maxAge * 1e3;
20
+ } else if (opts.expires) {
21
+ delay = opts.expires.getTime() - Date.now();
22
+ }
23
+ const hasExpired = delay !== void 0 && delay <= 0;
24
+ const shouldSetInitialClientCookie = hasExpired || cookies[name] === void 0 || cookies[name] === null;
25
+ const cookieValue = klona(hasExpired ? void 0 : cookies[name] ?? opts.default?.());
26
+ const cookie = delay && !hasExpired ? cookieRef(cookieValue, delay, opts.watch && opts.watch !== "shallow") : ref(cookieValue);
27
+ if (import.meta.env.MODE !== "production" && hasExpired) {
28
+ console.warn(`not setting cookie \`${name}\` as it has already expired.`);
29
+ }
30
+ let channel = null;
31
+ try {
32
+ if (!store && typeof BroadcastChannel !== "undefined") {
33
+ channel = new BroadcastChannel(`app:cookies:${name}`);
34
+ }
35
+ } catch {
36
+ }
37
+ const callback = (force = false) => {
38
+ if (!force && (opts.readonly || isEqual(cookie.value, cookies[name]))) {
39
+ return;
40
+ }
41
+ writeClientCookie(name, cookie.value, opts);
42
+ cookies[name] = klona(cookie.value);
43
+ channel?.postMessage({ value: opts.encode(cookie.value) });
44
+ };
45
+ const handleChange = (data) => {
46
+ const value = data.refresh ? readRawCookies(opts)?.[name] : opts.decode(data.value);
47
+ watchPaused = true;
48
+ cookie.value = value;
49
+ cookies[name] = klona(value);
50
+ nextTick(() => {
51
+ watchPaused = false;
52
+ });
53
+ };
54
+ let watchPaused = false;
55
+ const hasScope = !!getCurrentScope();
56
+ if (hasScope) {
57
+ onScopeDispose(() => {
58
+ watchPaused = true;
59
+ callback();
60
+ channel?.close();
61
+ });
62
+ }
63
+ if (store) {
64
+ const changeHandler = (event) => {
65
+ const changedCookie = event.changed.find((c) => c.name === name);
66
+ const removedCookie = event.deleted.find((c) => c.name === name);
67
+ if (changedCookie) {
68
+ handleChange({ value: changedCookie.value });
69
+ }
70
+ if (removedCookie) {
71
+ handleChange({ value: null });
72
+ }
73
+ };
74
+ store.addEventListener("change", changeHandler);
75
+ if (hasScope) {
76
+ onScopeDispose(() => store.removeEventListener("change", changeHandler));
77
+ }
78
+ } else if (channel) {
79
+ channel.onmessage = ({ data }) => handleChange(data);
80
+ }
81
+ if (opts.watch) {
82
+ watch(
83
+ cookie,
84
+ () => {
85
+ if (watchPaused) {
86
+ return;
87
+ }
88
+ callback();
89
+ },
90
+ { deep: opts.watch !== "shallow" }
91
+ );
92
+ }
93
+ if (shouldSetInitialClientCookie) {
94
+ callback(shouldSetInitialClientCookie);
95
+ }
96
+ return cookie;
97
+ }
98
+ function readRawCookies(opts = {}) {
99
+ return parse(document.cookie, opts);
100
+ }
101
+ function serializeCookie(name, value, opts = {}) {
102
+ if (value === null || value === void 0) {
103
+ return serialize(name, value, { ...opts, maxAge: -1 });
104
+ }
105
+ return serialize(name, value, opts);
106
+ }
107
+ function writeClientCookie(name, value, opts = {}) {
108
+ document.cookie = serializeCookie(name, value, opts);
109
+ }
110
+ const MAX_TIMEOUT_DELAY = 2147483647;
111
+ function cookieRef(value, delay, shouldWatch) {
112
+ let timeout;
113
+ let unsubscribe;
114
+ let elapsed = 0;
115
+ const internalRef = shouldWatch ? ref(value) : { value };
116
+ if (getCurrentScope()) {
117
+ onScopeDispose(() => {
118
+ unsubscribe?.();
119
+ clearTimeout(timeout);
120
+ });
121
+ }
122
+ return customRef((track, trigger) => {
123
+ if (shouldWatch) {
124
+ unsubscribe = watch(internalRef, trigger);
125
+ }
126
+ function createExpirationTimeout() {
127
+ elapsed = 0;
128
+ clearTimeout(timeout);
129
+ const timeRemaining = delay - elapsed;
130
+ const timeoutLength = Math.min(timeRemaining, MAX_TIMEOUT_DELAY);
131
+ timeout = setTimeout(() => {
132
+ elapsed += timeoutLength;
133
+ if (elapsed < delay) {
134
+ return createExpirationTimeout();
135
+ }
136
+ internalRef.value = void 0;
137
+ trigger();
138
+ }, timeoutLength);
139
+ }
140
+ return {
141
+ get() {
142
+ track();
143
+ return internalRef.value;
144
+ },
145
+ set(newValue) {
146
+ createExpirationTimeout();
147
+ internalRef.value = newValue;
148
+ trigger();
149
+ }
150
+ };
151
+ });
152
+ }
package/get-user.mjs CHANGED
@@ -16,7 +16,6 @@ async function getUserRequest(fetch, config) {
16
16
  }
17
17
  try {
18
18
  const apiActions = useApiActions();
19
- await apiActions.value?.getVisitorIdentifier?.();
20
19
  await apiActions.value?.refreshToken?.();
21
20
  } catch {
22
21
  flush();
package/get-visitor.mjs CHANGED
@@ -8,7 +8,7 @@ const setVisitor = (newVisitor) => {
8
8
  };
9
9
  const getVisitorRequest = async (config) => {
10
10
  const visitor = useVisitor();
11
- if (typeof window === "undefined" || visitor.value) {
11
+ if (visitor.value) {
12
12
  return;
13
13
  }
14
14
  const fp = await load();
package/index.mjs CHANGED
@@ -22,11 +22,7 @@ export function initApiFetch($fetch, config) {
22
22
  const initApplication = createInitApplication();
23
23
  const refreshToken = createApiRefreshToken(fetch, config);
24
24
  userActions = ref(createApiUserActions(fetch, config, getUser));
25
- apiActions.value = {
26
- initialized: true,
27
- getVisitorIdentifier,
28
- refreshToken
29
- };
25
+ apiActions.value = { getVisitorIdentifier, refreshToken };
30
26
  if (typeof window !== "undefined") {
31
27
  const loggedIn = useLocalStorage("lin", "no");
32
28
  const cometServerURL = config.cometServerURL;
@@ -45,7 +41,8 @@ export function initApiFetch($fetch, config) {
45
41
  }
46
42
  loggedIn.value = user ? "yes" : "no";
47
43
  });
48
- bus.subscribe("app:beforeMount", () => {
44
+ const subscription = bus.subscribe("app:beforeMount", () => {
45
+ subscription.unsubscribe();
49
46
  console.log("Service started in mode", import.meta.env.MODE);
50
47
  getVisitorIdentifier();
51
48
  initApplication();
@@ -5,7 +5,7 @@ import ruRU from "vant/es/locale/lang/ru-RU";
5
5
  import { watch } from "vue";
6
6
  import { useI18n } from "vue-i18n";
7
7
  import { useRouter } from "vue-router";
8
- import { useActiveSessions, useSubscribe, useUser } from "./composables/index.mjs";
8
+ import { useActiveSessions, useCookies, useSubscribe, useUser } from "./composables/index.mjs";
9
9
  import { once } from "./helpers/index.mjs";
10
10
  import { useAppLocale, useThemeMode, useUserActions, useVisitor } from "./index.mjs";
11
11
  function initApplication() {
@@ -62,6 +62,8 @@ function initApplication() {
62
62
  VantLocale.use(locale2, ruRU);
63
63
  VarletLocale.add("en-US", VarletLocale.enUS);
64
64
  }
65
+ const localeCookie = useCookies("locale", { maxAge: 60 * 60 * 24 * 365 });
66
+ localeCookie.value = locale2?.value;
65
67
  },
66
68
  { immediate: true }
67
69
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inzombieland/core",
3
- "version": "1.18.14",
3
+ "version": "1.18.16",
4
4
  "type": "module",
5
5
  "license": "ISC",
6
6
  "main": "./index.mjs",
@@ -14,7 +14,11 @@
14
14
  "@varlet/ui": "^3.10.5",
15
15
  "@vueuse/core": "^12.8.2",
16
16
  "centrifuge": "^5.3.4",
17
+ "cookie-es": "^2.0.0",
18
+ "destr": "^2.0.5",
19
+ "klona": "^2.0.6",
17
20
  "ofetch": "^1.4.1",
21
+ "ohash": "^2.0.11",
18
22
  "rxjs": "^7.8.2",
19
23
  "vant": "^4.9.19",
20
24
  "zod": "^3.24.2"