zenon 0.1.0 β†’ 1.1.0

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 CHANGED
@@ -1,23 +1,64 @@
1
+ <h1 align="center">
2
+ <br>
3
+ <img src="https://github.com/ljlm0402/zenon/raw/images/logo.png" alt="Project Logo" width="800" />
4
+ <br>
5
+ <br>
6
+ zenon
7
+ <br>
8
+ </h1>
9
+
10
+ <h4 align="center">πŸ¦‰ A minimalist, Zustand-inspired state manager for <b>Vue 3</b></h4>
11
+
12
+ <p align ="center">
13
+ <a href="https://nodei.co/npm/zenon" target="_blank">
14
+ <img src="https://nodei.co/npm/zenon.png" alt="npm Info" />
15
+ </a>
16
+
17
+ </p>
18
+
1
19
  <p align="center">
2
- <img width="800" src="https://github.com/ljlm0402/zenon/raw/images/logo.png" alt="zenon logo" />
20
+ <a href="http://npm.im/zenon" target="_blank">
21
+ <img src="https://img.shields.io/npm/v/zenon.svg" alt="npm Version" />
22
+ </a>
23
+ <a href="http://npm.im/zenon" target="_blank">
24
+ <img src="https://img.shields.io/github/v/release/ljlm0402/zenon" alt="npm Release Version" />
25
+ </a>
26
+ <a href="http://npm.im/zenon" target="_blank">
27
+ <img src="https://img.shields.io/npm/dm/zenon.svg" alt="npm Downloads" />
28
+ </a>
29
+ <a href="http://npm.im/zenon" target="_blank">
30
+ <img src="https://img.shields.io/npm/l/zenon.svg" alt="npm Package License" />
31
+ </a>
3
32
  </p>
4
33
 
5
- <h1 align="center">Zenon</h1>
6
- <p align="center">A minimalist, Zustand-inspired state manager for <b>Vue 3</b></p>
34
+ <p align="center">
35
+ <a href="https://github.com/ljlm0402/zenon/stargazers" target="_blank">
36
+ <img src="https://img.shields.io/github/stars/ljlm0402/zenon" alt="github Stars" />
37
+ </a>
38
+ <a href="https://github.com/ljlm0402/zenon/network/members" target="_blank">
39
+ <img src="https://img.shields.io/github/forks/ljlm0402/zenon" alt="github Forks" />
40
+ </a>
41
+ <a href="https://github.com/ljlm0402/zenon/stargazers" target="_blank">
42
+ <img src="https://img.shields.io/github/contributors/ljlm0402/zenon" alt="github Contributors" />
43
+ </a>
44
+ <a href="https://github.com/ljlm0402/zenon/issues" target="_blank">
45
+ <img src="https://img.shields.io/github/issues/ljlm0402/zenon" alt="github Issues" />
46
+ </a>
47
+ </p>
7
48
 
8
49
  ---
9
50
 
10
51
  ## ✨ Features
11
52
 
12
- - πŸƒ <b>Vue 3</b> Composition API μ „μš©
13
- - ⚑️ <b>Zustand와 거의 λ™μΌν•œ DX</b>: set/get/selector λͺ¨λ‘ 지원
14
- - πŸ§‘β€πŸ’» <b>TypeScript μΉœν™”μ </b>: νƒ€μž… μΆ”λ‘ /뢄리/μ•‘μ…˜ λͺ¨λ‘ 쉬움
15
- - πŸš€ <b>μ΄ˆκ²½λŸ‰ & μ‹¬ν”Œ</b>: 1-file store, λŸ¬λ‹μ»€λΈŒ ZERO
16
- - 🧩 <b>뢀뢄ꡬ독(Selector)</b> 지원, μ»΄ν¬λ„ŒνŠΈλ³„ μ΅œμ ν™” OK
17
-
18
- ---
53
+ - πŸƒ **Vue 3** Composition API only
54
+ - ⚑️ **Almost identical DX to Zustand**: supports set/get/selector, middleware composition
55
+ - πŸ§‘β€πŸ’» **TypeScript friendly**: easy type inference, separation, and actions
56
+ - πŸš€ **Lightweight & simple**: true 1-file store, ZERO learning curve
57
+ - 🧩 **Selector-based partial subscription** supported for optimal component performance
58
+ - 🧩 **Pluggable middleware support** (Logger, Persist, ... with compose or chain)
59
+ - πŸ—‚ **Full npm-style import/usage** (`import ... from "zenon"`, `"zenon/plugins"`, etc.)
19
60
 
