npm package: @jaiswald159/shared-settings-universal
Description: A universal shared settings library that works with both Vue 2 and Vue 3
Author: Deepak Jaiswal
Latest version: 1.0.1

# @jaiswald159/shared-settings-universal

A universal shared settings library that works with **both Vue 2 and Vue 3** applications. This library provides a centralized store to manage application settings such as language preferences, themes, and site-specific configurations.

## ✨ Features

- 🔄 **Universal Compatibility**: Works with both Vue 2 and Vue 3
- 📘 **JavaScript & TypeScript**: Separate builds for both JS and TS projects
- 🎯 **Framework Agnostic Core**: Core logic works without any framework
- 💾 **Persistent Storage**: Automatically saves to localStorage
- 🔌 **Flexible Integration**: Works with Pinia (Vue 3), Vuex (Vue 2), or standalone
- 📦 **Lightweight**: Minimal dependencies
- 🎨 **CSS Included**: Optional global styles

---

## 📦 Installation

```bash
npm install @jaiswald159/shared-settings-universal
```

### Peer Dependencies

The library works with Vue 2 or Vue 3. Install the appropriate version:

**For Vue 3:**
```bash
npm install vue@^3.0.0
# Optional: for Pinia integration
npm install pinia pinia-plugin-persistedstate
```

**For Vue 2:**
```bash
npm install vue@^2.6.0
# Optional: for Vuex integration
npm install vuex
```

---

## 🚀 Usage

> **Note**: This library supports both **JavaScript** and **TypeScript**. Use the appropriate import path based on your project:
> - JavaScript: `/vue2`, `/vue3`, `/core`
> - TypeScript: `/vue2-ts`, `/vue3-ts`, `/core-ts`
>
> See [JS_TS_SUPPORT.md](./JS_TS_SUPPORT.md) for detailed information.

### Vue 3 with Composition API (TypeScript)

```typescript
import { useSettingsStoreVue3 } from '@jaiswald159/shared-settings-universal/vue3-ts';

// Optional: App store that provides site ID
const useAppStore = () => ({
  getApplicationData: (key: string) => {
    if (key === 'loggedSiteID') return 'site-123';
    return null;
  }
});

// Create settings store
const settingsStore = useSettingsStoreVue3('my-app-settings', useAppStore);

// Update settings
settingsStore.UPDATE_SETTINGS({
  siteID: 'site-123',
  theme: 'dark',
  language: 'en',
  notifications: true
});

// Get settings for current site
const currentSettings = settingsStore.GET_SETTINGS();
console.log(currentSettings); // { siteID: 'site-123', theme: 'dark', ... }

// Get all settings
const allSettings = settingsStore.GET_ALL_SETTINGS();

// Clear all settings
settingsStore.CLEAR_SETTINGS();
```

### Vue 3 with Composition API (JavaScript)

```javascript
import { useSettingsStoreVue3 } from '@jaiswald159/shared-settings-universal/vue3';

// Create settings store
const settingsStore = useSettingsStoreVue3('my-app-settings');

// Update settings
settingsStore.UPDATE_SETTINGS({
  siteID: 'site-123',
  theme: 'dark',
  language: 'en'
});

// Get settings
const currentSettings = settingsStore.GET_SETTINGS();
```

### Vue 3 with Pinia (TypeScript)

```typescript
import { createPiniaSettingsStore } from '@jaiswald159/shared-settings-universal/vue3-ts';

const useAppStore = () => ({
  getApplicationData: (key: string) => {
    if (key === 'loggedSiteID') return 'site-123';
    return null;
  }
});

// Create Pinia store (requires pinia to be installed)
const settingsStore = createPiniaSettingsStore('my-app-settings', useAppStore);

// Use like any Pinia store
settingsStore.UPDATE_SETTINGS({
  siteID: 'site-123',
  theme: 'dark'
});

const settings = settingsStore.GET_SETTINGS();
```

### Vue 2 with Options API (TypeScript)

```typescript
import { useSettingsStoreVue2 } from '@jaiswald159/shared-settings-universal/vue2-ts';

export default {
  data() {
    const useAppStore = () => ({
      getApplicationData: (key) => {
        if (key === 'loggedSiteID') return this.currentSiteId;
        return null;
      }
    });

    const settingsStore = useSettingsStoreVue2('my-app-settings', useAppStore);

    return {
      settingsStore
    };
  },
  methods: {
    saveSettings() {
      this.settingsStore.UPDATE_SETTINGS({
        siteID: this.currentSiteId,
        theme: 'dark',
        language: 'en'
      });
    },
    loadSettings() {
      const settings = this.settingsStore.GET_SETTINGS();
      console.log(settings);
    }
  }
};
```

### Vue 2 with Options API (JavaScript)

```javascript
import { useSettingsStoreVue2 } from '@jaiswald159/shared-settings-universal/vue2';

export default {
  data() {
    return {
      settingsStore: useSettingsStoreVue2('my-app-settings')
    };
  },
  methods: {
    saveSettings() {
      this.settingsStore.UPDATE_SETTINGS({
        siteID: 'site-123',
        theme: 'dark'
      });
    }
  }
};
```

### Vue 2 with Vuex (TypeScript)

