@vinicunca/taman-core

GitHubnpm
Foundation layer — utils, constants, color, cache, store, typings, composables, and preferences.

Version 0.1.0. ESM only. Peer: vue ^3.5; optional peer vue-router ^5 (for ./typings).

pnpm add @vinicunca/taman-core vue

There is no root export. Import a subpath.

With skipLibCheck: false, you also need @types/web-bluetooth, vue-component-type-helpers, and ESNext in lib (for Temporal) because of @vueuse/core and akar — not because of taman-core itself.

@vinicunca/taman-core/utils

DOM, tree, date, diff, download, merge, nprogress, codecs, window helpers. Re-exports all of @vinicunca/perkakas plus get / set from es-toolkit/compat.

Notable functions (signatures from source):

formatDate(time?: FormatDate | null, format?: Format /* default 'YYYY-MM-DD' */): string
formatDateTime(time?: FormatDate | null): string
getSystemTimezone(): string
setCurrentTimezone(timezone?: string): void
getCurrentTimezone(): string
getTimezoneOptions(locale?: string): Array<TimezoneOption>

getElementVisibleRect(element?: HTMLElement | null): VisibleDomRect
getScrollbarWidth(): number
getLayoutScrollElement(): HTMLElement | null
triggerWindowResize(): void

applyCssVariables(vars: Record<string, string>, el?: HTMLElement): void
downloadFileFromUrl({ fileName, source }): Promise<void>
downloadFileFromBase64({ fileName, source }): void
startProgress(): void
stopProgress(): void
openWindow(url: string, options?): Window | null
openRouteInNewWindow(path: string): void

to<T, U = Error>(promise: Promise<T>): Promise<[U, undefined] | [null, T]>
bindMethods<T extends object>(instance: T): void
createStack<T>(dedup?: boolean, maxSize?: number): Stack<T>
uniqueByField<T>(list: T[], field: keyof T): T[]

createCalendarDateCodec(options?: CalendarDateCodecOptions)
createTimeCodec()
encodeCalendarDateValues / decodeCalendarDateValues
diff / arraysEqual
mergeWithArrayOverride / defu / createMerge

@vinicunca/taman-core/constants

TAMAN_GITHUB_URL; // 'https://github.com/vinicunca/taman'
TAMAN_DOC_URL; // 'https://taman.vinicunca.dev' — docs now live at vinicunca.dev/taman

CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT; // '--taman-content-height'
CSS_VARIABLE_LAYOUT_CONTENT_WIDTH;
CSS_VARIABLE_LAYOUT_HEADER_HEIGHT;
CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT;
CSS_VARIABLE_LAYOUT_VIEWPORT_HEIGHT;
ELEMENT_ID_MAIN_CONTENT; // '__taman_main_content'
ELEMENT_ID_LAYOUT_SCROLL;
DISMISSABLE_DIALOG_ID;
DISMISSABLE_DRAWER_ID;
Z_INDEX_OVERLAY_BASE; // 1000

@vinicunca/taman-core/color

import { colordx, convertToHsl, convertToHslCssVar, convertToRgb, generatorColorVariables, isValidColor } from '@vinicunca/taman-core/color';

generatorColorVariables([{ name: 'primary', color: '#3b82f6' }]);
// → { '--taman-color-primary-500': 'oklch(...)', '--taman-color-primary': '...', ... }

colordx is @colordx/core with the mix plugin. convertToRgb strips deg|grad|rad|turn before TinyColor parse.

@vinicunca/taman-core/cache

StorageManager + drivers. Prefix isolation and TTL live on the manager; drivers are pure KV.

import {
  StorageManager,
  LocalStorageDriver,
  IndexedDBDriver,
  MemoryStorageDriver,
} from '@vinicunca/taman-core/cache';

const cache = new StorageManager({ prefix: 'myapp' });
// StorageManager({ driver?: IStorageDriver, prefix?: string })
// Default driver: LocalStorageDriver in the browser, MemoryStorageDriver on Node / if localStorage throws.

await cache.setItem(key, value, ttlMs?)
await cache.getItem<T>(key, defaultValue?)   // expired → default, item removed
await cache.removeItem(key)
await cache.clear()            // keys with this prefix only
await cache.clearExpiredItems()
await cache.keys()             // prefix stripped
cache.getFullKey(key)

Empty prefix + LocalStorageDriver logs a warning: clear() / keys() would touch all of localStorage.

The in-repo src/cache/README.md is a leftover bilingual/garbled draft. Trust this page and the TypeScript source.

@vinicunca/taman-core/store

Re-exports @tanstack/vue-store (Store, useSelector, …). Used by preferences, forms, and dialog APIs.

@vinicunca/taman-core/global-state

Singleton for cross-package UI pieces — not request-scoped user data.

globalShareState.setComponents({ ... })
globalShareState.getComponents()
globalShareState.defineMessage({ copyPreferencesSuccess?: (title, content?) => void })
globalShareState.getMessage()

@vinicunca/taman-core/typings

Menu, tab, layout, and RouteMeta augmentation for vue-router. Importing this module (or listing it in compilerOptions.types) adds Taman fields to RouteMeta. See Permissions for authority / auth / TamanRoleRegistry.

@vinicunca/taman-core/composables

useBreakpoints()           // VueUse Tailwind breakpoints; isMobile = smaller('md')
useLayoutContentStyle()    // contentElement, overlayStyle
useLayoutHeaderStyle()     // get/setLayoutHeaderHeight
useLayoutFooterStyle()     // get/setLayoutFooterHeight
useLayoutViewportHeight()  // writes --taman-viewport-height only when dvh is unsupported
useOverlayZIndex(isOpen)   // Ref<number | undefined>
usePriorityValue(key, props, state)
usePriorityValues / useForwardPriorityValues
useScrollLock({ immediate?: boolean })  // default immediate true; SCROLL_FIXED_CLASS
useSimpleLocale()          // { $t, currentLocale, setSimpleLocale }  locales: en-US, …
useSortable(el, options?)  // { initializeSortable(): Promise<Sortable> }

Also re-exports from akar: useEmitAsProps, useForwardExpose, useForwardProps, useForwardPropsEmits.

@vinicunca/taman-core/preferences

See Preferences.

initPreferences({ namespace: string, overrides?: DeepPartial<Preferences> }): Promise<void>
updatePreferences(partial: DeepPartial<Preferences>): void
resetPreferences(): void
clearCache(): Promise<void>
getPreferences(): Preferences          // readonly reactive
preferences                            // same object as getPreferences() at module init
defineOverridesPreferences(partial)
usePreferences()
preferencesManager                     // PreferenceManager instance

initPreferences is a no-op if already initialized. Merge order: overrides over defaultPreferences; cache fills unset fields only.