20
- ## πŸ“¦ μ„€μΉ˜
61
+ ## πŸ’Ύ Installation
21
62
 
22
63
  ```bash
23
64
  pnpm add zenon
@@ -27,31 +68,38 @@ npm install zenon
27
68
  yarn add zenon
28
69
  ```
29
70
 
30
- ---
31
-
32
- ## ⚑️ κΈ°λ³Έ μ‚¬μš©λ²•
71
+ ## πŸ“ Usage Example
33
72
 
34
73
  ```ts
35
74
  // stores/counter.ts
36
- import { createStore } from "zenon";
75
+ import { createStore, compose } from "zenon";
76
+ import { withLogger, withPersist } from "zenon/plugins";
37
77
 
38
- type State = { count: number };
39
- type Actions = {
78
+ type CounterState = { count: number };
79
+ type CounterActions = {
40
80
  increase: () => void;
41
81
  reset: () => void;
42
82
  };
43
83
 
84
+ const STORE_KEY = "zenon-counter";
85
+
86
+ // Compose DX
44
87
  export const useCounter = () =>
45
- createStore<State & Actions>((set, get) => ({
46
- count: 0,
47
- increase: () => set({ count: get().count + 1 }),
48
- reset: () => set({ count: 0 }),
49
- }));
88
+ createStore(
89
+ compose(
90
+ withLogger({ store: "counter", timestamp: true, expanded: true }),
91
+ withPersist<CounterState & CounterActions>(STORE_KEY, {
92
+ storage: window.sessionStorage,
93
+ })
94
+ )((set, get) => ({
95
+ count: 0,
96
+ increase: () => set({ count: get().count + 1 }, "increase"),
97
+ reset: () => set({ count: 0 }, "reset"),
98
+ }))
99
+ );
50
100
  ```
51
101
 
52
- ---
53
-
54
- ## 🎯 μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©
102
+ ## 🎯 Comoponents Usage
55
103
 
56
104
  ```vue
57
105
  <template>
@@ -71,40 +119,54 @@ const { increase, reset } = store;
71
119
  </script>
72
120
  ```
73
121
 
74
- ---
122
+ ## 🧩 Middleware (Logger, Persist)
75
123
 
76
- ## 🚦 Selector둜 λΆ€λΆ„ ꡬ독
124
+ - Compose or chain multiple plugins
125
+
126
+ - Plugin entry: zenon/plugins
77
127
 
78
128
  ```ts
79
- const store = useCounter();
80
- const count = store.useSelector((s) => s.count); // count만 λ°˜μ‘
81
- const double = store.useSelector((s) => s.count * 2); // νŒŒμƒκ°’λ„ OK
82
- ```
129
+ import { createStore, compose } from "zenon";
130
+ import { withLogger, withPersist } from "zenon/plugins";
83
131
 
84
- ---
132
+ // Compose style
133
+ export const useCounter = () =>
134
+ createStore(
135
+ compose(
136
+ withLogger({ store: "counter" }),
137
+ withPersist("counter")
138
+ )((set, get) => ({
139
+ count: 0,
140
+ increase: () => set({ count: get().count + 1 }, "increase"),
141
+ reset: () => set({ count: 0 }, "reset"),
142
+ }))
143
+ );
144
+
145
+ // Or chain style
146
+ export const useCounter = () =>
147
+ createStore(
148
+ withLogger({ store: "counter" })(
149
+ withPersist("counter")((set, get) => ({
150
+ count: 0,
151
+ increase: () => set({ count: get().count + 1 }, "increase"),
152
+ reset: () => set({ count: 0 }, "reset"),
153
+ }))
154
+ )
155
+ );
156
+ ```
85
157
 
86
- ## πŸ§‘β€πŸ’» νƒ€μž… 뢄리 μ˜ˆμ‹œ
158
+ ## 🚦 Partial Subscription with Selector
87
159
 
88
160
  ```ts