```typescript
import { createVuexSettingsModule } from '@jaiswald159/shared-settings-universal/vue2-ts';
import Vuex from 'vuex';

const useAppStore = () => ({
  getApplicationData: (key) => {
    if (key === 'loggedSiteID') return 'site-123';
    return null;
  }
});

const store = new Vuex.Store({
  modules: {
    settings: createVuexSettingsModule('my-app-settings', useAppStore)
  }
});

// Usage in component
this.$store.dispatch('settings/updateSettings', {
  siteID: 'site-123',
  theme: 'dark'
});

const settings = this.$store.getters['settings/getSettings']();
```

### Vue 2 Global Plugin (JavaScript)

```javascript
import Vue from 'vue';
import { Vue2SettingsPlugin } from '@jaiswald159/shared-settings-universal/vue2';

Vue.use(Vue2SettingsPlugin, {
  storeKey: 'my-app-settings',
  useAppStore: () => ({
    getApplicationData: (key) => {
      if (key === 'loggedSiteID') return 'site-123';
      return null;
    }
  })
});

// Now available in all components as this.$settingsStore
export default {
  mounted() {
    this.$settingsStore.UPDATE_SETTINGS({
      siteID: 'site-123',
      theme: 'dark'
    });
  }
};
```

### Framework-Agnostic Usage

```typescript
import { SettingsManager } from '@jaiswald159/shared-settings-universal';

// Create a settings manager instance
const manager = new SettingsManager('my-app-settings', () => 'site-123');

// Update settings
manager.updateSettings({
  siteID: 'site-123',
  theme: 'dark',
  language: 'en'
});

// Get settings
const settings = manager.getSettings();

// Subscribe to changes
const unsubscribe = manager.subscribe((newSettings) => {
  console.log('Settings updated:', newSettings);
});

// Later...
unsubscribe();
```

---

## 📚 API Reference

### Common Methods

All implementations provide these methods:

#### `UPDATE_SETTINGS(data: Setting): void`
Update settings for a specific site. Requires `siteID` in the data object.

#### `GET_SETTINGS(): Setting | false`
Get settings for the current site (based on the app store's logged site ID).

#### `GET_ALL_SETTINGS(): Setting[]`
Get all settings for all sites.

#### `GET_SETTINGS_BY_SITE_ID(siteID: string): Setting | false`
Get settings for a specific site ID.

#### `CLEAR_SETTINGS(): void`
Clear all settings from the store and localStorage.

#### `REMOVE_SETTINGS_BY_SITE_ID(siteID: string): void`
Remove settings for a specific site.

### TypeScript Types

```typescript
interface Setting {
  siteID: string;
  [key: string]: any; // Any additional properties
}

interface AppStore {
  getApplicationData: (key: string) => any;
}
```

---

## 🎨 CSS Styles

The library includes optional global CSS styles. Import them if needed:

```typescript
import '@jaiswald159/shared-settings-universal/global.css';
```

The CSS defines CSS variables:
```css
:root {
  --settings-primary-color: #007bff;
  --settings-secondary-color: #6c757d;
  --settings-success-color: #28a745;
  --settings-danger-color: #dc3545;
  --settings-warning-color: #ffc107;
  --settings-info-color: #17a2b8;
}
```

---

## 🔧 Build & Development

```bash
# Install dependencies
npm install

# Build the library
npm run build

# Development mode
npm run dev
```

---

## 📝 Examples

### Multi-site Application

```typescript
import { useSettingsStoreVue3 } from '@jaiswald159/shared-settings-universal';

const useAppStore = () => ({
  getApplicationData: (key: string) => {
    if (key === 'loggedSiteID') {
      // Get current site from your auth system
      return localStorage.getItem('currentSiteID');
    }
    return null;
  }
});

const settingsStore = useSettingsStoreVue3('app-settings', useAppStore);

// Save settings for Site A
settingsStore.UPDATE_SETTINGS({
  siteID: 'site-a',
  theme: 'dark',
  language: 'en'
});

// Save settings for Site B
settingsStore.UPDATE_SETTINGS({
  siteID: 'site-b',
  theme: 'light',
  language: 'es'
});

// Get settings for current site (whichever is logged in)
const currentSettings = settingsStore.GET_SETTINGS();

// Get specific site settings
const siteASettings = settingsStore.GET_SETTINGS_BY_SITE_ID('site-a');
```

---

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

---

## 📄 License

MIT © Deepak Jaiswal

---

## 🆚 Comparison with @jaiswald159/shared-settings

| Feature | shared-settings | shared-settings-universal |
|---------|----------------|---------------------------|
| Vue 3 Support | ✅ | ✅ |
| Vue 2 Support | ❌ | ✅ |
| Pinia Integration | ✅ | ✅ |
| Vuex Integration | ❌ | ✅ |
| Framework Agnostic Core | ❌ | ✅ |
| Multiple Site Support | ✅ | ✅ |
| LocalStorage Persistence | ✅ | ✅ |

---

## ❓ FAQ

**Q: Can I use this with Nuxt 2?**  
A: Yes! Use the Vue 2 implementation with Nuxt 2.

**Q: Can I use this with Nuxt 3?**  
A: Yes! Use the Vue 3 implementation with Nuxt 3.

**Q: Do I need Pinia or Vuex?**  
A: No, they are optional. The library works standalone, but provides integration helpers if you're already using them.

**Q: Will my settings persist across page refreshes?**  
A: Yes, settings are automatically saved to localStorage.

**Q: Can I use this in a non-Vue project?**  
A: Yes! Use the framework-agnostic `SettingsManager` class directly.