@friendofsvelte/state 0.0.1-dev

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/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # Persistent Svelte 5 State
2
+
3
+ A lightweight, type-safe state management solution for Svelte applications with built-in storage persistence.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Type-safe**: Full TypeScript support with automatic type inference
8
+ - 💾 **Persistent Storage**: Automatic state persistence in localStorage or sessionStorage
9
+ - 🪶 **Lightweight**: Zero dependencies beyond Svelte
10
+ - âš¡ **Reactive**: Seamless integration with Svelte's reactivity system
11
+ - 🔄 **Auto-sync**: Automatically syncs state across components
12
+ - 📦 **Simple API**: Just one function to manage all your state needs
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @friendofsvelte/state
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ 1. Define your types in your `app.d.ts`:
23
+
24
+ ```typescript
25
+ declare global {
26
+ interface PodTypeRegistry {
27
+ layout: {
28
+ bg: string;
29
+ };
30
+ userSettings: {
31
+ theme: 'light' | 'dark';
32
+ fontSize: number;
33
+ };
34
+ }
35
+ }
36
+
37
+ export {};
38
+ ```
39
+
40
+ 2. Use in your components:
41
+
42
+ ```svelte
43
+ <script lang="ts">
44
+ import { pod } from '@friendofsvelte/state';
45
+
46
+ // Initialize with value
47
+ let app = pod('layout', 'localStorage', {
48
+ bg: 'lightblue'
49
+ });
50
+
51
+ // Or use existing value
52
+ let settings = pod('userSettings');
53
+ </script>
54
+
55
+ <div style="background-color: {app.bg}">
56
+ <!-- Your content -->
57
+ </div>
58
+ ```
59
+
60
+ ## API Reference
61
+
62
+ ### `pod<K>(key: K, storage?: StorageType, context?: GetTypeFromRegistry<K>)`
63
+
64
+ Creates or retrieves a persistent state container.
65
+
66
+ Parameters:
67
+ - `key`: Unique identifier for the state container
68
+ - `storage`: (Optional) Storage type - 'localStorage' or 'sessionStorage' (default: 'localStorage')
69
+ - `context`: (Optional) Initial state value
70
+
71
+ Returns:
72
+ - A reactive state object of type `GetTypeFromRegistry<K>`
73
+
74
+ ## Type Safety
75
+
76
+ Pod State provides complete type safety through TypeScript. The global `PodTypeRegistry` interface allows you to define types for all your state containers in one place:
77
+
78
+ ```typescript
79
+ interface PodTypeRegistry {
80
+ layout: {
81
+ bg: string;
82
+ };
83
+ userSettings: {
84
+ theme: 'light' | 'dark';
85
+ fontSize: number;
86
+ };
87
+ }
88
+ ```
89
+
90
+ ## Examples
91
+
92
+ ### Basic Usage
93
+
94
+ ```svelte
95
+ <script lang="ts">
96
+ import { pod } from '@friendofsvelte/state';
97
+
98
+ let app = pod('layout', 'localStorage', {
99
+ bg: 'lightblue'
100
+ });
101
+ </script>
102
+
103
+ <button onclick={() => app.bg = 'lightgreen'}>
104
+ Change Background
105
+ </button>
106
+ ```
107
+
108
+ ### Shared State
109
+
110
+ ```svelte
111
+ <!-- ComponentA.svelte -->
112
+ <script>
113
+ import { pod } from '@friendofsvelte/state';
114
+ let settings = pod('userSettings');
115
+ </script>
116
+
117
+ <!-- ComponentB.svelte -->
118
+ <script>
119
+ import { pod } from '@friendofsvelte/state';
120
+ let settings = pod('userSettings');
121
+ // Will automatically sync with ComponentA
122
+ </script>
123
+ ```
124
+
125
+ ## Testing
126
+
127
+ Pod State includes a test suite to ensure reliability. Run tests with:
128
+
129
+ ```bash
130
+ npm test
131
+ ```
132
+
133
+ ## Contributing
134
+
135
+ Contributions are welcome! Please feel free to submit a Pull Request.
136
+
137
+ ## License
138
+
139
+ MIT License - see LICENSE file for details
@@ -0,0 +1 @@
1
+ export { pod } from './state.svelte';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // Reexport your entry components here
2
+ export { pod } from './state.svelte';
@@ -0,0 +1,16 @@
1
+ type StorageType = 'localStorage' | 'sessionStorage';
2
+ type TypeRegistry = {
3
+ [K in PropertyKey]: unknown;
4
+ };
5
+ declare global {
6
+ type PodTypeRegistry = TypeRegistry;
7
+ }
8
+ type GetTypeFromRegistry<K extends keyof PodTypeRegistry> = PodTypeRegistry[K] extends never ? unknown : PodTypeRegistry[K];
9
+ /**
10
+ * Get a persistent state from storage, or initialize with an optional context.
11
+ * @param key - The key to store the state.
12
+ * @param storage - The storage type to use.
13
+ * @param context - The initial state or override.
14
+ */
15
+ export declare function pod<K extends keyof PodTypeRegistry>(key: K, storage?: StorageType, context?: GetTypeFromRegistry<K>): GetTypeFromRegistry<K>;
16
+ export {};
@@ -0,0 +1,31 @@
1
+ import { untrack } from 'svelte';
2
+ function track(key, storage, context) {
3
+ let state = $state(context ?? {});
4
+ if (typeof window !== 'undefined') {
5
+ if (context === undefined) {
6
+ const storedValue = untrack(() => window[storage].getItem(String(key)));
7
+ if (storedValue) {
8
+ try {
9
+ state = JSON.parse(storedValue);
10
+ }
11
+ catch {
12
+ state = {};
13
+ }
14
+ }
15
+ }
16
+ $effect.pre(() => {
17
+ const json = JSON.stringify($state.snapshot(state));
18
+ window[storage].setItem(String(key), json);
19
+ });
20
+ }
21
+ return state;
22
+ }
23
+ /**
24
+ * Get a persistent state from storage, or initialize with an optional context.
25
+ * @param key - The key to store the state.
26
+ * @param storage - The storage type to use.
27
+ * @param context - The initial state or override.
28
+ */
29
+ export function pod(key, storage = 'localStorage', context) {
30
+ return track(key, storage, context);
31
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@friendofsvelte/state",
3
+ "version": "0.0.1-dev",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "preview": "vite preview",
8
+ "prepare": "svelte-kit sync || echo ''",
9
+ "prepack": "svelte-kit sync && svelte-package && publint",
10
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12
+ "format": "prettier --write .",
13
+ "lint": "prettier --check . && eslint .",
14
+ "test:unit": "vitest",
15
+ "test": "npm run test:unit -- --run"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "!dist/**/*.test.*",
20
+ "!dist/**/*.spec.*"
21
+ ],
22
+ "sideEffects": [
23
+ "**/*.css"
24
+ ],
25
+ "svelte": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "type": "module",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "svelte": "./dist/index.js"
32
+ }
33
+ },
34
+ "peerDependencies": {
35
+ "svelte": "^5.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/compat": "^1.2.5",
39
+ "@eslint/js": "^9.18.0",
40
+ "@sveltejs/adapter-auto": "^4.0.0",
41
+ "@sveltejs/kit": "^2.16.0",
42
+ "@sveltejs/package": "^2.0.0",
43
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
44
+ "@tailwindcss/vite": "^4.0.0",
45
+ "@testing-library/jest-dom": "^6.6.3",
46
+ "@testing-library/svelte": "^5.2.4",
47
+ "eslint": "^9.18.0",
48
+ "eslint-config-prettier": "^10.0.1",
49
+ "eslint-plugin-svelte": "^2.46.1",
50
+ "globals": "^15.14.0",
51
+ "jsdom": "^25.0.1",
52
+ "prettier": "^3.4.2",
53
+ "prettier-plugin-svelte": "^3.3.3",
54
+ "prettier-plugin-tailwindcss": "^0.6.11",
55
+ "publint": "^0.3.2",
56
+ "svelte": "^5.0.0",
57
+ "svelte-check": "^4.0.0",
58
+ "tailwindcss": "^4.0.0",
59
+ "typescript": "^5.0.0",
60
+ "typescript-eslint": "^8.20.0",
61
+ "vite": "^6.0.0",
62
+ "vitest": "^3.0.0"
63
+ }
64
+ }