89
- type UserState = { name: string; age: number };
90
- type UserActions = { setName: (name: string) => void };
91
-
92
- export const useUser = () =>
93
- createStore<UserState & UserActions>((set, get) => ({
94
- name: "아ꡬλͺ¬",
95
- age: 32,
96
- setName: (name) => set({ name }),
97
- }));
161
+ const store = useCounter();
162
+ const count = store.useSelector((s) => s.count); // Subscribe only to count
163
+ const double = store.useSelector((s) => s.count * 2); // Derived value is also OK
98
164
  ```
99
165
 
100
- ---
101
-
102
166
  ## πŸ“š License
103
167
 
104
168
  MIT
105
169
 
106
- ---
107
-
108
170
  ## ⭐️ Star & Contribute
109
171
 
110
- 아이디어, PR, ν”Όλ“œλ°± λͺ¨λ‘ ν™˜μ˜ν•©λ‹ˆλ‹€!
172
+ Ideas, PRs, and feedback are all welcome!
@@ -0,0 +1,14 @@
1
+ // src/utils/compose.ts
2
+ function compose(...funcs) {
3
+ if (funcs.length === 0)
4
+ return (arg) => arg;
5
+ if (funcs.length === 1)
6
+ return funcs[0];
7
+ return funcs.reduce(
8
+ (a, b) => (...args) => a(b(...args))
9
+ );
10
+ }
11
+
12
+ export {
13
+ compose
14
+ };
@@ -0,0 +1,35 @@
1
+ // src/plugins/withPersist.ts
2
+ function withPersist(key, options = {}) {
3
+ const storage = options.storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
4
+ return (initializer) => (set, get) => {
5
+ let initial = {};
6
+ if (storage) {
7
+ const saved = storage.getItem(key);
8
+ if (saved) {
9
+ try {
10
+ initial = { ...JSON.parse(saved) };
11
+ } catch {
12
+ initial = {};
13
+ }
14
+ }
15
+ }
16
+ const persistSet = (updater, actionName) => {
17
+ set(updater, actionName);
18
+ if (storage) {
19
+ try {
20
+ storage.setItem(key, JSON.stringify(get()));
21
+ } catch {
22
+ }
23
+ }
24
+ };
25
+ const store = initializer(persistSet, get);
26
+ Object.assign(store, initial);
27
+ if (storage)
28
+ storage.setItem(key, JSON.stringify(store));
29
+ return store;
30
+ };
31
+ }
32
+
33
+ export {
34
+ withPersist
35
+ };
@@ -0,0 +1,51 @@
1
+ // src/plugins/withLogger.ts
2
+ function pickValuesOnly(obj) {
3
+ const result = {};
4
+ for (const key in obj) {
5
+ if (typeof obj[key] !== "function" && typeof obj[key] !== "symbol") {
6
+ result[key] = obj[key];
7
+ }
8
+ }
9
+ return result;
10
+ }
11
+ function getTimeStamp() {
12
+ return (/* @__PURE__ */ new Date()).toLocaleTimeString();
13
+ }
14
+ function withLogger(options = {}) {
15
+ return (initializer) => (set, get) => {
16
+ const loggerSet = (updater, actionName) => {
17
+ if (!actionName)
18
+ return set(updater);
19
+ const prevState = pickValuesOnly({ ...get() });
20
+ set(updater, actionName);
21
+ const nextState = pickValuesOnly(get());
22
+ const action = {
23
+ type: actionName,
24
+ args: updater ? [updater] : [],
25
+ ...options.store && { store: options.store }
26
+ };
27
+ const title = `action \u{1F989} ${options.store ? `[${options.store}]` : ""} ${action.type} ${options.timestamp ? `@${getTimeStamp()}` : ""}`;
28
+ console[options.expanded ? "group" : "groupCollapsed"](
29
+ `%c${title}`,
30
+ "font-weight: bold; color: #42b883;"
31
+ );
32
+ console.log(
33
+ "%cprev state",
34
+ "font-weight: bold; color: grey;",
35
+ prevState
36
+ );
37
+ console.log("%caction", "font-weight: bold; color: #69B7FF;", action);
38
+ console.log(
39
+ "%cnext state",
40
+ "font-weight: bold; color: #4caf50;",
41
+ nextState
42
+ );
43
+ console.groupEnd();
44
+ };
45
+ return initializer(loggerSet, get);
46
+ };
47
+ }
48
+
49
+ export {
50
+ withLogger
51
+ };
@@ -0,0 +1,17 @@
1
+ // src/createStore.ts
2
+ import { reactive, computed } from "vue";
3
+ function createStore(initializer) {
4
+ const state = reactive({});
5
+ const set = (updater, _actionName) => {
6
+ Object.assign(state, updater);
7
+ };
8
+ const get = () => state;
9
+ const useSelector = (selector) => computed(() => selector(state));
10
+ const initial = initializer(set, get);
11
+ Object.assign(state, initial);
12
+ return Object.assign(state, { useSelector });
13
+ }
14
+
15
+ export {
16
+ createStore
17
+ };
@@ -1,8 +1,18 @@
1
1
  import { ComputedRef } from 'vue';
2
2
 
3
+ /*****************************************************************
4
+ * ZENON - Minimal Zustand-like State Manager for Vue 3
5
+ * (c) 2025-present AGUMON (https://github.com/ljlm0402/zenon)
6
+ *
7
+ * This source code is licensed under the MIT license.
8
+ * See the LICENSE file in the project root for more information.
9
+ *
10
+ * Made with ❀️ by AGUMON πŸ¦–
11
+ *****************************************************************/
12
+
3
13
  type StoreApi<T> = {
4
14
  get: () => T;
5
- set: (updater: Partial<T>) => void;
15
+ set: (updater: Partial<T>, actionName?: string) => void;
6
16
  useSelector: <S>(selector: (state: T) => S) => ComputedRef<S>;
7
17
  };
8
18
  declare function createStore<T extends Record<string, any>>(initializer: (set: StoreApi<T>["set"], get: StoreApi<T>["get"]) => T): T & Pick<StoreApi<T>, "useSelector">;
@@ -1,8 +1,18 @@
1
1
  import { ComputedRef } from 'vue';
2
2
 
3
+ /*****************************************************************
4
+ * ZENON - Minimal Zustand-like State Manager for Vue 3
5
+ * (c) 2025-present AGUMON (https://github.com/ljlm0402/zenon)
6
+ *
7
+ * This source code is licensed under the MIT license.
8
+ * See the LICENSE file in the project root for more information.
9
+ *
10
+ * Made with ❀️ by AGUMON πŸ¦–
11
+ *****************************************************************/
12
+
3
13
  type StoreApi<T> = {
4
14
  get: () => T;
5
- set: (updater: Partial<T>) => void;
15
+ set: (updater: Partial<T>, actionName?: string) => void;
6
16
  useSelector: <S>(selector: (state: T) => S) => ComputedRef<S>;
7
17
  };
8
18
  declare function createStore<T extends Record<string, any>>(initializer: (set: StoreApi<T>["set"], get: StoreApi<T>["get"]) => T): T & Pick<StoreApi<T>, "useSelector">;
@@ -26,13 +26,11 @@ module.exports = __toCommonJS(createStore_exports);
26
26
  var import_vue = require("vue");
27
27
  function createStore(initializer) {
28
28
  const state = (0, import_vue.reactive)({});
29
- const set = (updater) => {
29
+ const set = (updater, _actionName) => {
30
30
  Object.assign(state, updater);
31
31
  };
32
32
  const get = () => state;
33
- const useSelector = (selector) => {
34
- return (0, import_vue.computed)(() => selector(state));
35
- };
33
+ const useSelector = (selector) => (0, import_vue.computed)(() => selector(state));
36
34
  const initial = initializer(set, get);
37
35
  Object.assign(state, initial);
38
36
  return Object.assign(state, { useSelector });
@@ -1,18 +1,6 @@
1
- // src/createStore.ts
2
- import { reactive, computed } from "vue";
3
- function createStore(initializer) {
4
- const state = reactive({});
5
- const set = (updater) => {
6
- Object.assign(state, updater);
7
- };
8
- const get = () => state;
9
- const useSelector = (selector) => {
10
- return computed(() => selector(state));
11
- };
12
- const initial = initializer(set, get);
13
- Object.assign(state, initial);
14
- return Object.assign(state, { useSelector });
15
- }
1
+ import {
2
+ createStore
3
+ } from "./chunk-ZJASNIW3.mjs";
16
4
  export {
17
5
  createStore
18
6
  };
@@ -0,0 +1,3 @@
1
+ export { createStore } from './createStore.mjs';
2
+ export { compose } from './utils/compose.mjs';
3
+ import 'vue';
@@ -0,0 +1,3 @@
1
+ export { createStore } from './createStore.js';
2
+ export { compose } from './utils/compose.js';
3
+ import 'vue';
package/dist/index.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ compose: () => compose,
24
+ createStore: () => createStore
25
+ });
26
+ module.exports = __toCommonJS(src_exports);
27
+
28
+ // src/createStore.ts
29
+ var import_vue = require("vue");
30
+ function createStore(initializer) {
31
+ const state = (0, import_vue.reactive)({});
32
+ const set = (updater, _actionName) => {
33
+ Object.assign(state, updater);
34
+ };
35
+ const get = () => state;
36
+ const useSelector = (selector) => (0, import_vue.computed)(() => selector(state));
37
+ const initial = initializer(set, get);
38
+ Object.assign(state, initial);
39
+ return Object.assign(state, { useSelector });
40
+ }
41
+
42
+ // src/utils/compose.ts
43
+ function compose(...funcs) {
44
+ if (funcs.length === 0)
45
+ return (arg) => arg;
46
+ if (funcs.length === 1)
47
+ return funcs[0];
48
+ return funcs.reduce(
49
+ (a, b) => (...args) => a(b(...args))
50
+ );
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ compose,
55
+ createStore
56
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,10 @@
1
+ import {
2
+ createStore
3
+ } from "./chunk-ZJASNIW3.mjs";
4
+ import {
5
+ compose
6
+ } from "./chunk-BOGWVDMK.mjs";
7
+ export {
8
+ compose,
9
+ createStore
10
+ };
@@ -0,0 +1,2 @@
1
+ export { withLogger } from './withLogger.mjs';
2
+ export { withPersist } from './withPersist.mjs';
@@ -0,0 +1,2 @@
1
+ export { withLogger } from './withLogger.js';
2
+ export { withPersist } from './withPersist.js';
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/plugins/index.ts
21
+ var plugins_exports = {};
22
+ __export(plugins_exports, {
23
+ withLogger: () => withLogger,
24
+ withPersist: () => withPersist
25
+ });
26
+ module.exports = __toCommonJS(plugins_exports);
27
+
28
+ // src/plugins/withLogger.ts
29
+ function pickValuesOnly(obj) {
30
+ const result = {};
31
+ for (const key in obj) {
32
+ if (typeof obj[key] !== "function" && typeof obj[key] !== "symbol") {
33
+ result[key] = obj[key];
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ function getTimeStamp() {
39
+ return (/* @__PURE__ */ new Date()).toLocaleTimeString();
40
+ }
41
+ function withLogger(options = {}) {
42
+ return (initializer) => (set, get) => {
43
+ const loggerSet = (updater, actionName) => {
44
+ if (!actionName)
45
+ return set(updater);
46
+ const prevState = pickValuesOnly({ ...get() });
47
+ set(updater, actionName);
48
+ const nextState = pickValuesOnly(get());
49
+ const action = {
50
+ type: actionName,
51
+ args: updater ? [updater] : [],
52
+ ...options.store && { store: options.store }
53
+ };
54
+ const title = `action \u{1F989} ${options.store ? `[${options.store}]` : ""} ${action.type} ${options.timestamp ? `@${getTimeStamp()}` : ""}`;
55
+ console[options.expanded ? "group" : "groupCollapsed"](
56
+ `%c${title}`,
57
+ "font-weight: bold; color: #42b883;"
58
+ );
59
+ console.log(
60
+ "%cprev state",
61
+ "font-weight: bold; color: grey;",
62
+ prevState
63
+ );
64
+ console.log("%caction", "font-weight: bold; color: #69B7FF;", action);
65
+ console.log(
66
+ "%cnext state",
67
+ "font-weight: bold; color: #4caf50;",
68
+ nextState
69
+ );
70
+ console.groupEnd();
71
+ };
72
+ return initializer(loggerSet, get);
73
+ };
74
+ }
75
+
76
+ // src/plugins/withPersist.ts
77
+ function withPersist(key, options = {}) {
78
+ const storage = options.storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
79
+ return (initializer) => (set, get) => {
80
+ let initial = {};
81
+ if (storage) {
82
+ const saved = storage.getItem(key);
83
+ if (saved) {
84
+ try {
85
+ initial = { ...JSON.parse(saved) };
86
+ } catch {
87
+ initial = {};
88
+ }
89
+ }
90
+ }
91
+ const persistSet = (updater, actionName) => {
92
+ set(updater, actionName);
93
+ if (storage) {
94
+ try {
95
+ storage.setItem(key, JSON.stringify(get()));
96
+ } catch {
97
+ }
98
+ }
99
+ };
100
+ const store = initializer(persistSet, get);
101
+ Object.assign(store, initial);
102
+ if (storage)
103
+ storage.setItem(key, JSON.stringify(store));
104
+ return store;
105
+ };
106
+ }
107
+ // Annotate the CommonJS export names for ESM import in node:
108
+ 0 && (module.exports = {
109
+ withLogger,
110
+ withPersist
111
+ });
@@ -0,0 +1,10 @@
1
+ import {
2
+ withLogger
3
+ } from "../chunk-POKXZH6S.mjs";
4
+ import {
5
+ withPersist
6
+ } from "../chunk-CK67EZXJ.mjs";
7
+ export {
8
+ withLogger,
9
+ withPersist
10
+ };
@@ -0,0 +1,7 @@
1
+ declare function withLogger<T extends Record<string, any>>(options?: {
2
+ store?: string;
3
+ timestamp?: boolean;
4
+ expanded?: boolean;
5
+ }): (initializer: (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T) => (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T;
6
+
7
+ export { withLogger };
@@ -0,0 +1,7 @@
1
+ declare function withLogger<T extends Record<string, any>>(options?: {
2
+ store?: string;
3
+ timestamp?: boolean;
4
+ expanded?: boolean;
5
+ }): (initializer: (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T) => (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T;
6
+
7
+ export { withLogger };
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/plugins/withLogger.ts
21
+ var withLogger_exports = {};
22
+ __export(withLogger_exports, {
23
+ withLogger: () => withLogger
24
+ });
25
+ module.exports = __toCommonJS(withLogger_exports);
26
+ function pickValuesOnly(obj) {
27
+ const result = {};
28
+ for (const key in obj) {
29
+ if (typeof obj[key] !== "function" && typeof obj[key] !== "symbol") {
30
+ result[key] = obj[key];
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ function getTimeStamp() {
36
+ return (/* @__PURE__ */ new Date()).toLocaleTimeString();
37
+ }
38
+ function withLogger(options = {}) {
39
+ return (initializer) => (set, get) => {
40
+ const loggerSet = (updater, actionName) => {
41
+ if (!actionName)
42
+ return set(updater);
43
+ const prevState = pickValuesOnly({ ...get() });
44
+ set(updater, actionName);
45
+ const nextState = pickValuesOnly(get());
46
+ const action = {
47
+ type: actionName,
48
+ args: updater ? [updater] : [],
49
+ ...options.store && { store: options.store }
50
+ };
51
+ const title = `action \u{1F989} ${options.store ? `[${options.store}]` : ""} ${action.type} ${options.timestamp ? `@${getTimeStamp()}` : ""}`;
52
+ console[options.expanded ? "group" : "groupCollapsed"](
53
+ `%c${title}`,
54
+ "font-weight: bold; color: #42b883;"
55
+ );
56
+ console.log(
57
+ "%cprev state",
58
+ "font-weight: bold; color: grey;",
59
+ prevState
60
+ );
61
+ console.log("%caction", "font-weight: bold; color: #69B7FF;", action);
62
+ console.log(
63
+ "%cnext state",
64
+ "font-weight: bold; color: #4caf50;",
65
+ nextState
66
+ );
67
+ console.groupEnd();
68
+ };
69
+ return initializer(loggerSet, get);
70
+ };
71
+ }
72
+ // Annotate the CommonJS export names for ESM import in node:
73
+ 0 && (module.exports = {
74
+ withLogger
75
+ });
@@ -0,0 +1,6 @@
1
+ import {
2
+ withLogger
3
+ } from "../chunk-POKXZH6S.mjs";
4
+ export {
5
+ withLogger
6
+ };
@@ -0,0 +1,5 @@
1
+ declare function withPersist<T extends Record<string, any>>(key: string, options?: {
2
+ storage?: Storage;
3
+ }): (initializer: (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T) => (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T;
4
+
5
+ export { withPersist };
@@ -0,0 +1,5 @@
1
+ declare function withPersist<T extends Record<string, any>>(key: string, options?: {
2
+ storage?: Storage;
3
+ }): (initializer: (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T) => (set: (updater: Partial<T>, actionName?: string) => void, get: () => T) => T;
4
+
5
+ export { withPersist };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/plugins/withPersist.ts
21
+ var withPersist_exports = {};
22
+ __export(withPersist_exports, {
23
+ withPersist: () => withPersist
24
+ });
25
+ module.exports = __toCommonJS(withPersist_exports);
26
+ function withPersist(key, options = {}) {
27
+ const storage = options.storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
28
+ return (initializer) => (set, get) => {
29
+ let initial = {};
30
+ if (storage) {
31
+ const saved = storage.getItem(key);
32
+ if (saved) {
33
+ try {
34
+ initial = { ...JSON.parse(saved) };
35
+ } catch {
36
+ initial = {};
37
+ }
38
+ }
39
+ }
40
+ const persistSet = (updater, actionName) => {
41
+ set(updater, actionName);
42
+ if (storage) {
43
+ try {
44
+ storage.setItem(key, JSON.stringify(get()));
45
+ } catch {
46
+ }
47
+ }
48
+ };
49
+ const store = initializer(persistSet, get);
50
+ Object.assign(store, initial);
51
+ if (storage)
52
+ storage.setItem(key, JSON.stringify(store));
53
+ return store;
54
+ };
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ withPersist
59
+ });
@@ -0,0 +1,6 @@
1
+ import {
2
+ withPersist
3
+ } from "../chunk-CK67EZXJ.mjs";
4
+ export {
5
+ withPersist
6
+ };
@@ -0,0 +1,3 @@
1
+ declare function compose(...funcs: Function[]): Function;
2
+
3
+ export { compose };
@@ -0,0 +1,3 @@
1
+ declare function compose(...funcs: Function[]): Function;
2
+
3
+ export { compose };
@@ -17,24 +17,22 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/create.ts
21
- var create_exports = {};
22
- __export(create_exports, {
23
- create: () => create
20
+ // src/utils/compose.ts
21
+ var compose_exports = {};
22
+ __export(compose_exports, {
23
+ compose: () => compose
24
24
  });
25
- module.exports = __toCommonJS(create_exports);
26
- var import_vue = require("vue");
27
- function create(initializer) {
28
- const state = (0, import_vue.reactive)({});
29
- const set = (updater) => {
30
- Object.assign(state, updater);
31
- };
32
- const get = () => state;
33
- const initial = initializer(set, get);
34
- Object.assign(state, initial);
35
- return (0, import_vue.readonly)(state);
25
+ module.exports = __toCommonJS(compose_exports);
26
+ function compose(...funcs) {
27
+ if (funcs.length === 0)
28
+ return (arg) => arg;
29
+ if (funcs.length === 1)
30
+ return funcs[0];
31
+ return funcs.reduce(
32
+ (a, b) => (...args) => a(b(...args))
33
+ );
36
34
  }
37
35
  // Annotate the CommonJS export names for ESM import in node:
38
36
  0 && (module.exports = {
39
- create
37
+ compose
40
38
  });
@@ -0,0 +1,6 @@
1
+ import {
2
+ compose
3
+ } from "../chunk-BOGWVDMK.mjs";
4
+ export {
5
+ compose
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zenon",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "description": "A minimalist Zustand-inspired state manager for Vue 3",
5
5
  "author": "AGUMON <ljlm0402@gmail.com>",
6
6
  "license": "MIT",
@@ -21,6 +21,16 @@
21
21
  "import": "./dist/zenon.es.js",
22
22
  "require": "./dist/zenon.cjs.js",
23
23
  "types": "./dist/index.d.ts"
24
+ },
25
+ "./plugins": {
26
+ "import": "./dist/plugins/index.js",
27
+ "require": "./dist/plugins/index.js",
28
+ "types": "./dist/plugins/index.d.ts"
29
+ },
30
+ "./utils/compose": {
31
+ "import": "./dist/utils/compose.js",
32
+ "require": "./dist/utils/compose.js",
33
+ "types": "./dist/utils/compose.d.ts"
24
34
  }
25
35
  },
26
36
  "files": [
@@ -28,7 +38,7 @@
28
38
  ],
29
39
  "scripts": {
30
40
  "dev": "vite",
31
- "build": "tsup src/createStore.ts --format cjs,esm --dts",
41
+ "build": "tsup --config tsup.config.ts",
32
42
  "prepare": "pnpm build"
33
43
  },
34
44
  "devDependencies": {
@@ -41,5 +51,16 @@
41
51
  },
42
52
  "peerDependencies": {
43
53
  "vue": "^3.2.0"
44
- }
54
+ },
55
+ "directories": {
56
+ "example": "examples"
57
+ },
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/ljlm0402/zenon.git"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/ljlm0402/zenon/issues"
64
+ },
65
+ "homepage": "https://github.com/ljlm0402/zenon#readme"
45
66
  }
package/dist/create.d.mts DELETED
@@ -1,7 +0,0 @@
1
- type StoreApi<T> = {
2
- get: () => T;
3
- set: (updater: Partial<T>) => void;
4
- };
5
- declare function create<T extends Record<string, any>>(initializer: (set: StoreApi<T>["set"], get: StoreApi<T>["get"]) => T): Readonly<T>;
6
-
7
- export { type StoreApi, create };
package/dist/create.d.ts DELETED
@@ -1,7 +0,0 @@
1
- type StoreApi<T> = {
2
- get: () => T;
3
- set: (updater: Partial<T>) => void;
4
- };
5
- declare function create<T extends Record<string, any>>(initializer: (set: StoreApi<T>["set"], get: StoreApi<T>["get"]) => T): Readonly<T>;
6
-
7
- export { type StoreApi, create };
package/dist/create.mjs DELETED
@@ -1,15 +0,0 @@
1
- // src/create.ts
2
- import { reactive, readonly } from "vue";
3
- function create(initializer) {
4
- const state = reactive({});
5
- const set = (updater) => {
6
- Object.assign(state, updater);
7
- };
8
- const get = () => state;
9
- const initial = initializer(set, get);
10
- Object.assign(state, initial);
11
- return readonly(state);
12
- }
13
- export {
14
- create
15
- };