@gluhar/core 6.0.0-next.1 → 6.0.0-next.4

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/CHANGELOG.md CHANGED
@@ -3,6 +3,33 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [6.0.0-next.4](https://github.com/gluharco/gluhar/compare/v6.0.0-next.3...v6.0.0-next.4) (2026-10-21)
7
+
8
+ **📝 Note:** Version bump only for package @gluhar/core
9
+
10
+
11
+
12
+
13
+
14
+ # [6.0.0-next.3](https://github.com/gluharco/gluhar/compare/v6.0.0-next.2...v6.0.0-next.3) (2026-10-21)
15
+
16
+ **📝 Note:** Version bump only for package @gluhar/core
17
+
18
+
19
+
20
+
21
+
22
+ # [6.0.0-next.2](https://github.com/gluharco/gluhar/compare/v6.0.0-next.1...v6.0.0-next.2) (2026-10-21)
23
+
24
+
25
+ ### 🩹 Fixes
26
+
27
+ - **build:** Publish real module builds from CI ([68adc79](https://github.com/gluharco/gluhar/commit/68adc794b3140a00eee6a30713ea2867505ed52c))
28
+
29
+
30
+
31
+
32
+
6
33
  # [6.0.0-next.1](https://github.com/gluharco/gluhar/compare/v6.0.0-next.0...v6.0.0-next.1) (2026-10-20)
7
34
 
8
35
 
@@ -0,0 +1,8 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface GluharCoreOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<GluharCoreOptions, GluharCoreOptions, false>;
6
+
7
+ export { _default as default };
8
+ export type { GluharCoreOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@gluhar/core",
3
+ "configKey": "gluharCore",
4
+ "version": "6.0.0-next.4",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.3",
7
+ "unbuild": "3.6.1"
8
+ }
9
+ }
@@ -0,0 +1,18 @@
1
+ import { defineNuxtModule, createResolver, installModule, addImportsDir } from '@nuxt/kit';
2
+
3
+ const module$1 = defineNuxtModule({
4
+ meta: {
5
+ name: "@gluhar/core",
6
+ configKey: "gluharCore"
7
+ },
8
+ // Default configuration options of the Nuxt module
9
+ defaults: {},
10
+ async setup() {
11
+ const { resolve } = createResolver(import.meta.url);
12
+ await installModule("@nuxtjs/device");
13
+ addImportsDir(resolve("runtime/composables"));
14
+ addImportsDir(resolve("runtime/utils"));
15
+ }
16
+ });
17
+
18
+ export { module$1 as default };
@@ -0,0 +1,3 @@
1
+ export declare const useClientOnly: () => {
2
+ isClient: import("vue").Ref<boolean, boolean>;
3
+ };
@@ -0,0 +1,8 @@
1
+ import { onMounted, ref } from "vue";
2
+ export const useClientOnly = () => {
3
+ const mounted = ref(false);
4
+ onMounted(() => {
5
+ mounted.value = true;
6
+ });
7
+ return { isClient: mounted };
8
+ };
@@ -0,0 +1,42 @@
1
+ import { type ComputedRef } from "vue";
2
+ import type { GluharBreakpoints } from "../types/index.js";
3
+ /**
4
+ * Viewport state for BEHAVIOUR — event handlers, GSAP/ScrollTrigger setup,
5
+ * imperative measurement. Never for layout: responsive layout is Tailwind
6
+ * variants in the template (`tablet:`, `desktop:`), which the server renders
7
+ * for every width with no JS and no hydration risk.
8
+ *
9
+ * Two kinds of signal, kept apart on purpose:
10
+ *
11
+ * - `isMobileDevice` — user-agent based, identical on server and client. The
12
+ * only one safe in `v-if` / `:class` / props. A device guess, not a width.
13
+ *
14
+ * - Width flags (`mobile`, `tablet`, `desktop`, `up("nav")`, …) — `false` on
15
+ * the server and through the first hydration, so the server render and the
16
+ * first client render agree by construction. They switch on in this
17
+ * composable's own `onMounted`, which Vue runs before any `onMounted` you
18
+ * register later in the same setup. Components created after hydration
19
+ * (client-side navigation, SPA mode) get live values from the first render.
20
+ *
21
+ * Breakpoints come from the project's CSS (`--breakpoint-*` in the main
22
+ * stylesheet's `@theme`, read at build time by @gluhar/theme), so JS and CSS
23
+ * cannot drift. Comparisons are `>=`, matching CSS `min-width`: at exactly the
24
+ * breakpoint width, `tablet:` applies and `tablet` is true.
25
+ */
26
+ export declare const useResponsive: () => {
27
+ isMobileDevice: boolean;
28
+ /** True once hydrated — for guarding client-only behaviour explicitly. */
29
+ mounted: import("vue").Ref<boolean, boolean>;
30
+ breakpoints: GluharBreakpoints;
31
+ up: (name: string) => ComputedRef<boolean>;
32
+ down: (name: string) => ComputedRef<boolean>;
33
+ between: (from: string, to: string) => ComputedRef<boolean>;
34
+ mobile: ComputedRef<boolean>;
35
+ tablet: ComputedRef<boolean>;
36
+ tabletExact: ComputedRef<boolean>;
37
+ desktop: ComputedRef<boolean>;
38
+ desktopExact: ComputedRef<boolean>;
39
+ wide: ComputedRef<boolean>;
40
+ /** Below desktop width. A width, not touch capability. */
41
+ touch: ComputedRef<boolean>;
42
+ };
@@ -0,0 +1,36 @@
1
+ import { computed, onMounted, ref } from "vue";
2
+ import { useBreakpoints } from "@vueuse/core";
3
+ import { useAppConfig, useDevice, useNuxtApp } from "#imports";
4
+ const DEFAULT_BREAKPOINTS = { tablet: 768, desktop: 1200, wide: 2e3 };
5
+ export const useResponsive = () => {
6
+ const nuxtApp = useNuxtApp();
7
+ const breakpoints = {
8
+ ...DEFAULT_BREAKPOINTS,
9
+ ...useAppConfig().gluhar?.breakpoints
10
+ };
11
+ const viewport = useBreakpoints(breakpoints);
12
+ const { isMobile: isMobileDevice } = useDevice();
13
+ const mounted = ref(import.meta.client && !nuxtApp.isHydrating);
14
+ if (!mounted.value) onMounted(() => mounted.value = true);
15
+ const gate = (source) => computed(() => mounted.value && source.value);
16
+ const up = (name) => gate(viewport.greaterOrEqual(name));
17
+ const down = (name) => gate(viewport.smaller(name));
18
+ const between = (from, to) => gate(viewport.between(from, to));
19
+ return {
20
+ isMobileDevice,
21
+ /** True once hydrated — for guarding client-only behaviour explicitly. */
22
+ mounted,
23
+ breakpoints,
24
+ up,
25
+ down,
26
+ between,
27
+ mobile: down("tablet"),
28
+ tablet: up("tablet"),
29
+ tabletExact: between("tablet", "desktop"),
30
+ desktop: up("desktop"),
31
+ desktopExact: between("desktop", "wide"),
32
+ wide: up("wide"),
33
+ /** Below desktop width. A width, not touch capability. */
34
+ touch: down("desktop")
35
+ };
36
+ };
@@ -0,0 +1,18 @@
1
+ import { breakpointsTailwind } from "@vueuse/core";
2
+ export type NonNegativeInteger<T extends number> = number extends T ? never : `${T}` extends `-${string}` | `${string}.${string}` ? never : T;
3
+ /** Tailwind's default screens (sm…2xl), still present in v4. */
4
+ export type Breakpoint = keyof typeof breakpointsTailwind;
5
+ /** Breakpoint name -> min-width in px, as declared in the project's CSS. */
6
+ export type GluharBreakpoints = Record<string, number>;
7
+ declare module "nuxt/schema" {
8
+ interface AppConfigInput {
9
+ gluhar?: {
10
+ breakpoints?: GluharBreakpoints;
11
+ };
12
+ }
13
+ interface AppConfig {
14
+ gluhar?: {
15
+ breakpoints?: GluharBreakpoints;
16
+ };
17
+ }
18
+ }
File without changes
@@ -0,0 +1,10 @@
1
+ export declare const capitalize: (s: string) => string;
2
+ export declare const envMode: () => "dev" | "prod";
3
+ /**
4
+ * Returns the base URL based on the environment mode.
5
+ *
6
+ * @param {string} baseUrl - The base URL to be used.
7
+ * @returns {string | undefined} - The base URL if the environment mode is "prod", otherwise undefined.
8
+ */
9
+ export declare const useBaseUrl: (baseUrl: string) => string | undefined;
10
+ export declare const asyncTimeout: (ms: number) => Promise<unknown>;
@@ -0,0 +1,6 @@
1
+ export const capitalize = (s) => s && s[0].toUpperCase() + s.slice(1);
2
+ export const envMode = () => process.env.NODE_ENV === "development" ? "dev" : "prod";
3
+ export const useBaseUrl = (baseUrl) => {
4
+ return envMode() === "prod" ? baseUrl : void 0;
5
+ };
6
+ export const asyncTimeout = (ms) => new Promise((res) => setTimeout(res, ms));
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Evaluates a project config file (e.g. `config/i18n.config.ts`) at build time.
3
+ *
4
+ * Relative paths resolve against `rootDir` — pass `nuxt.options.rootDir`.
5
+ * `process.cwd()` is only the fallback: it is wrong whenever Nuxt is started
6
+ * from another directory (`nuxi dev playground`, monorepos, `--cwd`).
7
+ */
8
+ export declare const readModule: <T extends Record<string, any>>(path: string | undefined, options?: {
9
+ rootDir?: string;
10
+ default?: boolean;
11
+ }) => Promise<T>;
12
+ /**
13
+ * True during a module package's own `nuxt-module-build prepare`: rootDir is the package
14
+ * (`src/module.ts`, no `nuxt.config`), not a project, so there is no `config/` or `lang/` to read.
15
+ * Setup that needs project files must be skipped then; registering imports and components is fine.
16
+ */
17
+ export declare const isModulePrepare: (nuxt: {
18
+ options: {
19
+ _prepare?: boolean;
20
+ rootDir: string;
21
+ };
22
+ }) => boolean;
@@ -0,0 +1,17 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { isAbsolute, join } from "path";
3
+ import { evalModule } from "mlly";
4
+ export const readModule = async (path, options = {}) => {
5
+ if (!path) throw new Error("[@gluhar/core] readModule | No path provided.");
6
+ const p = isAbsolute(path) ? path : join(options.rootDir ?? process.cwd(), path);
7
+ const file = readFileSync(p)?.toString();
8
+ if (!file)
9
+ throw new Error("[@gluhar/core] readModule | File not found on path: " + p);
10
+ const sanitizedFile = file.replaceAll(" as const", "");
11
+ const module = await evalModule(sanitizedFile);
12
+ return options.default ? module.default : module;
13
+ };
14
+ export const isModulePrepare = (nuxt) => {
15
+ const { _prepare, rootDir } = nuxt.options;
16
+ return !!_prepare && existsSync(join(rootDir, "src/module.ts")) && !["ts", "js", "mjs"].some((ext) => existsSync(join(rootDir, `nuxt.config.${ext}`)));
17
+ };
@@ -0,0 +1,6 @@
1
+ import type { NonNegativeInteger } from "../types/index.js";
2
+ export declare const getRandomInt: (max?: number) => number;
3
+ export declare const getRandomBetween: (min: number, max: number) => number;
4
+ export declare const getRandomDigits: <N extends number>(count: NonNegativeInteger<N>) => number;
5
+ export declare const getRandomHex: <N extends number>(count?: NonNegativeInteger<N>) => string;
6
+ export declare const getUuid: () => string;
@@ -0,0 +1,5 @@
1
+ export const getRandomInt = (max = 100) => Math.floor(Math.random() * max);
2
+ export const getRandomBetween = (min, max) => getRandomInt(max - min + 1) + min;
3
+ export const getRandomDigits = (count) => getRandomBetween(9 * 10 ** (count - 1), 10 ** (count - 1));
4
+ export const getRandomHex = (count) => [...Array(count || 6)].map(() => getRandomBetween(0, 15).toString(16)).join("");
5
+ export const getUuid = () => `huuid-${getRandomHex()}-${getRandomHex()}-${getRandomHex()}`;
@@ -0,0 +1,2 @@
1
+ export * from "./generators.js";
2
+ export * from "./common.js";
@@ -0,0 +1,2 @@
1
+ export * from "./generators.js";
2
+ export * from "./common.js";
@@ -0,0 +1,9 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module.mjs'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module.mjs'
8
+
9
+ export { type GluharCoreOptions } from './module.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gluhar/core",
3
- "version": "6.0.0-next.1",
3
+ "version": "6.0.0-next.4",
4
4
  "description": "Gluhar Core packages.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,25 +39,24 @@
39
39
  "test:watch": "vitest watch"
40
40
  },
41
41
  "dependencies": {
42
- "@nuxt/kit": "^4.5.0",
43
- "@nuxtjs/device": "^3.2.2",
44
- "@vueuse/core": "^14.1.0",
42
+ "@nuxt/kit": "^4.6.2",
43
+ "@nuxtjs/device": "^4.0.0",
44
+ "@vueuse/core": "^15.0.0",
45
45
  "mlly": "^1.7.1"
46
46
  },
47
47
  "devDependencies": {
48
- "@nuxt/devtools": "latest",
49
48
  "@nuxt/eslint-config": "^1.9.0",
50
49
  "@nuxt/module-builder": "^1.0.3",
51
- "@nuxt/schema": "^4.5.0",
52
- "@nuxt/test-utils": "^3.19.2",
50
+ "@nuxt/schema": "^4.6.2",
51
+ "@nuxt/test-utils": "^4.3.4",
53
52
  "@types/node": "^22.5.4",
54
53
  "changelogen": "^0.5.5",
55
54
  "copyfiles": "^2.4.1",
56
55
  "eslint": "^9.10.0",
57
- "nuxt": "^4.5.0",
58
- "vitest": "^3.2.4"
56
+ "nuxt": "^4.6.2",
57
+ "vitest": "^5.0.5"
59
58
  },
60
59
  "peerDependencies": {
61
- "nuxt": "^4.5.0"
60
+ "nuxt": "^4.6.2"
62
61
  }
63
62
  }